tldraw
Version:
A tiny little drawing editor.
122 lines (121 loc) • 3.02 kB
JavaScript
import {
StateNode,
Vec,
createShapeId,
maybeSnapToGrid
} from "@tldraw/editor";
import {
NOTE_ADJACENT_POSITION_SNAP_RADIUS,
getAvailableNoteAdjacentPositions
} from "../noteHelpers.mjs";
class Pointing extends StateNode {
static id = "pointing";
dragged = false;
info = {};
markId = "";
shape = {};
onEnter() {
const { editor } = this;
const id = createShapeId();
this.markId = editor.markHistoryStoppingPoint(`creating_note:${id}`);
const center = this.editor.inputs.originPagePoint.clone();
const offset = getNoteShapeAdjacentPositionOffset(
this.editor,
center,
this.editor.user.getIsDynamicResizeMode() ? 1 / this.editor.getZoomLevel() : 1
);
if (offset) {
center.sub(offset);
}
this.shape = createNoteShape(this.editor, id, center);
}
onPointerMove(info) {
if (this.editor.inputs.isDragging) {
this.editor.setCurrentTool("select.translating", {
...info,
target: "shape",
shape: this.shape,
onInteractionEnd: "note",
isCreating: true,
creatingMarkId: this.markId,
onCreate: () => {
this.editor.setEditingShape(this.shape.id);
this.editor.setCurrentTool("select.editing_shape");
}
});
}
}
onPointerUp() {
this.complete();
}
onInterrupt() {
this.cancel();
}
onComplete() {
this.complete();
}
onCancel() {
this.cancel();
}
complete() {
if (this.editor.getInstanceState().isToolLocked) {
this.parent.transition("idle");
} else {
this.editor.setEditingShape(this.shape.id);
this.editor.setCurrentTool("select.editing_shape", {
...this.info,
target: "shape",
shape: this.shape
});
}
}
cancel() {
this.editor.bailToMark(this.markId);
this.parent.transition("idle", this.info);
}
}
function getNoteShapeAdjacentPositionOffset(editor, center, scale) {
let min = NOTE_ADJACENT_POSITION_SNAP_RADIUS / editor.getZoomLevel();
let offset;
for (const pit of getAvailableNoteAdjacentPositions(editor, 0, scale, 0)) {
const deltaToPit = Vec.Sub(center, pit);
const dist = deltaToPit.len();
if (dist < min) {
min = dist;
offset = deltaToPit;
}
}
return offset;
}
function createNoteShape(editor, id, center) {
editor.createShape({
id,
type: "note",
x: center.x,
y: center.y,
props: {
scale: editor.user.getIsDynamicResizeMode() ? 1 / editor.getZoomLevel() : 1
}
}).select(id);
const shape = editor.getShape(id);
const bounds = editor.getShapeGeometry(shape).bounds;
const newPoint = maybeSnapToGrid(
new Vec(shape.x - bounds.width / 2, shape.y - bounds.height / 2),
editor
);
editor.updateShapes([
{
id,
type: "note",
x: newPoint.x,
y: newPoint.y
}
]);
return editor.getShape(id);
}
export {
Pointing,
createNoteShape,
getNoteShapeAdjacentPositionOffset
};
//# sourceMappingURL=Pointing.mjs.map