diff --git a/packages/tldraw/src/lib/shapes/image/ImageShapeUtil.tsx b/packages/tldraw/src/lib/shapes/image/ImageShapeUtil.tsx index 576db5d90..5aaba2250 100644 --- a/packages/tldraw/src/lib/shapes/image/ImageShapeUtil.tsx +++ b/packages/tldraw/src/lib/shapes/image/ImageShapeUtil.tsx @@ -186,14 +186,29 @@ export class ImageShapeUtil extends BaseBoxShapeUtil { const crop = shape.props.crop if (containerStyle.transform && crop) { const { transform, width, height } = containerStyle + const croppedWidth = (crop.bottomRight.x - crop.topLeft.x) * width + const croppedHeight = (crop.bottomRight.y - crop.topLeft.y) * height + const points = [ - new Vec2d(crop.topLeft.x * width, crop.topLeft.y * height), - new Vec2d(crop.bottomRight.x * width, crop.topLeft.y * height), - new Vec2d(crop.bottomRight.x * width, crop.bottomRight.y * height), - new Vec2d(crop.topLeft.x * width, crop.bottomRight.y * height), + new Vec2d(0, 0), + new Vec2d(croppedWidth, 0), + new Vec2d(croppedWidth, croppedHeight), + new Vec2d(0, croppedHeight), ] + + const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon') + polygon.setAttribute('points', points.map((p) => `${p.x},${p.y}`).join(' ')) + + const clipPath = document.createElementNS('http://www.w3.org/2000/svg', 'clipPath') + clipPath.setAttribute('id', 'cropClipPath') + clipPath.appendChild(polygon) + + const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs') + defs.appendChild(clipPath) + g.appendChild(defs) + const innerElement = document.createElementNS('http://www.w3.org/2000/svg', 'g') - innerElement.style.clipPath = `polygon(${points.map((p) => `${p.x}px ${p.y}px`).join(',')})` + innerElement.setAttribute('clip-path', 'url(#cropClipPath)') image.setAttribute('width', width.toString()) image.setAttribute('height', height.toString()) image.style.transform = transform diff --git a/packages/tldraw/src/lib/utils/export/copyAs.ts b/packages/tldraw/src/lib/utils/export/copyAs.ts index 379c488fd..fa657a934 100644 --- a/packages/tldraw/src/lib/utils/export/copyAs.ts +++ b/packages/tldraw/src/lib/utils/export/copyAs.ts @@ -23,7 +23,6 @@ export function copyAs( // Note: it's important that this function itself isn't async - we need to create the relevant // `ClipboardItem`s synchronously to make sure safari knows that the user _wants_ to copy // See https://bugs.webkit.org/show_bug.cgi?id=222262 - const write = window.navigator.clipboard?.write return editor .getSvg(ids?.length ? ids : [...editor.getCurrentPageShapeIds()], { @@ -39,8 +38,8 @@ export function copyAs( switch (format) { case 'svg': { if (window.navigator.clipboard) { - if (write) { - write([ + if (window.navigator.clipboard.write) { + window.navigator.clipboard.write([ new ClipboardItem({ 'text/plain': new Blob([getSvgAsString(svg)], { type: 'text/plain' }), }), @@ -71,27 +70,29 @@ export function copyAs( }) const mimeType = format === 'jpeg' ? 'image/jpeg' : 'image/png' - if (write) { - write([ - new ClipboardItem({ - [mimeType]: blobPromise, - }), - ]).catch((err: any) => { - // Firefox will fail with the above if `dom.events.asyncClipboard.clipboardItem` is enabled. - // See - if (!err.toString().match(/^TypeError: DOMString not supported/)) { - console.error(err) - } + if (window.navigator.clipboard.write) { + window.navigator.clipboard + .write([ + new ClipboardItem({ + [mimeType]: blobPromise, + }), + ]) + .catch((err: any) => { + // Firefox will fail with the above if `dom.events.asyncClipboard.clipboardItem` is enabled. + // See + if (!err.toString().match(/^TypeError: DOMString not supported/)) { + console.error(err) + } - blobPromise.then((blob) => { - window.navigator.clipboard.write([ - new ClipboardItem({ - // Note: This needs to use the promise based approach for safari/ios to not bail on a permissions error. - [mimeType]: blob, - }), - ]) + blobPromise.then((blob) => { + window.navigator.clipboard.write([ + new ClipboardItem({ + // Note: This needs to use the promise based approach for safari/ios to not bail on a permissions error. + [mimeType]: blob, + }), + ]) + }) }) - }) } break @@ -101,8 +102,8 @@ export function copyAs( const data = editor.getContentFromCurrentPage(ids) const jsonStr = JSON.stringify(data) - if (write) { - write([ + if (window.navigator.clipboard.write) { + window.navigator.clipboard.write([ new ClipboardItem({ 'text/plain': new Blob([jsonStr], { type: 'text/plain' }), }),