Skip to content

Commit

Permalink
Merge pull request #346 from idrawjs/dev-v0.4
Browse files Browse the repository at this point in the history
feat: add method for moving elements by point and refactor rotatable
  • Loading branch information
chenshenhai authored Aug 17, 2024
2 parents 1e76b5c + a68ccc4 commit 5b263d9
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 80 deletions.
19 changes: 9 additions & 10 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,12 @@ jobs:
- run: pnpm i
- run: npm run beforetest
- run: npm run cover
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
files: /home/runner/work/idraw/idraw/reports/clover.xml # optional
flags: unittests # optional
name: codecov-umbrella # optional
fail_ci_if_error: true # optional (default = false)
verbose: true # optional (default = false)

# - name: Upload coverage to Codecov
# uses: codecov/codecov-action@v2
# with:
# token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
# files: /home/runner/work/idraw/idraw/reports/clover.xml # optional
# flags: unittests # optional
# name: codecov-umbrella # optional
# fail_ci_if_error: true # optional (default = false)
# verbose: true # optional (default = false)
26 changes: 14 additions & 12 deletions packages/core/src/middleware/info/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,20 @@ export const MiddlewareInfo: BoardMiddleware<
});

if (showAngleInfo) {
drawAngleInfoText(overlayContext, {
point: {
x: rectInfo.top.x + infoFontSize + 4,
y: rectInfo.top.y - infoFontSize * 2 - 18
},
rotateCenter: rectInfo.center,
angle: totalAngle,
text: angleText,
fontSize: infoFontSize,
lineHeight: infoLineHeight,
style
});
if (elem.operations?.rotatable !== false) {
drawAngleInfoText(overlayContext, {
point: {
x: rectInfo.top.x + infoFontSize + 4,
y: rectInfo.top.y - infoFontSize * 2 - 18
},
rotateCenter: rectInfo.center,
angle: totalAngle,
text: angleText,
fontSize: infoFontSize,
lineHeight: infoLineHeight,
style
});
}
}
}
}
Expand Down
34 changes: 18 additions & 16 deletions packages/core/src/middleware/selector/draw-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ export function drawSelectedElementControllersVertexes(
hideControllers,
style,
rotateControllerPattern,
viewSizeInfo
// calculator, element, viewScaleInfo, viewSizeInfo
viewSizeInfo,
element
// calculator, viewScaleInfo, viewSizeInfo
} = opts;

const { devicePixelRatio = 1 } = viewSizeInfo;
Expand All @@ -113,20 +114,21 @@ export function drawSelectedElementControllersVertexes(
drawVertexes(ctx, calcViewVertexes(bottomLeft.vertexes, opts), ctrlOpts);
drawVertexes(ctx, calcViewVertexes(bottomRight.vertexes, opts), ctrlOpts);

// TODO
drawCircleController(ctx, calcViewPointSize(rotate.center, opts), { ...ctrlOpts, size: rotate.size, borderWidth: 0 });
const rotateCenter = calcViewPointSize(rotate.center, opts);
ctx.drawImage(
rotateControllerPattern.canvas,
0,
0,
rotateControllerPattern.canvas.width / devicePixelRatio,
rotateControllerPattern.canvas.height / devicePixelRatio,
rotateCenter.x - rotate.size / 2,
rotateCenter.y - rotate.size / 2,
rotate.size,
rotate.size
);
if (element?.operations?.rotatable !== false) {
drawCircleController(ctx, calcViewPointSize(rotate.center, opts), { ...ctrlOpts, size: rotate.size, borderWidth: 0 });
const rotateCenter = calcViewPointSize(rotate.center, opts);
ctx.drawImage(
rotateControllerPattern.canvas,
0,
0,
rotateControllerPattern.canvas.width / devicePixelRatio,
rotateControllerPattern.canvas.height / devicePixelRatio,
rotateCenter.x - rotate.size / 2,
rotateCenter.y - rotate.size / 2,
rotate.size,
rotate.size
);
}
}

// drawAuxiliaryExperimentBox(ctx, {
Expand Down
23 changes: 18 additions & 5 deletions packages/core/src/middleware/selector/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
getElementPositionFromList,
getElementPositionMapFromList,
deepResizeGroupElement,
getElementSize
getElementSize,
calcPointMoveElementInGroup,
isSameElementSize
} from '@idraw/util';
import type {
Data,
Expand Down Expand Up @@ -52,8 +54,7 @@ import {
getSelectedListArea,
calcSelectedElementsArea,
isElementInGroup,
isPointInViewActiveGroup,
calcMoveInGroup
isPointInViewActiveGroup
} from './util';
import {
keyActionType,
Expand Down Expand Up @@ -513,7 +514,7 @@ export const MiddlewareSelector: BoardMiddleware<
eventHub.trigger(MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE, { show: false });

if (data && elems?.length === 1 && moveOriginalStartElementSize && originalStart && end && elems[0]?.operations?.locked !== true) {
const { moveX, moveY } = calcMoveInGroup(originalStart, end, groupQueue);
const { moveX, moveY } = calcPointMoveElementInGroup(originalStart, end, groupQueue);

let totalMoveX = calculator.toGridNum(moveX / scale);
let totalMoveY = calculator.toGridNum(moveY / scale);
Expand Down Expand Up @@ -871,7 +872,19 @@ export const MiddlewareSelector: BoardMiddleware<

const drawBaseOpts = { calculator, viewScaleInfo, viewSizeInfo, style };

const selectedElementController = sharedStore[keySelectedElementController];
let selectedElementController = sharedStore[keySelectedElementController];
if (selectedElementController && selectedElements.length === 1 && elem) {
if (!isSameElementSize(elem, selectedElementController.originalElementSize)) {
selectedElementController = calcElementSizeController(elem, {
groupQueue: groupQueue || [],
controllerSize,
viewScaleInfo,
rotateControllerPosition,
rotateControllerSize
});
sharer.setSharedStorage(keySelectedElementController, selectedElementController);
}
}

const isHoverLocked: boolean = !!hoverElement?.operations?.locked;

Expand Down
34 changes: 4 additions & 30 deletions packages/core/src/middleware/selector/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
calcElementQueueVertexesQueueInGroup,
calcViewPointSize,
calcViewElementSize,
rotatePointInGroup,
rotatePoint,
parseAngleToRadian,
parseRadianToAngle,
Expand Down Expand Up @@ -106,7 +105,10 @@ export function getPointTarget(
// resize
if (selectedElementController) {
const { left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, rotate } = selectedElementController;
const ctrls = [left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, rotate];
const ctrls = [left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight];
if (selectedElements?.length === 1 && selectedElements?.[0]?.operations?.rotatable !== false) {
ctrls.push(rotate);
}
for (let i = 0; i < ctrls.length; i++) {
const ctrl = ctrls[i];
if (isPointInViewActiveVertexes(p, { ctx, vertexes: ctrl.vertexes, viewSizeInfo, viewScaleInfo })) {
Expand Down Expand Up @@ -968,31 +970,3 @@ export function isElementInGroup(elem: Element<ElementType>, group: Element<'gro
}
return false;
}

export function calcMoveInGroup(start: PointSize, end: PointSize, groupQueue: Element<'group'>[]): { moveX: number; moveY: number } {
let moveX = end.x - start.x;
let moveY = end.y - start.y;
const pointGroupQueue: Element<'group'>[] = [];
groupQueue.forEach((group) => {
const { x, y, w, h, angle = 0 } = group;
pointGroupQueue.push({
x,
y,
w,
h,
angle: 0 - angle
} as Element<'group'>);
});

if (groupQueue?.length > 0) {
const startInGroup = rotatePointInGroup(start, pointGroupQueue);
const endInGroup = rotatePointInGroup(end, pointGroupQueue);
moveX = endInGroup.x - startInGroup.x;
moveY = endInGroup.y - startInGroup.y;
}

return {
moveX,
moveY
};
}
3 changes: 2 additions & 1 deletion packages/idraw/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ export {
calcElementOriginRectInfo,
calcElementViewRectInfoMap,
sortElementsViewVisiableInfoMap,
flatElementList
flatElementList,
calcPointMoveElementInGroup
} from '@idraw/util';
export { iDraw } from './idraw';
export { eventKeys } from './event';
Expand Down
5 changes: 4 additions & 1 deletion packages/types/src/lib/controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ViewRectVertexes } from './view';
import { PointSize } from './point';
import { ElementSize } from './element';

export type ElementSizeControllerType =
| 'left'
Expand All @@ -24,6 +25,8 @@ export interface ElementSizeControllerItem {
}

export interface ElementSizeController {
originalElementCenter: PointSize;
originalElementSize: ElementSize;
elementWrapper: ViewRectVertexes;
top: ElementSizeControllerItem;
bottom: ElementSizeControllerItem;
Expand All @@ -40,4 +43,4 @@ export interface ElementSizeController {
rotate: ElementSizeControllerItem;
}

export type LayoutSizeController = Omit<ElementSizeController, 'rotate' | 'elementWrapper'>;
export type LayoutSizeController = Omit<ElementSizeController, 'rotate' | 'elementWrapper' | 'originalElementCenter' | 'originalElementSize'>;
5 changes: 2 additions & 3 deletions packages/types/src/lib/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,10 @@ export type ElementType = keyof ElementDetailMap;
export interface ElementOperations {
locked?: boolean;
invisible?: boolean;
disableScale?: boolean;
disableRotate?: boolean;
rotatable?: boolean;
limitRatio?: boolean;
lastModified?: number;
deepResize?: boolean;
lastModified?: number;
}

export interface ElementGlobalDetail {
Expand Down
4 changes: 3 additions & 1 deletion packages/util/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export {
isResourceElement,
getElementPositionFromList,
getElementPositionMapFromList,
calcElementListSize
calcElementListSize,
isSameElementSize
} from './lib/element';
export { checkRectIntersect } from './lib/rect';
export {
Expand Down Expand Up @@ -91,3 +92,4 @@ export { modifyElement, getModifiedElement } from './lib/modify';
export { enhanceFontFamliy } from './lib/text';
export { flatElementList } from './lib/flat';
export { groupElementsByPosition, ungroupElementsByPosition } from './lib/group';
export { calcPointMoveElementInGroup } from './lib/point-move-element';
2 changes: 2 additions & 0 deletions packages/util/src/lib/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ export function calcElementSizeController(
const rotateVertexes = calcElementVertexes(rotateSize);

const sizeController: ElementSizeController = {
originalElementCenter: calcElementCenter(elemSize),
originalElementSize: { ...elemSize },
elementWrapper: vertexes,
left: {
type: 'left',
Expand Down
8 changes: 7 additions & 1 deletion packages/util/src/lib/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type {
LoadElementType,
ElementPosition
} from '@idraw/types';
import { rotateElementVertexes } from './rotate';
import { limitAngle, rotateElementVertexes } from './rotate';
import { isAssetId, createAssetId } from './uuid';

function getGroupUUIDs(elements: Array<Element<ElementType>>, index: string): string[] {
Expand Down Expand Up @@ -504,3 +504,9 @@ export function getElementPositionMapFromList(
_loop(elements);
return positionMap;
}

export function isSameElementSize(elem1: ElementSize, elem2: ElementSize) {
return (
elem1.x === elem2.x && elem1.y === elem2.y && elem1.h === elem2.h && elem1.w === elem2.w && limitAngle(elem1.angle || 0) === limitAngle(elem2.angle || 0)
);
}
30 changes: 30 additions & 0 deletions packages/util/src/lib/point-move-element.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { PointSize, Element } from '@idraw/types';
import { rotatePointInGroup } from './rotate';

export function calcPointMoveElementInGroup(start: PointSize, end: PointSize, groupQueue: Element<'group'>[]): { moveX: number; moveY: number } {
let moveX = end.x - start.x;
let moveY = end.y - start.y;
const pointGroupQueue: Element<'group'>[] = [];
groupQueue.forEach((group) => {
const { x, y, w, h, angle = 0 } = group;
pointGroupQueue.push({
x,
y,
w,
h,
angle: 0 - angle
} as Element<'group'>);
});

if (groupQueue?.length > 0) {
const startInGroup = rotatePointInGroup(start, pointGroupQueue);
const endInGroup = rotatePointInGroup(end, pointGroupQueue);
moveX = endInGroup.x - startInGroup.x;
moveY = endInGroup.y - startInGroup.y;
}

return {
moveX,
moveY
};
}

0 comments on commit 5b263d9

Please sign in to comment.