import { useCallback } from "react" import { BaseBoxShapeUtil, Geometry2d, RecordProps, Rectangle2d, SVGContainer, ShapeUtil, T, TLBaseShape, getPerfectDashProps, resizeBox, useValue, } from "tldraw" import { moveToSlide, useSlides } from "@/slides/useSlides" export type ISlideShape = TLBaseShape< "Slide", { w: number h: number } > export class SlideShape extends BaseBoxShapeUtil { static override type = "Slide" // static override props = { // w: T.number, // h: T.number, // } override canBind = () => false override hideRotateHandle = () => true getDefaultProps(): ISlideShape["props"] { return { w: 720, h: 480, } } getGeometry(shape: ISlideShape): Geometry2d { // isFilled must be true for proper hit testing and nearestPoint calculation return new Rectangle2d({ width: Math.max(shape.props.w, 1), height: Math.max(shape.props.h, 1), isFilled: true, }) } override onRotate = (initial: ISlideShape) => initial override onResize(shape: ISlideShape, info: any) { return resizeBox(shape, info) } override onDoubleClick = (shape: ISlideShape) => { moveToSlide(this.editor, shape) this.editor.selectNone() } override onDoubleClickEdge = (shape: ISlideShape) => { moveToSlide(this.editor, shape) this.editor.selectNone() } component(shape: ISlideShape) { const bounds = this.editor.getShapeGeometry(shape).bounds // eslint-disable-next-line react-hooks/rules-of-hooks const zoomLevel = useValue("zoom level", () => this.editor.getZoomLevel(), [ this.editor, ]) // eslint-disable-next-line react-hooks/rules-of-hooks const slides = useSlides() const index = Array.isArray(slides) ? slides.findIndex((s) => s.id === shape.id) : -1 // eslint-disable-next-line react-hooks/rules-of-hooks const handleLabelPointerDown = useCallback( () => this.editor.select(shape.id), [shape.id], ) if (!bounds) return null return ( <>
{`Slide ${index + 1}`}
{bounds.sides.map((side, i) => { const { strokeDasharray, strokeDashoffset } = getPerfectDashProps( side[0].dist(side[1]), 1 / zoomLevel, { style: "dashed", lengthRatio: 6, }, ) return ( ) })} ) } indicator(shape: ISlideShape) { return } }