From 23ffe970b15b28171091d079470ef6fdeb7e4bd0 Mon Sep 17 00:00:00 2001 From: chenshenhai Date: Mon, 27 Sep 2021 19:01:02 +0800 Subject: [PATCH] fix: update scale-direction for element when it rotated --- packages/core/src/lib/draw/wrapper.ts | 20 ++-- packages/core/src/lib/element.ts | 144 ++++++++++++++++---------- packages/core/src/lib/helper.ts | 11 ++ packages/types/src/lib/helper.ts | 22 ++-- 4 files changed, 125 insertions(+), 72 deletions(-) diff --git a/packages/core/src/lib/draw/wrapper.ts b/packages/core/src/lib/draw/wrapper.ts index f72abbd..797afea 100644 --- a/packages/core/src/lib/draw/wrapper.ts +++ b/packages/core/src/lib/draw/wrapper.ts @@ -44,13 +44,21 @@ export function drawElementWrapper(ctx: TypeContext, config: TypeHelperConfig) { // draw wrapper's dots ctx.setFillStyle(wrapper.color); [ - wrapper.dots.topLeft, wrapper.dots.top, wrapper.dots.topRight, wrapper.dots.right, - wrapper.dots.bottomRight, wrapper.dots.bottom, wrapper.dots.bottomLeft, wrapper.dots.left, + wrapper.dots.topLeft, + wrapper.dots.top, + wrapper.dots.topRight, + wrapper.dots.right, + wrapper.dots.bottomRight, + wrapper.dots.bottom, + wrapper.dots.bottomLeft, + wrapper.dots.left, ].forEach((dot) => { - ctx.beginPath(); - ctx.arc(dot.x, dot.y, wrapper.dotSize, 0, Math.PI * 2); - ctx.fill(); - ctx.closePath(); + if (dot.invisible !== true) { + ctx.beginPath(); + ctx.arc(dot.x, dot.y, wrapper.dotSize, 0, Math.PI * 2); + ctx.fill(); + ctx.closePath(); + } }); } else { // draw wrapper's lock dots, diff --git a/packages/core/src/lib/element.ts b/packages/core/src/lib/element.ts index fb8fa9e..e40b91e 100644 --- a/packages/core/src/lib/element.ts +++ b/packages/core/src/lib/element.ts @@ -12,6 +12,7 @@ import { calcRadian, calcElementCenter, parseRadianToAngle } from './calculate'; import { limitAngle, limitNum } from './value'; const { createUUID } = util.uuid; +const limitQbliqueAngle = 30; export class Element { private _ctx: TypeContext; @@ -165,6 +166,9 @@ function calcuScaleElemPosition( } switch (direction) { case 'top-left': { + + // TODO + // if (elem.angle === 0) { // // TODO // } else if (elem.angle > 0 || elem.angle < 0) { @@ -193,7 +197,7 @@ function calcuScaleElemPosition( break; } case 'top': { - if (elem.angle === 0) { + if (elem.angle === 0 || Math.abs(elem.angle) < limitQbliqueAngle) { if (p.h - moveY > 0) { p.y += moveY; p.h -= moveY; @@ -242,64 +246,90 @@ function calcuScaleElemPosition( break; } case 'top-right': { - if (elem.angle === 0) { - if (p.h - moveY > 0) { - p.y += moveY; - p.h -= moveY; - } - } else if (elem.angle > 0 || elem.angle < 0) { - const angle = elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360); - let moveDist = calcMoveDist(moveX, moveY); - let centerX = p.x + elem.w / 2; - let centerY = p.y + elem.h / 2; - let moveDistW: number = 0; - let moveDistH: number = 0; - if (angle < 90) { - const radianDist = Math.atan(Math.tan(Math.abs(moveY)/Math.abs(moveX))) - const radian = parseRadian(angle); - const radianResult = radianDist + radian; - moveDistH = moveDist * Math.sin(radianResult); - moveDistW = moveDist * Math.cos(radianResult); - moveDistH = 0 - changeMoveDistDirect(moveDistH, moveY); - moveDistW = changeMoveDistDirect(moveDistW, moveX); - { - // top direct - const radian = parseRadian(angle); - const centerMoveDist = moveDistH / 2; - centerX = centerX + centerMoveDist * Math.sin(radian); - centerY = centerY - centerMoveDist * Math.cos(radian); - } - { - // right direct - const radian = parseRadian(angle); - const centerMoveDist = moveDistW / 2; - centerX = centerX + centerMoveDist * Math.cos(radian); - centerY = centerY + centerMoveDist * Math.sin(radian); - } - - } else if (angle < 180) { - // TODO - } else if (angle < 270) { - // TODO - } else if (angle < 360) { - // TODO - } - if (p.h + moveDistH > 0 && p.w + moveDistW > 0) { - p.h = p.h + moveDistH; - p.w = p.w + moveDistW; - p.x = centerX - p.w / 2; - p.y = centerY - p.h / 2; - } - } else { - if (p.h - moveY > 0) { - p.y += moveY; - p.h -= moveY; - } + if (p.h - moveY > 0) { + p.y += moveY; + p.h -= moveY; } + // // TODO + // if (elem.angle === 0) { + // if (p.h - moveY > 0) { + // p.y += moveY; + // p.h -= moveY; + // } + // } else if (elem.angle > 0 || elem.angle < 0) { + // const angle = elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360); + // let moveDist = calcMoveDist(moveX, moveY); + // let centerX = p.x + elem.w / 2; + // let centerY = p.y + elem.h / 2; + // let moveDistW: number = 0; + // let moveDistH: number = 0; + // if (angle < 90) { + // const radianDist = Math.atan(Math.tan(Math.abs(moveY)/Math.abs(moveX))) + // const radian = parseRadian(angle); + // const radianResult = radianDist + radian; + // moveDistH = moveDist * Math.sin(radianResult); + // moveDistW = moveDist * Math.cos(radianResult); + // moveDistH = 0 - changeMoveDistDirect(moveDistH, moveY); + // moveDistW = changeMoveDistDirect(moveDistW, moveX); + // { + // // top direct + // const radian = parseRadian(angle); + // const centerMoveDist = moveDistH / 2; + // centerX = centerX + centerMoveDist * Math.sin(radian); + // centerY = centerY - centerMoveDist * Math.cos(radian); + // } + // { + // // right direct + // const radian = parseRadian(angle); + // const centerMoveDist = moveDistW / 2; + // centerX = centerX + centerMoveDist * Math.cos(radian); + // centerY = centerY + centerMoveDist * Math.sin(radian); + // } + + // } else if (angle < 180) { + // const radianDist = Math.atan(Math.tan(Math.abs(moveX)/Math.abs(moveY))) + // const radian = parseRadian(angle); + // const radianResult = radianDist + radian; + // moveDistH = moveDist * Math.sin(radianResult); + // moveDistW = moveDist * Math.cos(radianResult); + // moveDistH = changeMoveDistDirect(moveDistH, moveY); + // moveDistW = changeMoveDistDirect(moveDistW, moveX); + // { + // // top direct + // const radian = parseRadian(angle - 90); + // const centerMoveDist = moveDistH / 2; + // centerX = centerX + centerMoveDist * Math.cos(radian); + // centerY = centerY + centerMoveDist * Math.sin(radian); + // } + // { + // // right direct TODO + // const radian = parseRadian(angle - 90); + // const centerMoveDist = moveDistW / 2; + // centerX = centerX - centerMoveDist * Math.sin(radian); + // centerY = centerY + centerMoveDist * Math.cos(radian); + // } + + // } else if (angle < 270) { + // // TODO + // } else if (angle < 360) { + // // TODO + // } + // if (p.h + moveDistH > 0 && p.w + moveDistW > 0) { + // p.h = p.h + moveDistH; + // // p.w = p.w + moveDistW; + // p.x = centerX - p.w / 2; + // p.y = centerY - p.h / 2; + // } + // } else { + // if (p.h - moveY > 0) { + // p.y += moveY; + // p.h -= moveY; + // } + // } break; } case 'right': { - if (elem.angle === 0) { + if (elem.angle === 0 || Math.abs(elem.angle) < limitQbliqueAngle) { if (elem.w + moveX > 0) { p.w += moveX; } @@ -371,7 +401,7 @@ function calcuScaleElemPosition( break; } case 'bottom': { - if (elem.angle === 0) { + if (elem.angle === 0 || Math.abs(elem.angle) < limitQbliqueAngle) { if (elem.h + moveY > 0) { p.h += moveY; } @@ -443,7 +473,7 @@ function calcuScaleElemPosition( break; } case 'left': { - if (elem.angle === 0) { + if (elem.angle === 0 || Math.abs(elem.angle) < limitQbliqueAngle) { if (elem.w - moveX > 0) { p.x += moveX; p.w -= moveX; diff --git a/packages/core/src/lib/helper.ts b/packages/core/src/lib/helper.ts index 1b22a3e..7c6c0c6 100644 --- a/packages/core/src/lib/helper.ts +++ b/packages/core/src/lib/helper.ts @@ -122,6 +122,9 @@ export class Helper implements TypeHelper { rotateContext(ctx, wrapper.translate, wrapper.radian || 0, () => { for (let i = 0; i < dots.length; i ++) { const dot = dots[i]; + if (dot.invisible === true) { + continue; + } ctx.beginPath(); ctx.arc(dot.x, dot.y, wrapper.dotSize, 0, Math.PI * 2); ctx.closePath(); @@ -311,6 +314,10 @@ export class Helper implements TypeHelper { const rotateLimit = 12; // @ts-ignore const bw = elem.desc?.borderWidth || 0; + let hideObliqueDirection = false; + if (typeof elem.angle === 'number' && Math.abs(elem.angle) > 30) { + hideObliqueDirection = true; + } const wrapper: TypeHeplerSelectedElementWrapper = { uuid: elem.uuid, @@ -320,6 +327,7 @@ export class Helper implements TypeHelper { topLeft: { x: elem.x - dotSize - bw, y: elem.y - dotSize - bw, + invisible: hideObliqueDirection, }, top: { x: elem.x + elem.w / 2, @@ -328,6 +336,7 @@ export class Helper implements TypeHelper { topRight: { x: elem.x + elem.w + dotSize + bw, y: elem.y - dotSize - bw, + invisible: hideObliqueDirection, }, right: { x: elem.x + elem.w + dotSize + bw, @@ -336,6 +345,7 @@ export class Helper implements TypeHelper { bottomRight: { x: elem.x + elem.w + dotSize + bw, y: elem.y + elem.h + dotSize + bw, + invisible: hideObliqueDirection, }, bottom: { x: elem.x + elem.w / 2, @@ -344,6 +354,7 @@ export class Helper implements TypeHelper { bottomLeft: { x: elem.x - dotSize - bw, y: elem.y + elem.h + dotSize + bw, + invisible: hideObliqueDirection, }, left: { x: elem.x - dotSize - bw, diff --git a/packages/types/src/lib/helper.ts b/packages/types/src/lib/helper.ts index 0adb6cc..5e09839 100644 --- a/packages/types/src/lib/helper.ts +++ b/packages/types/src/lib/helper.ts @@ -3,20 +3,24 @@ import { TypePoint } from './board'; // type test = {[uuid string]: TypeElement} +type TypeDot = TypePoint & { + invisible?: boolean; +}; + type TypeHeplerSelectedElementWrapper = { uuid: string; dotSize: number; lock: boolean; dots: { - topLeft: TypePoint, - top: TypePoint, - topRight: TypePoint, - right: TypePoint, - bottomRight: TypePoint, - bottom: TypePoint, - bottomLeft: TypePoint, - left: TypePoint, - rotate: TypePoint, + topLeft: TypeDot, + top: TypeDot, + topRight: TypeDot, + right: TypeDot, + bottomRight: TypeDot, + bottom: TypeDot, + bottomLeft: TypeDot, + left: TypeDot, + rotate: TypeDot, }, lineDash: number[]; lineWidth: number;