File size: 1,960 Bytes
6f91ce5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import { BindingUtil, type BindingOnShapeChangeOptions } from 'tldraw'
import { NOTE_PIN_TYPE, notePinMigrations, notePinProps, type NotePinBinding } from '../../shared/bindings'
type Options = BindingOnShapeChangeOptions<NotePinBinding>
const near = (a: number, b: number) => Math.abs(a - b) < 0.5
/**
* A built-in note pinned to a paper card, after tldraw's sticker-bindings example: the note keeps
* its offset as the paper moves, and stays (unpinned) when the paper is deleted, because the
* editor removes the binding along with the paper.
*/
export class NotePinBindingUtil extends BindingUtil<NotePinBinding> {
static override type = NOTE_PIN_TYPE
static override props = notePinProps
static override migrations = notePinMigrations
override getDefaultProps() {
return { dx: 0, dy: 0 }
}
// the paper moved: bring the note along
override onAfterChangeToShape({ binding, shapeAfter }: Options) {
const note = this.editor.getShape(binding.fromId)
if (!note) return
const paper = this.editor.getShapePageTransform(shapeAfter).point()
const target = { x: paper.x + binding.props.dx, y: paper.y + binding.props.dy }
const current = this.editor.getShapePageTransform(note).point()
if (near(current.x, target.x) && near(current.y, target.y)) return
const { x, y } = this.editor.getPointInParentSpace(note, target)
this.editor.updateShape({ id: note.id, type: note.type, x, y })
}
// the note itself was moved: keep its new place next to the paper
override onAfterChangeFromShape({ binding, shapeAfter }: Options) {
const paper = this.editor.getShape(binding.toId)
if (!paper) return
const p = this.editor.getShapePageTransform(paper).point()
const n = this.editor.getShapePageTransform(shapeAfter).point()
const dx = n.x - p.x
const dy = n.y - p.y
if (near(dx, binding.props.dx) && near(dy, binding.props.dy)) return
this.editor.updateBinding({ id: binding.id, type: binding.type, props: { dx, dy } })
}
}
|