Skip to content

Commit

Permalink
feat: snap graphics when creating
Browse files Browse the repository at this point in the history
  • Loading branch information
F-star committed Jan 12, 2025
1 parent 6ae56b7 commit 66681f4
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 20 deletions.
28 changes: 13 additions & 15 deletions packages/core/src/ref_line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ export class RefLine {

constructor(private editor: SuikaEditor) {}

cacheXYToBbox() {
/**
* cache reference line of graphics in viewport
*/
cacheGraphicsRefLines() {
this.clear();

const vRefLineMap = this.vRefLineMap;
Expand Down Expand Up @@ -100,9 +103,9 @@ export class RefLine {
}

// bbox 中水平线
this.addBboxToMap(vRefLineMap, bbox.midX, [bbox.minY, bbox.maxY]);
RefLine.addRefLinesToMap(vRefLineMap, bbox.midX, [bbox.minY, bbox.maxY]);
// bbox 中垂直线
this.addBboxToMap(hRefLineMap, bbox.midY, [bbox.minX, bbox.maxX]);
RefLine.addRefLinesToMap(hRefLineMap, bbox.midY, [bbox.minX, bbox.maxX]);

/**
* 获取旋转后4个顶点的坐标
Expand Down Expand Up @@ -141,11 +144,11 @@ export class RefLine {

// top 和 bottom 要绘制水平参考线,不要绘制垂直参照线
for (const p of [...top, ...bottom]) {
this.addBboxToMap(vRefLineMap, p.x, [p.y]);
RefLine.addRefLinesToMap(vRefLineMap, p.x, [p.y]);
}
// left 和 right 要绘制垂直参照线,不要绘制水平参照线
for (const p of [...left, ...right]) {
this.addBboxToMap(hRefLineMap, p.y, [p.x]);
RefLine.addRefLinesToMap(hRefLineMap, p.y, [p.x]);
}
}

Expand All @@ -160,7 +163,7 @@ export class RefLine {
this.toDrawVLines = [];
this.toDrawHLines = [];
}
private addBboxToMap(
static addRefLinesToMap(
m: Map<number, Set<number>>,
xOrY: number,
xsOrYs: number[],
Expand All @@ -175,7 +178,7 @@ export class RefLine {
}
}

private getTargetPointFromSelect(record: Map<string, ITransformRect>) {
static getGraphicsTargetPoints(record: Map<string, ITransformRect>) {
let targetPoints: IPoint[] = [];
// 选中的为单个图形,要以旋转后的 4 个顶点和中心点为目标线
if (record.size === 1) {
Expand Down Expand Up @@ -213,12 +216,7 @@ export class RefLine {
* update ref line
* and return offset
*/
updateRefLine(record: Map<string, ITransformRect>): {
offsetX: number;
offsetY: number;
} {
const targetPoints = this.getTargetPointFromSelect(record);

getGraphicsSnapOffset(targetPoints: IPoint[]): IPoint | undefined {
this.toDrawVLines = [];
this.toDrawHLines = [];

Expand All @@ -234,7 +232,7 @@ export class RefLine {

// there are no reference graphs
if (sortedXs.length === 0 && sortedYs.length === 0) {
return { offsetX: 0, offsetY: 0 };
return undefined;
}

let offsetX: number | undefined = undefined;
Expand Down Expand Up @@ -334,7 +332,7 @@ export class RefLine {
});
}

return { offsetX: offsetX ?? 0, offsetY: offsetY ?? 0 };
return { x: offsetX ?? 0, y: offsetY ?? 0 };
}

drawRefLine(ctx: CanvasRenderingContext2D) {
Expand Down
33 changes: 32 additions & 1 deletion packages/core/src/tools/tool_draw_graphics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ export abstract class DrawGraphicsTool implements ITool {
};
hotkeysManager.on('shiftToggle', updateRect);

const updateRefLinesWhenViewportTranslate = () => {
if (editor.hostEventManager.isDraggingCanvasBySpace) {
return;
}
if (this.isDragging) {
this.editor.refLine.cacheGraphicsRefLines();
}
};
const updateRectWhenViewportTranslate = () => {
if (editor.hostEventManager.isDraggingCanvasBySpace) {
return;
Expand All @@ -68,10 +76,18 @@ export abstract class DrawGraphicsTool implements ITool {
this.updateRect();
}
};
editor.viewportManager.on(
'xOrYChange',
updateRefLinesWhenViewportTranslate,
);
editor.viewportManager.on('xOrYChange', updateRectWhenViewportTranslate);

this.unbindEvent = () => {
hotkeysManager.off('shiftToggle', updateRect);
editor.viewportManager.off(
'xOrYChange',
updateRefLinesWhenViewportTranslate,
);
editor.viewportManager.off('xOrYChange', updateRectWhenViewportTranslate);
};
}
Expand Down Expand Up @@ -117,13 +133,27 @@ export abstract class DrawGraphicsTool implements ITool {
if (this.editor.hostEventManager.isDraggingCanvasBySpace) {
return;
}
this.isDragging = true;
this.lastDragPointInViewport = this.editor.getCursorXY(e);

this.lastDragPoint = this.lastMousePoint = SnapHelper.getSnapPtBySetting(
this.editor.getSceneCursorXY(e),
this.editor.setting,
);

if (!this.isDragging) {
this.editor.refLine.cacheGraphicsRefLines();
}
const offset = this.editor.refLine.getGraphicsSnapOffset([
this.lastDragPoint,
]);
if (offset) {
this.lastDragPoint = {
x: this.lastDragPoint.x + offset.x,
y: this.lastDragPoint.y + offset.y,
};
}
this.isDragging = true;

this.updateRect();
}
/**
Expand Down Expand Up @@ -346,5 +376,6 @@ export abstract class DrawGraphicsTool implements ITool {
}
this.startPointWhenSpaceDown = null;
this.lastDragPointWhenSpaceDown = null;
this.editor.refLine.clear();
}
}
10 changes: 6 additions & 4 deletions packages/core/src/tools/tool_select/tool_select_move.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type SuikaGraphics,
} from '../../graphics';
import { type SuikaCanvas } from '../../graphics/canvas';
import { RefLine } from '../../ref_line';
import { Transaction } from '../../transaction';
import { getDeepFrameAtPoint } from '../../utils';
import { type IBaseTool } from '../type';
Expand Down Expand Up @@ -85,7 +86,7 @@ export class SelectMoveTool implements IBaseTool {
this.prevBBoxPos = { x: boundingRect.x, y: boundingRect.y };
}

this.editor.refLine.cacheXYToBbox();
this.editor.refLine.cacheGraphicsRefLines();
}
onDrag(e: PointerEvent) {
this.dragPoint = this.editor.getCursorXY(e);
Expand Down Expand Up @@ -141,7 +142,8 @@ export class SelectMoveTool implements IBaseTool {
});
}

const { offsetX, offsetY } = this.editor.refLine.updateRefLine(record);
const targetPoints = RefLine.getGraphicsTargetPoints(record);
const offset = this.editor.refLine.getGraphicsSnapOffset(targetPoints);

const canvasGraphics = this.editor.doc.getCanvas();
const newParent =
Expand All @@ -155,8 +157,8 @@ export class SelectMoveTool implements IBaseTool {
const newWorldTf = cloneDeep(
this.originWorldTfMap.get(graphics.attrs.id)!,
);
newWorldTf[4] += dx + offsetX;
newWorldTf[5] += dy + offsetY;
newWorldTf[4] += dx + (offset?.x ?? 0);
newWorldTf[5] += dy + (offset?.y ?? 0);

// change parent
if (this.prevParent !== newParent) {
Expand Down

0 comments on commit 66681f4

Please sign in to comment.