kopia lustrzana https://github.com/Tldraw/Tldraw
90 wiersze
2.3 KiB
TypeScript
90 wiersze
2.3 KiB
TypeScript
import { Box, Editor, TLFrameShape, TLShapeId, TLShapePartial, Vec, compact } from '@tldraw/editor'
|
|
|
|
/**
|
|
* Remove a frame.
|
|
*
|
|
* @param editor - tlraw editor instance.
|
|
* @param ids - Ids of the frames you wish to remove.
|
|
*
|
|
* @public
|
|
*/
|
|
export function removeFrame(editor: Editor, ids: TLShapeId[]) {
|
|
const frames = compact(
|
|
ids
|
|
.map((id) => editor.getShape<TLFrameShape>(id))
|
|
.filter((f) => f && editor.isShapeOfType<TLFrameShape>(f, 'frame'))
|
|
)
|
|
if (!frames.length) return
|
|
|
|
const allChildren: TLShapeId[] = []
|
|
frames.map((frame) => {
|
|
const children = editor.getSortedChildIdsForParent(frame.id)
|
|
if (children.length) {
|
|
editor.reparentShapes(children, frame.parentId, frame.index)
|
|
allChildren.push(...children)
|
|
}
|
|
})
|
|
editor.setSelectedShapes(allChildren)
|
|
editor.deleteShapes(ids)
|
|
}
|
|
|
|
/** @internal */
|
|
export const DEFAULT_FRAME_PADDING = 50
|
|
|
|
/**
|
|
* Fit a frame to its content.
|
|
*
|
|
* @param id - Id of the frame you wish to fit to content.
|
|
* @param editor - tlraw editor instance.
|
|
* @param opts - Options for fitting the frame.
|
|
*
|
|
* @public
|
|
*/
|
|
export function fitFrameToContent(editor: Editor, id: TLShapeId, opts = {} as { padding: number }) {
|
|
const frame = editor.getShape<TLFrameShape>(id)
|
|
if (!frame) return
|
|
|
|
const childIds = editor.getSortedChildIdsForParent(frame.id)
|
|
const children = compact(childIds.map((id) => editor.getShape(id)))
|
|
if (!children.length) return
|
|
|
|
const bounds = Box.FromPoints(
|
|
children.flatMap((shape) => {
|
|
const geometry = editor.getShapeGeometry(shape.id)
|
|
return editor.getShapeLocalTransform(shape)!.applyToPoints(geometry.vertices)
|
|
})
|
|
)
|
|
|
|
const { padding = DEFAULT_FRAME_PADDING } = opts
|
|
const w = bounds.w + 2 * padding
|
|
const h = bounds.h + 2 * padding
|
|
const dx = padding - bounds.minX
|
|
const dy = padding - bounds.minY
|
|
// The shapes already perfectly fit the frame.
|
|
if (dx === 0 && dy === 0 && frame.props.w === w && frame.props.h === h) return
|
|
|
|
const diff = new Vec(dx, dy).rot(frame.rotation)
|
|
const changes: TLShapePartial[] = childIds.map((child) => {
|
|
const shape = editor.getShape(child)!
|
|
return {
|
|
id: shape.id,
|
|
type: shape.type,
|
|
x: shape.x + dx,
|
|
y: shape.y + dy,
|
|
}
|
|
})
|
|
|
|
changes.push({
|
|
id: frame.id,
|
|
type: frame.type,
|
|
x: frame.x - diff.x,
|
|
y: frame.y - diff.y,
|
|
props: {
|
|
w,
|
|
h,
|
|
},
|
|
})
|
|
|
|
editor.updateShapes(changes)
|
|
}
|