kopia lustrzana https://github.com/Tldraw/Tldraw
Fix copy group shapes as svg (#112)
* fixes copy group shapes as svg * Update tlstate.ts * Fix failing testspull/114/head
rodzic
6ba76c0e78
commit
48f784c322
|
@ -125,4 +125,14 @@ Array [
|
|||
]
|
||||
`;
|
||||
|
||||
exports[`TLDrawState Selection When selecting all selects all: selected all 1`] = `
|
||||
Array [
|
||||
"rect1",
|
||||
"rect2",
|
||||
"rect3",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`TLDrawState When copying to SVG Copies grouped shapes.: copied svg with group 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"-16 -16 232 232\\" width=\\"200\\" height=\\"200\\"><g/></svg>"`;
|
||||
|
||||
exports[`TLDrawState When copying to SVG Copies shapes.: copied svg 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"-20.741879096242684 -20.741879096242684 236.74 236.74\\" width=\\"204.74\\" height=\\"204.74\\"/>"`;
|
||||
|
|
|
@ -113,7 +113,17 @@ describe('TLDrawState', () => {
|
|||
|
||||
it.todo('re-creates shapes on redo after creating')
|
||||
|
||||
it.todo('selects all')
|
||||
describe('When selecting all', () => {
|
||||
it('selects all', () => {
|
||||
const tlstate = new TLDrawState().loadDocument(mockDocument).selectAll()
|
||||
expect(tlstate.selectedIds).toMatchSnapshot('selected all')
|
||||
})
|
||||
|
||||
it('does not select children of a group', () => {
|
||||
const tlstate = new TLDrawState().loadDocument(mockDocument).selectAll().group()
|
||||
expect(tlstate.selectedIds.length).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
// Single click on a selected shape to select just that shape
|
||||
|
||||
|
@ -453,6 +463,17 @@ describe('TLDrawState', () => {
|
|||
expect(result).toMatchSnapshot('copied svg')
|
||||
})
|
||||
|
||||
it('Copies grouped shapes.', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
const result = tlstate
|
||||
.loadDocument(mockDocument)
|
||||
.select('rect1', 'rect2')
|
||||
.group()
|
||||
.selectAll()
|
||||
.copySvg()
|
||||
expect(result).toMatchSnapshot('copied svg with group')
|
||||
})
|
||||
|
||||
it.todo('Copies Text shapes as <text> elements.')
|
||||
// it('Copies Text shapes as <text> elements.', () => {
|
||||
// const tlstate2 = new TLDrawState()
|
||||
|
|
|
@ -979,26 +979,56 @@ export class TLDrawState extends StateManager<Data> {
|
|||
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
||||
|
||||
ids.forEach((id) => {
|
||||
const elm = document.getElementById(id + '_svg')
|
||||
// const idsToCopy = ids.flatMap((id) => TLDR.getDocumentBranch(this.state, id, pageId))
|
||||
|
||||
const shapes = ids.map((id) => this.getShape(id, pageId))
|
||||
|
||||
function getSvgElementForShape(shape: TLDrawShape) {
|
||||
const elm = document.getElementById(shape.id + '_svg')
|
||||
|
||||
if (!elm) return
|
||||
|
||||
// TODO: Create SVG elements for text
|
||||
|
||||
if (elm) {
|
||||
const clone = elm?.cloneNode(true) as SVGElement
|
||||
const shape = this.getShape(id, pageId)
|
||||
const bounds = TLDR.getShapeUtils(shape).getBounds(shape)
|
||||
clone.setAttribute(
|
||||
'transform',
|
||||
`translate(${shape.point[0]}px ${shape.point[1]}px) rotate(${
|
||||
((shape.rotation || 0) * 180) / Math.PI
|
||||
}, ${bounds.width / 2}, ${bounds.height / 2})`
|
||||
)
|
||||
svg.appendChild(clone)
|
||||
const element = elm?.cloneNode(true) as SVGElement
|
||||
|
||||
const bounds = TLDR.getShapeUtils(shape).getBounds(shape)
|
||||
|
||||
element.setAttribute(
|
||||
'transform',
|
||||
`translate(${shape.point[0]}, ${shape.point[1]}) rotate(${
|
||||
((shape.rotation || 0) * 180) / Math.PI
|
||||
}, ${bounds.width / 2}, ${bounds.height / 2})`
|
||||
)
|
||||
|
||||
return element
|
||||
}
|
||||
|
||||
shapes.forEach((shape) => {
|
||||
if (shape.children?.length) {
|
||||
// Create a group <g> element for shape
|
||||
const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')
|
||||
|
||||
// Get the shape's children as elements
|
||||
shape.children
|
||||
.map((childId) => this.getShape(childId, pageId))
|
||||
.map(getSvgElementForShape)
|
||||
.filter(Boolean)
|
||||
.forEach((element) => g.appendChild(element!))
|
||||
|
||||
// Add the group element to the SVG
|
||||
svg.appendChild(g)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const element = getSvgElementForShape(shape)
|
||||
|
||||
if (element) {
|
||||
svg.appendChild(element)
|
||||
}
|
||||
})
|
||||
|
||||
const shapes = ids.map((id) => this.getShape(id, pageId))
|
||||
const bounds = Utils.getCommonBounds(shapes.map(TLDR.getRotatedBounds))
|
||||
const padding = 16
|
||||
|
||||
|
@ -1307,13 +1337,22 @@ export class TLDrawState extends StateManager<Data> {
|
|||
/**
|
||||
* Select all shapes on the page.
|
||||
*/
|
||||
selectAll = (): this => {
|
||||
selectAll = (pageId = this.currentPageId): this => {
|
||||
if (this.session) return this
|
||||
this.setSelectedIds(Object.keys(this.page.shapes))
|
||||
|
||||
// Select only shapes that are the direct child of the page
|
||||
this.setSelectedIds(
|
||||
Object.values(this.document.pages[pageId].shapes)
|
||||
.filter((shape) => shape.parentId === pageId)
|
||||
.map((shape) => shape.id)
|
||||
)
|
||||
|
||||
this.addToSelectHistory(this.selectedIds)
|
||||
|
||||
if (this.appState.activeTool !== 'select') {
|
||||
this.selectTool('select')
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue