fix: update scale-direction for element when it rotated

This commit is contained in:
chenshenhai 2021-09-27 19:01:02 +08:00
parent 328c363bca
commit 23ffe970b1
4 changed files with 125 additions and 72 deletions

View file

@ -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,

View file

@ -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;

View file

@ -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,

View file

@ -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;