feat: core implement transfrom element

This commit is contained in:
chenshenhai 2021-05-28 10:20:14 +08:00
parent a1fe5f5eb5
commit 930ee64e8b
4 changed files with 100 additions and 33 deletions

View file

@ -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();
}
}

View file

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

View file

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

View file

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