mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
fix: update scale-direction for element when it rotated
This commit is contained in:
parent
328c363bca
commit
23ffe970b1
4 changed files with 125 additions and 72 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue