mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
feat: core implement transfrom element
This commit is contained in:
parent
a1fe5f5eb5
commit
930ee64e8b
4 changed files with 100 additions and 33 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { TypeData, TypePoint, TypeHelperWrapperDotPosition, TypeConfig, TypeConfigStrict } from '@idraw/types';
|
||||
import { TypeData, TypePoint, TypeHelperWrapperDotDirection, TypeConfig, TypeConfigStrict } from '@idraw/types';
|
||||
import Board from '@idraw/board';
|
||||
import Renderer from './lib/renderer';
|
||||
import { Element } from './lib/element';
|
||||
|
|
@ -32,7 +32,7 @@ class Core {
|
|||
|
||||
private _selectedUUID: string | null = null;
|
||||
private _prevPoint: TypePoint | null = null;
|
||||
private _selectedDotPosition: TypeHelperWrapperDotPosition | null = null;
|
||||
private _selectedDotDirection: TypeHelperWrapperDotDirection | null = null;
|
||||
|
||||
constructor(mount: HTMLDivElement, opts: Options, config: TypeConfig) {
|
||||
this._data = { elements: [] };
|
||||
|
|
@ -92,10 +92,11 @@ class Core {
|
|||
}
|
||||
|
||||
private _handlePoint(point: TypePoint) {
|
||||
const [uuid, position] = this._helper.isPointInElementWrapperDot(point);
|
||||
if (uuid && position && uuid === this._selectedUUID) {
|
||||
const [uuid, direction] = this._helper.isPointInElementWrapperDot(point);
|
||||
if (uuid && direction) {
|
||||
this._mode = Mode.SELECT_ELEMENT_WRAPPER_DOT;
|
||||
this._selectedDotPosition = position;
|
||||
this._selectedDotDirection = direction;
|
||||
this._selectedUUID = uuid;
|
||||
} else {
|
||||
const [index, uuid] = this._element.isPointInElement(point, this._data);
|
||||
if (index >= 0) {
|
||||
|
|
@ -111,14 +112,15 @@ class Core {
|
|||
}
|
||||
|
||||
private _handleMove(point: TypePoint) {
|
||||
if (this._mode === Mode.SELECT_ELEMENT) {
|
||||
if (this._selectedUUID) {
|
||||
if (this._selectedUUID) {
|
||||
if (this._mode === Mode.SELECT_ELEMENT) {
|
||||
this._dragElement(this._selectedUUID, point, this._prevPoint);
|
||||
this.draw();
|
||||
} else if (this._mode === Mode.SELECT_ELEMENT_WRAPPER_DOT && this._selectedDotDirection) {
|
||||
this._transfromElement(this._selectedUUID, point, this._prevPoint, this._selectedDotDirection);
|
||||
}
|
||||
this.draw();
|
||||
} else if (this._mode === Mode.SELECT_ELEMENT_WRAPPER_DOT) {
|
||||
this._transfromElement(point, this._prevPoint);
|
||||
}
|
||||
|
||||
this._prevPoint = point;
|
||||
}
|
||||
|
||||
|
|
@ -133,13 +135,14 @@ class Core {
|
|||
}
|
||||
this._element.dragElement(this._data, uuid, point, prevPoint, this._board.getContext().getTransform().scale);
|
||||
this.draw();
|
||||
prevPoint = point;
|
||||
}
|
||||
|
||||
private _transfromElement(point: TypePoint, prevPoint: TypePoint|null) {
|
||||
const uuid = this._selectedUUID;
|
||||
const position = this._selectedDotPosition;
|
||||
console.log(uuid, position);
|
||||
private _transfromElement(uuid: string, point: TypePoint, prevPoint: TypePoint|null, direction: TypeHelperWrapperDotDirection) {
|
||||
if (!prevPoint) {
|
||||
return;
|
||||
}
|
||||
this._element.transformElement(this._data, uuid, point, prevPoint, this._board.getContext().getTransform().scale, direction);
|
||||
this.draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
import { TypeContext, TypePoint, TypeData } from '@idraw/types';
|
||||
import {
|
||||
TypeContext,
|
||||
TypePoint,
|
||||
TypeData,
|
||||
TypeHelperWrapperDotDirection
|
||||
} from '@idraw/types';
|
||||
import util from './../util';
|
||||
|
||||
const { createUUID } = util.uuid;
|
||||
|
|
@ -42,11 +47,70 @@ export class Element {
|
|||
|
||||
dragElement(data: TypeData, uuid: string, point: TypePoint, prevPoint: TypePoint, scale: number) {
|
||||
const index = this.getElementIndex(data, uuid);
|
||||
if (data.elements[index]) {
|
||||
const moveX = point.x - prevPoint.x;
|
||||
const moveY = point.y - prevPoint.y;
|
||||
data.elements[index].x += (moveX / scale);
|
||||
data.elements[index].y += (moveY / scale);
|
||||
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);
|
||||
}
|
||||
|
||||
transformElement(data: TypeData, uuid: string, point: TypePoint, prevPoint: TypePoint, scale: number, direction: TypeHelperWrapperDotDirection) {
|
||||
const index = this.getElementIndex(data, uuid);
|
||||
if (!data.elements[index]) {
|
||||
return;
|
||||
}
|
||||
const moveX = (point.x - prevPoint.x) / scale;
|
||||
const moveY = (point.y - prevPoint.y) / scale;
|
||||
const elem = data.elements[index];
|
||||
|
||||
switch (direction) {
|
||||
case 'top-left': {
|
||||
elem.x += moveX;
|
||||
elem.y += moveY;
|
||||
elem.w -= moveX;
|
||||
elem.h -= moveY;
|
||||
break;
|
||||
};
|
||||
case 'top': {
|
||||
elem.y += moveY;
|
||||
elem.h -= moveY;
|
||||
break;
|
||||
};
|
||||
case 'top-right': {
|
||||
elem.y += moveY;
|
||||
elem.w += moveX;
|
||||
elem.h -= moveY;
|
||||
break;
|
||||
};
|
||||
case 'right': {
|
||||
elem.w += moveX;
|
||||
break;
|
||||
};
|
||||
case 'bottom-right': {
|
||||
elem.w += moveX;
|
||||
elem.h += moveY;
|
||||
break;
|
||||
};
|
||||
case 'bottom': {
|
||||
elem.h += moveY;
|
||||
break;
|
||||
};
|
||||
case 'bottom-left': {
|
||||
elem.x += moveX;
|
||||
elem.w -= moveX;
|
||||
elem.h += moveY;
|
||||
break;
|
||||
};
|
||||
case 'left': {
|
||||
elem.x += moveX;
|
||||
elem.w -= moveX;
|
||||
break;
|
||||
};
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {
|
|||
TypeHelper,
|
||||
TypeHelperConfig,
|
||||
TypeHelperUpdateOpts,
|
||||
TypeHelperWrapperDotPosition,
|
||||
TypeHelperWrapperDotDirection,
|
||||
TypeElement,
|
||||
TypeElemDesc,
|
||||
TypeContext,
|
||||
|
|
@ -38,10 +38,10 @@ export class Helper implements TypeHelper {
|
|||
return JSON.parse(JSON.stringify(this._helperConfig));
|
||||
}
|
||||
|
||||
isPointInElementWrapperDot(p: TypePoint): [string | null | undefined, TypeHelperWrapperDotPosition | null] {
|
||||
isPointInElementWrapperDot(p: TypePoint): [string | null | undefined, TypeHelperWrapperDotDirection | null] {
|
||||
const ctx = this._ctx;
|
||||
const uuid = this._helperConfig?.selectedElementWrapper?.uuid;
|
||||
let position: TypeHelperWrapperDotPosition | null = null;
|
||||
let direction: TypeHelperWrapperDotDirection | null = null;
|
||||
if (!this._helperConfig.selectedElementWrapper) {
|
||||
return [null, null];
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ export class Helper implements TypeHelper {
|
|||
wrapper.topLeft, wrapper.top, wrapper.topRight, wrapper.right,
|
||||
wrapper.bottomRight, wrapper.bottom, wrapper.bottomLeft, wrapper.left,
|
||||
];
|
||||
const names: TypeHelperWrapperDotPosition[] = [
|
||||
const directionNames: TypeHelperWrapperDotDirection[] = [
|
||||
'top-left', 'top', 'top-right', 'right',
|
||||
'bottom-right', 'bottom', 'bottom-left', 'left',
|
||||
];
|
||||
|
|
@ -60,11 +60,11 @@ export class Helper implements TypeHelper {
|
|||
ctx.arc(dot.x, dot.y, wrapper.dotSize, 0, Math.PI * 2);
|
||||
ctx.closePath();
|
||||
if (ctx.isPointInPath(p.x, p.y)) {
|
||||
position = names[i];
|
||||
direction = directionNames[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return [uuid, position];
|
||||
return [uuid, direction];
|
||||
}
|
||||
|
||||
private _updateElementIndex(data: TypeData) {
|
||||
|
|
@ -83,9 +83,9 @@ export class Helper implements TypeHelper {
|
|||
const index: number = this._helperConfig.elementIndexMap[uuid];
|
||||
const elem = data.elements[index];
|
||||
|
||||
const dotSize = this._coreConfig.elementWrapper.dotSize / Math.min(1, scale);
|
||||
const lineWidth = this._coreConfig.elementWrapper.lineWidth / Math.min(1, scale);
|
||||
const lineDash = this._coreConfig.elementWrapper.lineDash.map(n => (n / Math.min(1, scale)));
|
||||
const dotSize = this._coreConfig.elementWrapper.dotSize / scale;
|
||||
const lineWidth = this._coreConfig.elementWrapper.lineWidth / scale;
|
||||
const lineDash = this._coreConfig.elementWrapper.lineDash.map(n => (n / scale));
|
||||
|
||||
const wrapper = {
|
||||
uuid,
|
||||
|
|
@ -123,7 +123,7 @@ export class Helper implements TypeHelper {
|
|||
},
|
||||
left: {
|
||||
x: elem.x - dotSize,
|
||||
y: elem.y + elem.h / 2 - dotSize,
|
||||
y: elem.y + elem.h / 2 - dotSize / 2,
|
||||
},
|
||||
}
|
||||
this._helperConfig.selectedElementWrapper = wrapper;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ interface TypeHelper {
|
|||
getConfig(): TypeHelperConfig;
|
||||
}
|
||||
|
||||
type TypeHelperWrapperDotPosition
|
||||
type TypeHelperWrapperDotDirection
|
||||
= 'top-left' | 'top' | 'top-right' | 'right'
|
||||
| 'bottom-right' | 'bottom' | 'bottom-left' | 'left';
|
||||
|
||||
|
|
@ -44,5 +44,5 @@ export {
|
|||
TypeHelper,
|
||||
TypeHelperConfig,
|
||||
TypeHelperUpdateOpts,
|
||||
TypeHelperWrapperDotPosition,
|
||||
TypeHelperWrapperDotDirection,
|
||||
}
|
||||
Loading…
Reference in a new issue