Skip to content

Commit

Permalink
feat: change align logic
Browse files Browse the repository at this point in the history
  • Loading branch information
F-star committed Jun 12, 2024
1 parent 602f0c1 commit 31092e6
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 126 deletions.
121 changes: 0 additions & 121 deletions packages/core/src/commands/align.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/core/src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * from './add_graphs';
export * from './align';
export * from './command_manager';
export * from './macro';
export * from './remove_graphs';
Expand Down
114 changes: 110 additions & 4 deletions packages/core/src/service/align_and_record.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,119 @@
import { AlignCmd, type AlignType } from '../commands/align';
import { cloneDeep } from '@suika/common';
import { type IMatrixArr, mergeBoxes } from '@suika/geo';

import { type Editor } from '../editor';
import { type SuikaGraphics } from '../graphs';
import { Transaction } from '../transaction';
import { AlignType } from '../type';

/**
* Align graphics
* reference: https://mp.weixin.qq.com/s/9mGZYP_EPL7r-JVjOwyotw
*/
export const alignAndRecord = (editor: Editor, type: AlignType) => {
if (editor.selectedElements.size() < 2) {
console.warn('can align zero or two elements, fail silently');
return;
}
editor.commandManager.pushCommand(
new AlignCmd('Align ' + type, editor.selectedElements.getItems(), type),
);

const graphicsArr = editor.selectedElements.getItems();

const bboxes = graphicsArr.map((item) => item.getBbox());
const worldTfs = graphicsArr.map((item) => item.getWorldTransform());
const mixedBBox = mergeBoxes(bboxes);

const transaction = new Transaction(editor);

const updateGraphicsPosition = (
graphics: SuikaGraphics,
worldTf: IMatrixArr,
dx: number,
dy: number,
) => {
transaction.recordOld(graphics.attrs.id, {
transform: cloneDeep(graphics.attrs.transform),
});

const newWorldTf = cloneDeep(worldTf);
newWorldTf[4] += dx;
newWorldTf[5] += dy;
graphics.setWorldTransform(newWorldTf);

transaction.update(graphics.attrs.id, {
transform: cloneDeep(graphics.attrs.transform),
});
};

switch (type) {
case AlignType.Left: {
for (let i = 0; i < graphicsArr.length; i++) {
const graphics = graphicsArr[i];
const dx = mixedBBox.minX - bboxes[i].minX;
if (dx !== 0) {
updateGraphicsPosition(graphics, worldTfs[i], dx, 0);
}
}
break;
}
case AlignType.HCenter: {
const centerX = mixedBBox.minX / 2 + mixedBBox.maxX / 2;
for (let i = 0; i < graphicsArr.length; i++) {
const graphics = graphicsArr[i];
const dx = centerX - (bboxes[i].minX / 2 + bboxes[i].maxX / 2);
if (dx !== 0) {
updateGraphicsPosition(graphics, worldTfs[i], dx, 0);
}
}
break;
}
case AlignType.Right: {
for (let i = 0; i < graphicsArr.length; i++) {
const graphics = graphicsArr[i];
const dx = mixedBBox.maxX - bboxes[i].maxX;
if (dx !== 0) {
updateGraphicsPosition(graphics, worldTfs[i], dx, 0);
}
}
break;
}
case AlignType.Top: {
for (let i = 0; i < graphicsArr.length; i++) {
const graphics = graphicsArr[i];
const dy = mixedBBox.minY - bboxes[i].minY;
if (dy !== 0) {
updateGraphicsPosition(graphics, worldTfs[i], 0, dy);
}
}
break;
}
case AlignType.VCenter: {
const centerY = mixedBBox.minY / 2 + mixedBBox.maxY / 2;
for (let i = 0; i < graphicsArr.length; i++) {
const graphics = graphicsArr[i];
const dy = centerY - (bboxes[i].minY / 2 + bboxes[i].maxY / 2);
if (dy !== 0) {
updateGraphicsPosition(graphics, worldTfs[i], 0, dy);
}
}
break;
}
case AlignType.Bottom: {
for (let i = 0; i < graphicsArr.length; i++) {
const graphics = graphicsArr[i];
const dy = mixedBBox.maxY - bboxes[i].maxY;
if (dy !== 0) {
updateGraphicsPosition(graphics, worldTfs[i], 0, dy);
}
}
break;
}
default: {
console.warn('invalid type:', type);
break;
}
}

transaction.updateParentSize(graphicsArr);
transaction.commit('Align ' + type);
editor.render();
};
9 changes: 9 additions & 0 deletions packages/core/src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,12 @@ export interface IFillStrokeSVGAttrs {
stroke?: string;
'stroke-opacity'?: number;
}

export enum AlignType {
Left = 'Left',
HCenter = 'HCenter',
Right = 'Right',
Top = 'Top',
VCenter = 'VCenter',
Bottom = 'Bottom',
}

0 comments on commit 31092e6

Please sign in to comment.