Adds copy to json, copy to svg
This commit is contained in:
parent
16fda2fddf
commit
e6535c4dd4
4 changed files with 120 additions and 8 deletions
|
@ -70,7 +70,7 @@ export class Ellipse extends TLDrawShapeUtil<EllipseShape> {
|
|||
rx={rx}
|
||||
ry={ry}
|
||||
stroke="none"
|
||||
fill={style.isFilled ? styles.fill : 'transparent'}
|
||||
fill={style.isFilled ? styles.fill : 'none'}
|
||||
pointerEvents="all"
|
||||
/>
|
||||
<path
|
||||
|
|
|
@ -61,7 +61,7 @@ export class Rectangle extends TLDrawShapeUtil<RectangleShape> {
|
|||
y={+styles.strokeWidth / 2}
|
||||
width={Math.max(0, size[0] - strokeWidth)}
|
||||
height={Math.max(0, size[1] - strokeWidth)}
|
||||
fill={style.isFilled ? styles.fill : 'transparent'}
|
||||
fill={style.isFilled ? styles.fill : 'none'}
|
||||
stroke="none"
|
||||
pointerEvents="all"
|
||||
/>
|
||||
|
|
|
@ -809,6 +809,38 @@ export class TLDR {
|
|||
return Array.from(bindingsToUpdate.values())
|
||||
}
|
||||
|
||||
static copyStringToClipboard = (string: string) => {
|
||||
try {
|
||||
navigator.clipboard.writeText(string)
|
||||
} catch (e) {
|
||||
const textarea = document.createElement('textarea')
|
||||
textarea.setAttribute('position', 'fixed')
|
||||
textarea.setAttribute('top', '0')
|
||||
textarea.setAttribute('readonly', 'true')
|
||||
textarea.setAttribute('contenteditable', 'true')
|
||||
textarea.style.position = 'fixed'
|
||||
textarea.value = string
|
||||
document.body.appendChild(textarea)
|
||||
textarea.focus()
|
||||
textarea.select()
|
||||
|
||||
try {
|
||||
const range = document.createRange()
|
||||
range.selectNodeContents(textarea)
|
||||
const sel = window.getSelection()
|
||||
if (sel) {
|
||||
sel.removeAllRanges()
|
||||
sel.addRange(range)
|
||||
textarea.setSelectionRange(0, textarea.value.length)
|
||||
}
|
||||
} catch (err) {
|
||||
null // Could not copy to clipboard
|
||||
} finally {
|
||||
document.body.removeChild(textarea)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* Assertions */
|
||||
/* -------------------------------------------------- */
|
||||
|
|
|
@ -711,20 +711,79 @@ export class TLDrawState extends StateManager<Data> {
|
|||
return this
|
||||
}
|
||||
|
||||
copyAsSvg = () => {
|
||||
// TODO
|
||||
return '<svg/>'
|
||||
/**
|
||||
* Copy one or more shapes as SVG.
|
||||
* @param ids The ids of the shapes to copy.
|
||||
* @param pageId The page from which to copy the shapes.
|
||||
* @returns A string containing the JSON.
|
||||
*/
|
||||
copyAsSvg = (ids = this.selectedIds, pageId = this.currentPageId) => {
|
||||
if (ids.length === 0) return
|
||||
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
||||
|
||||
ids.forEach((id) => {
|
||||
const elm = document.getElementById(id)
|
||||
if (elm) {
|
||||
const clone = elm?.cloneNode(true)
|
||||
svg.appendChild(clone)
|
||||
}
|
||||
})
|
||||
|
||||
const shapes = ids.map((id) => this.getShape(id, pageId))
|
||||
const bounds = Utils.getCommonBounds(shapes.map(TLDR.getBounds))
|
||||
const padding = 16
|
||||
|
||||
// Resize the element to the bounding box
|
||||
svg.setAttribute(
|
||||
'viewBox',
|
||||
[
|
||||
bounds.minX - padding,
|
||||
bounds.minY - padding,
|
||||
bounds.width + padding * 2,
|
||||
bounds.height + padding * 2,
|
||||
].join(' ')
|
||||
)
|
||||
|
||||
svg.setAttribute('width', String(bounds.width))
|
||||
|
||||
svg.setAttribute('height', String(bounds.height))
|
||||
|
||||
const s = new XMLSerializer()
|
||||
|
||||
const svgString = s
|
||||
.serializeToString(svg)
|
||||
.replaceAll(' ', '')
|
||||
.replaceAll(/((\s|")[0-9]*\.[0-9]{2})([0-9]*)(\b|"|\))/g, '$1')
|
||||
|
||||
TLDR.copyStringToClipboard(svgString)
|
||||
|
||||
return svgString
|
||||
}
|
||||
|
||||
copyAsJson = () => {
|
||||
// TODO
|
||||
return {}
|
||||
/**
|
||||
* Copy one or more shapes as JSON
|
||||
* @param ids The ids of the shapes to copy.
|
||||
* @param pageId The page from which to copy the shapes.
|
||||
* @returns A string containing the JSON.
|
||||
*/
|
||||
copyAsJson = (ids = this.selectedIds, pageId = this.currentPageId) => {
|
||||
const shapes = ids.map((id) => this.getShape(id, pageId))
|
||||
const json = JSON.stringify(shapes, null, 2)
|
||||
TLDR.copyStringToClipboard(json)
|
||||
return json
|
||||
}
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* Sessions */
|
||||
/* -------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Start a new session.
|
||||
* @param session The new session
|
||||
* @param args arguments of the session's start method.
|
||||
* @returns this
|
||||
*/
|
||||
startSession<T extends Session>(session: T, ...args: ParametersExceptFirst<T['start']>): this {
|
||||
this.session = session
|
||||
|
||||
|
@ -749,6 +808,11 @@ export class TLDrawState extends StateManager<Data> {
|
|||
return this.setStatus(session.status)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current session.
|
||||
* @param args The arguments of the current session's update method.
|
||||
* @returns this
|
||||
*/
|
||||
updateSession<T extends Session>(...args: ParametersExceptFirst<T['update']>): this {
|
||||
const { session } = this
|
||||
if (!session) return this
|
||||
|
@ -757,6 +821,11 @@ export class TLDrawState extends StateManager<Data> {
|
|||
return this.patchState(patch, `session:update:${session.id}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the current session.
|
||||
* @param args The arguments of the current session's cancel method.
|
||||
* @returns this
|
||||
*/
|
||||
cancelSession<T extends Session>(...args: ParametersExceptFirst<T['cancel']>): this {
|
||||
const { session } = this
|
||||
if (!session) return this
|
||||
|
@ -808,6 +877,11 @@ export class TLDrawState extends StateManager<Data> {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete the current session.
|
||||
* @param args The arguments of the current session's complete method.
|
||||
* @returns this
|
||||
*/
|
||||
completeSession<T extends Session>(...args: ParametersExceptFirst<T['complete']>) {
|
||||
const { session } = this
|
||||
|
||||
|
@ -931,11 +1005,17 @@ export class TLDrawState extends StateManager<Data> {
|
|||
/* Selection */
|
||||
/* -------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Clear the selection history (undo/redo stack for selection).
|
||||
*/
|
||||
private clearSelectHistory() {
|
||||
this.selectHistory.pointer = 0
|
||||
this.selectHistory.stack = [this.selectedIds]
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a selection to the selection history (undo/redo stack for selection).
|
||||
*/
|
||||
private addToSelectHistory(ids: string[]) {
|
||||
if (this.selectHistory.pointer < this.selectHistory.stack.length) {
|
||||
this.selectHistory.stack = this.selectHistory.stack.slice(0, this.selectHistory.pointer + 1)
|
||||
|
|
Loading…
Reference in a new issue