mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-16 05:47:09 +08:00
init: the first public commit for AFFiNE
This commit is contained in:
177
libs/components/board-sessions/src/rotate-session.ts
Normal file
177
libs/components/board-sessions/src/rotate-session.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
import { Utils } from '@tldraw/core';
|
||||
import { Vec } from '@tldraw/vec';
|
||||
import {
|
||||
SessionType,
|
||||
TldrawCommand,
|
||||
TldrawPatch,
|
||||
TDShape,
|
||||
TDStatus,
|
||||
} from '@toeverything/components/board-types';
|
||||
import { TLDR } from '@toeverything/components/board-state';
|
||||
import { BaseSession } from './base-session';
|
||||
import type { TldrawApp } from '@toeverything/components/board-state';
|
||||
|
||||
export class RotateSession extends BaseSession {
|
||||
type = SessionType.Rotate;
|
||||
status = TDStatus.Transforming;
|
||||
performanceMode: undefined;
|
||||
delta = [0, 0];
|
||||
commonBoundsCenter: number[];
|
||||
initialAngle: number;
|
||||
initialShapes: {
|
||||
shape: TDShape;
|
||||
center: number[];
|
||||
}[];
|
||||
changes: Record<string, Partial<TDShape>> = {};
|
||||
|
||||
constructor(app: TldrawApp) {
|
||||
super(app);
|
||||
|
||||
const {
|
||||
app: { currentPageId, pageState, originPoint },
|
||||
} = this;
|
||||
|
||||
const initialShapes = TLDR.get_selected_branch_snapshot(
|
||||
app.state,
|
||||
currentPageId
|
||||
).filter(shape => !shape.isLocked);
|
||||
|
||||
if (initialShapes.length === 0) {
|
||||
throw Error('No selected shapes!');
|
||||
}
|
||||
|
||||
if (app.rotationInfo.selectedIds === pageState.selectedIds) {
|
||||
if (app.rotationInfo.center === undefined) {
|
||||
throw Error('We should have a center for rotation!');
|
||||
}
|
||||
|
||||
this.commonBoundsCenter = app.rotationInfo.center;
|
||||
} else {
|
||||
this.commonBoundsCenter = Utils.getBoundsCenter(
|
||||
Utils.getCommonBounds(initialShapes.map(TLDR.get_bounds))
|
||||
);
|
||||
app.rotationInfo.selectedIds = pageState.selectedIds;
|
||||
app.rotationInfo.center = this.commonBoundsCenter;
|
||||
}
|
||||
|
||||
this.initialShapes = initialShapes
|
||||
.filter(shape => shape.children === undefined)
|
||||
.map(shape => {
|
||||
return {
|
||||
shape,
|
||||
center: this.app.getShapeUtil(shape).getCenter(shape),
|
||||
};
|
||||
});
|
||||
|
||||
this.initialAngle = Vec.angle(this.commonBoundsCenter, originPoint);
|
||||
}
|
||||
|
||||
start = (): TldrawPatch | undefined => void null;
|
||||
|
||||
update = (): TldrawPatch | undefined => {
|
||||
const {
|
||||
commonBoundsCenter,
|
||||
initialShapes,
|
||||
app: { currentPageId, currentPoint, shiftKey },
|
||||
} = this;
|
||||
|
||||
const shapes: Record<string, Partial<TDShape>> = {};
|
||||
|
||||
let directionDelta =
|
||||
Vec.angle(commonBoundsCenter, currentPoint) - this.initialAngle;
|
||||
|
||||
if (shiftKey) {
|
||||
directionDelta = Utils.snapAngleToSegments(directionDelta, 24); // 15 degrees
|
||||
}
|
||||
|
||||
// Update the shapes
|
||||
initialShapes.forEach(({ center, shape }) => {
|
||||
const { rotation = 0 } = shape;
|
||||
let shapeDelta = 0;
|
||||
|
||||
if (shiftKey) {
|
||||
const snappedRotation = Utils.snapAngleToSegments(rotation, 24);
|
||||
shapeDelta = snappedRotation - rotation;
|
||||
}
|
||||
|
||||
const change = TLDR.get_rotated_shape_mutation(
|
||||
shape,
|
||||
center,
|
||||
commonBoundsCenter,
|
||||
shiftKey ? directionDelta + shapeDelta : directionDelta
|
||||
);
|
||||
|
||||
if (change) {
|
||||
shapes[shape.id] = change;
|
||||
}
|
||||
});
|
||||
|
||||
this.changes = shapes;
|
||||
|
||||
return {
|
||||
document: {
|
||||
pages: {
|
||||
[currentPageId]: {
|
||||
shapes,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
cancel = (): TldrawPatch | undefined => {
|
||||
const {
|
||||
initialShapes,
|
||||
app: { currentPageId },
|
||||
} = this;
|
||||
|
||||
const shapes: Record<string, TDShape> = {};
|
||||
initialShapes.forEach(({ shape }) => (shapes[shape.id] = shape));
|
||||
|
||||
return {
|
||||
document: {
|
||||
pages: {
|
||||
[currentPageId]: {
|
||||
shapes,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
complete = (): TldrawPatch | TldrawCommand | undefined => {
|
||||
const {
|
||||
initialShapes,
|
||||
app: { currentPageId },
|
||||
} = this;
|
||||
|
||||
const beforeShapes = {} as Record<string, Partial<TDShape>>;
|
||||
const afterShapes = this.changes;
|
||||
|
||||
initialShapes.forEach(({ shape: { id, point, rotation, handles } }) => {
|
||||
beforeShapes[id] = { point, rotation, handles };
|
||||
});
|
||||
|
||||
return {
|
||||
id: 'rotate',
|
||||
before: {
|
||||
document: {
|
||||
pages: {
|
||||
[currentPageId]: {
|
||||
shapes: beforeShapes,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
after: {
|
||||
document: {
|
||||
pages: {
|
||||
[currentPageId]: {
|
||||
shapes: afterShapes,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user