diff --git a/packages/core/dev/data.js b/packages/core/dev/data.js index ea72fcb..1def751 100644 --- a/packages/core/dev/data.js +++ b/packages/core/dev/data.js @@ -1,65 +1,65 @@ const data = { - bgColor: "#ffffff", + bgColor: '#ffffff', elements: [ { - name: "rect-001", + name: 'rect-001', x: 5, y: 5, w: 100, h: 50, - type: "rect", + type: 'rect', desc: { - bgColor: "#ffeb3b", + bgColor: '#ffeb3b', borderRadius: 10, borderWidth: 5, - borderColor: "#ffc107", - }, + borderColor: '#ffc107' + } }, { - name: "text-002", + name: 'text-002', x: 40, y: 40, w: 100, h: 60, // angle: 30, - type: "text", + type: 'text', desc: { fontSize: 16, - text: "Hello Text", + text: 'Hello Text', fontWeight: 'bold', - color: "#666666", + color: '#666666', borderRadius: 30, borderWidth: 4, - borderColor: "#ff5722", + borderColor: '#ff5722' }, operation: { disableScale: true, - disbaleRotate: true, + disableRotate: true } }, { - name: "image-003", + name: 'image-003', x: 80, y: 80, w: 160, h: 80, - type: "image", + type: 'image', desc: { - src: './images/computer.png', - }, + src: './images/computer.png' + } }, { - name: "svg-004", + name: 'svg-004', x: 200 - 5, y: 150 - 50, w: 100, h: 100, - type: "svg", + type: 'svg', desc: { - svg: '', - }, - }, - ], + svg: '' + } + } + ] }; export function getData() { diff --git a/packages/core/src/lib/element.ts b/packages/core/src/lib/element.ts index fe2ff86..214974f 100644 --- a/packages/core/src/lib/element.ts +++ b/packages/core/src/lib/element.ts @@ -1,10 +1,11 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ import { TypeContext, TypePoint, TypeData, TypeHelperWrapperControllerDirection, TypeElement, - TypeElemDesc, + TypeElemDesc } from '@idraw/types'; import { createUUID } from '@idraw/util'; import { rotateElement } from './transform'; @@ -21,7 +22,7 @@ export class Element { this._ctx = ctx; } - initData (data: TypeData): TypeData { + initData(data: TypeData): TypeData { data.elements.forEach((elem) => { if (!(elem.uuid && typeof elem.uuid === 'string')) { elem.uuid = createUUID(); @@ -65,15 +66,21 @@ export class Element { return [idx, uuid]; } - dragElement(data: TypeData, uuid: string, point: TypePoint, prevPoint: TypePoint, scale: number): void { + dragElement( + data: TypeData, + uuid: string, + point: TypePoint, + prevPoint: TypePoint, + scale: number + ): void { const index = this.getElementIndex(data, uuid); if (!data.elements[index]) { return; } const moveX = point.x - prevPoint.x; const moveY = point.y - prevPoint.y; - data.elements[index].x += (moveX / scale); - data.elements[index].y += (moveY / scale); + data.elements[index].x += moveX / scale; + data.elements[index].y += moveY / scale; this.limitElementAttrs(data.elements[index]); } @@ -85,9 +92,9 @@ export class Element { scale: number, direction: TypeHelperWrapperControllerDirection ): null | { - width: number, - height: number, - angle: number, + width: number; + height: number; + angle: number; } { const index = this.getElementIndex(data, uuid); if (!data.elements[index]) { @@ -96,8 +103,8 @@ export class Element { if (data.elements[index]?.operation?.lock === true) { return null; } - let moveX = (point.x - prevPoint.x) / scale; - let moveY = (point.y - prevPoint.y) / scale; + const moveX = (point.x - prevPoint.x) / scale; + const moveY = (point.y - prevPoint.y) / scale; const elem = data.elements[index]; // const { devicePixelRatio } = this._ctx.getSize(); @@ -105,10 +112,18 @@ export class Element { // moveY = (point.y - prevPoint.y) / scale; // } - if ([ - 'top-left', 'top', 'top-right', 'right', - 'bottom-right', 'bottom', 'bottom-left', 'left' - ].includes(direction)) { + if ( + [ + 'top-left', + 'top', + 'top-right', + 'right', + 'bottom-right', + 'bottom', + 'bottom-left', + 'left' + ].includes(direction) + ) { const p = calcuScaleElemPosition(elem, moveX, moveY, direction, scale); elem.x = p.x; elem.y = p.y; @@ -125,7 +140,7 @@ export class Element { return { width: limitNum(elem.w), height: limitNum(elem.h), - angle: limitAngle(elem.angle || 0), + angle: limitAngle(elem.angle || 0) }; } @@ -147,25 +162,34 @@ export class Element { elem.h = limitNum(elem.h); elem.angle = limitAngle(elem.angle || 0); } - } - function calcuScaleElemPosition( elem: TypeElement, moveX: number, moveY: number, direction: TypeHelperWrapperControllerDirection, - scale: number, -): TypePoint & { w: number, h: number } { + scale: number +): TypePoint & { w: number; h: number } { const p = { x: elem.x, y: elem.y, w: elem.w, h: elem.h }; let angle = elem.angle; if (angle < 0) { angle = Math.max(0, 360 + angle); } + if (elem.operation?.limitRatio === true) { + if ( + ['top-left', 'top-right', 'bottom-right', 'bottom-left'].includes( + direction + ) + ) { + const maxDist = Math.max(Math.abs(moveX), Math.abs(moveY)); + moveX = (moveX >= 0 ? 1 : -1) * maxDist; + moveY = (((moveY >= 0 ? 1 : -1) * maxDist) / elem.w) * elem.h; + } + } + switch (direction) { case 'top-left': { - // TODO // if (elem.angle === 0) { @@ -184,15 +208,14 @@ function calcuScaleElemPosition( // } else { // // TODO // } - - if (elem.w - moveX > 0 && elem.h - moveY > 0) { + + if (elem.w - moveX > 0 && elem.h - moveY > 0) { p.x += moveX; p.y += moveY; p.w -= moveX; p.h -= moveY; } - - + break; } case 'top': { @@ -202,7 +225,8 @@ function calcuScaleElemPosition( p.h -= moveY; } } else if (elem.angle > 0 || elem.angle < 0) { - const angle = elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360); + 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; @@ -285,7 +309,7 @@ function calcuScaleElemPosition( // 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); @@ -334,7 +358,8 @@ function calcuScaleElemPosition( p.w += moveX; } } else if (elem.angle > 0 || elem.angle < 0) { - const angle = elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360); + 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; @@ -374,7 +399,7 @@ function calcuScaleElemPosition( p.w += moveX; } } - + break; } case 'bottom-right': { @@ -406,7 +431,8 @@ function calcuScaleElemPosition( p.h += moveY; } } else if (elem.angle > 0 || elem.angle < 0) { - const angle = elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360); + 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; @@ -479,7 +505,8 @@ function calcuScaleElemPosition( p.w -= moveX; } } else if (elem.angle > 0 || elem.angle < 0) { - const angle = elem.angle > 0 ? elem.angle : Math.max(0, elem.angle + 360); + 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; @@ -529,7 +556,7 @@ function calcuScaleElemPosition( } function parseRadian(angle: number) { - return angle * Math.PI / 180; + return (angle * Math.PI) / 180; } function calcMoveDist(moveX: number, moveY: number) { @@ -538,4 +565,4 @@ function calcMoveDist(moveX: number, moveY: number) { function changeMoveDistDirect(moveDist: number, moveDirect: number) { return moveDirect > 0 ? Math.abs(moveDist) : 0 - Math.abs(moveDist); -} \ No newline at end of file +} diff --git a/packages/core/src/lib/helper.ts b/packages/core/src/lib/helper.ts index 19bcace..9412375 100644 --- a/packages/core/src/lib/helper.ts +++ b/packages/core/src/lib/helper.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ import { TypeData, TypeHelper, @@ -89,7 +90,7 @@ export class Helper implements TypeHelper { wrapper.controllers.bottom, wrapper.controllers.bottomRight ]; - let directionNames: TypeHelperWrapperControllerDirection[] = [ + const directionNames: TypeHelperWrapperControllerDirection[] = [ 'right', 'top-right', 'top', @@ -337,7 +338,7 @@ export class Helper implements TypeHelper { ) { const { selectedUUIDList } = opts; const wrapperList: TypeHeplerSelectedElementWrapper[] = []; - data.elements.forEach((elem, i) => { + data.elements.forEach((elem) => { if (selectedUUIDList?.includes(elem.uuid)) { const wrapper = this._createSelectedElementWrapper(elem, opts); wrapperList.push(wrapper); @@ -423,7 +424,7 @@ export class Helper implements TypeHelper { rotate: { x: elem.x + elem.w / 2, y: elem.y - controllerSize - (controllerSize * 2 + rotateLimit) - bw, - invisible: elem?.operation?.disbaleRotate === true + invisible: elem?.operation?.disableRotate === true } }, lineWidth: lineWidth, diff --git a/packages/idraw/dev/data.ts b/packages/idraw/dev/data.ts index f69d38a..28f0d79 100644 --- a/packages/idraw/dev/data.ts +++ b/packages/idraw/dev/data.ts @@ -53,6 +53,10 @@ const data = { type: 'svg', desc: { svg: '' + }, + operation: { + disableRotate: true, + limitRatio: true } } ] diff --git a/packages/types/src/lib/element.ts b/packages/types/src/lib/element.ts index 14b20fc..94bed16 100644 --- a/packages/types/src/lib/element.ts +++ b/packages/types/src/lib/element.ts @@ -7,31 +7,34 @@ type TypeElementAttrs = { h: number; angle: number; operation?: { - lock?: boolean, - invisible?: boolean, - disableScale?: boolean, - disbaleRotate?: boolean, - } - extension?: {[key: string]: any} | any; -} + lock?: boolean; + invisible?: boolean; + disableScale?: boolean; + disableRotate?: boolean; + limitRatio?: boolean; + }; + extension?: { [key: string]: any } | any; +}; -type TypeElementBase = TypeElementAttrs & { - name?: string; - uuid?: string; - type: T | TypeElemType; - desc: TypeElemDesc[T]; -} +type TypeElementBase = + TypeElementAttrs & { + name?: string; + uuid?: string; + type: T | TypeElemType; + desc: TypeElemDesc[T]; + }; -type TypeElement = TypeElementBase & { - uuid: string; -} +type TypeElement = + TypeElementBase & { + uuid: string; + }; type TypeElemDescBase = { shadowColor?: string; shadowOffsetX?: number; shadowOffsetY?: number; shadowBlur?: number; -} +}; type TypeElemBoxDesc = { borderRadius?: number; @@ -40,14 +43,14 @@ type TypeElemBoxDesc = { } & TypeElemDescBase; type TypeElemDesc = { - 'text': TypeElemDescText, - 'rect': TypeElemDescRect, - 'circle': TypeElemDescCircle, - 'image': TypeElemDescImage, - 'svg': TypeElemDescSVG, - 'html': TypeElemDescHTML, + text: TypeElemDescText; + rect: TypeElemDescRect; + circle: TypeElemDescCircle; + image: TypeElemDescImage; + svg: TypeElemDescSVG; + html: TypeElemDescHTML; // paint: TypeElemDescPaint, -} +}; // enum TypeElemType { // text = 'text', @@ -62,7 +65,7 @@ type TypeElemType = 'text' | 'rect' | 'circle' | 'image' | 'svg' | 'html'; type TypeElemDescRect = { bgColor?: string; -} & TypeElemBoxDesc +} & TypeElemBoxDesc; type TypeElemDescText = { text: string; @@ -79,11 +82,11 @@ type TypeElemDescText = { textShadowOffsetX?: number; textShadowOffsetY?: number; textShadowBlur?: number; -} & TypeElemBoxDesc +} & TypeElemBoxDesc; type TypeElemDescCircle = { bgColor: string; -} & TypeElemBoxDesc +} & TypeElemBoxDesc; type TypeElemDescImage = { src: string; @@ -91,13 +94,13 @@ type TypeElemDescImage = { type TypeElemDescSVG = { svg: string; -} +}; type TypeElemDescHTML = { html: string; width: number; height: number; -} +}; // type TypeElemDescPaint = TypePaintData @@ -112,5 +115,5 @@ export { TypeElemDesc, TypeElemType, TypeElement, - TypeElementBase, -}; \ No newline at end of file + TypeElementBase +};