diff --git a/src/components/App.tsx b/src/components/App.tsx index 42080e831..7ce561df3 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -868,6 +868,10 @@ class App extends React.Component { this.state.activeEmbeddable?.element === el && this.state.activeEmbeddable?.state === "hover"; + // Modify the scale based on el.scale property + const [xScale, yScale] = el.scale; + const scaledTransform = `scale(${scale * xScale}, ${scale * yScale})`; + return (
{ transform: isVisible ? `translate(${x - this.state.offsetLeft}px, ${ y - this.state.offsetTop - }px) scale(${scale})` + }px) ${scaledTransform}` : "none", display: isVisible ? "block" : "none", opacity: el.opacity / 100, @@ -907,8 +911,8 @@ class App extends React.Component { }}*/ className="excalidraw__embeddable-container__inner" style={{ - width: isVisible ? `${el.width}px` : 0, - height: isVisible ? `${el.height}px` : 0, + width: isVisible ? `${el.width / xScale}px` : 0, + height: isVisible ? `${el.height / yScale}px` : 0, transform: isVisible ? `rotate(${el.angle}rad)` : "none", pointerEvents: isActive ? POINTER_EVENTS.enabled diff --git a/src/data/restore.ts b/src/data/restore.ts index d9ea999ff..0005859c6 100644 --- a/src/data/restore.ts +++ b/src/data/restore.ts @@ -297,6 +297,7 @@ const restoreElement = ( case "embeddable": return restoreElementWithProperties(element, { validated: null, + scale: [1, 1], }); case "frame": return restoreElementWithProperties(element, { diff --git a/src/element/embeddable.ts b/src/element/embeddable.ts index e03ea7a61..1d875d2a9 100644 --- a/src/element/embeddable.ts +++ b/src/element/embeddable.ts @@ -27,7 +27,7 @@ type EmbeddedLink = const embeddedLinkCache = new Map(); const RE_YOUTUBE = - /^(?:http(?:s)?:\/\/)?(?:www\.)?youtu(?:be\.com|\.be)\/(embed\/|watch\?v=|shorts\/|playlist\?list=|embed\/videoseries\?list=)?([a-zA-Z0-9_-]+)(?:\?t=|&t=|\?start=|&start=)?([a-zA-Z0-9_-]+)?[^\s]*$/; + /^(?:http(?:s)?:\/\/)?(?:www\.)?youtu(?:be\.com|\.be)\/(embed\/|watch\?v=|shorts\/|playlist\?list=|embed\/videoseries\?list=)?([a-zA-Z0-9_-]+)(?:\?t=|.*&t=|\?start=|.*&start=)?([a-zA-Z0-9_-]+)?[^\s]*$/; const RE_VIMEO = /^(?:http(?:s)?:\/\/)?(?:(?:w){3}.)?(?:player\.)?vimeo\.com\/(?:video\/)?([^?\s]+)(?:\?.*)?$/; diff --git a/src/element/newElement.ts b/src/element/newElement.ts index 0ffd9df54..40fa13a10 100644 --- a/src/element/newElement.ts +++ b/src/element/newElement.ts @@ -140,6 +140,7 @@ export const newEmbeddableElement = ( return { ..._newElementBase("embeddable", opts), validated: opts.validated, + scale: [1, 1], }; }; diff --git a/src/element/resizeElements.ts b/src/element/resizeElements.ts index b4974848e..c89fea50d 100644 --- a/src/element/resizeElements.ts +++ b/src/element/resizeElements.ts @@ -27,6 +27,7 @@ import { import { isArrowElement, isBoundToContainer, + isEmbeddableElement, isFrameElement, isFreeDrawElement, isImageElement, @@ -586,15 +587,24 @@ export const resizeSingleElement = ( }; if ("scale" in element && "scale" in stateAtResizeStart) { - mutateElement(element, { - scale: [ - // defaulting because scaleX/Y can be 0/-0 - (Math.sign(newBoundsX2 - stateAtResizeStart.x) || - stateAtResizeStart.scale[0]) * stateAtResizeStart.scale[0], - (Math.sign(newBoundsY2 - stateAtResizeStart.y) || - stateAtResizeStart.scale[1]) * stateAtResizeStart.scale[1], - ], - }); + if (isEmbeddableElement(element) && shouldMaintainAspectRatio) { + const scale: [number, number] = [ + eleNewWidth / (stateAtResizeStart.width / stateAtResizeStart.scale[0]), + eleNewHeight / + (stateAtResizeStart.height / stateAtResizeStart.scale[1]), + ]; + mutateElement(element, { scale }); + } else { + mutateElement(element, { + scale: [ + // defaulting because scaleX/Y can be 0/-0 + (Math.sign(newBoundsX2 - stateAtResizeStart.x) || + stateAtResizeStart.scale[0]) * stateAtResizeStart.scale[0], + (Math.sign(newBoundsY2 - stateAtResizeStart.y) || + stateAtResizeStart.scale[1]) * stateAtResizeStart.scale[1], + ], + }); + } } if ( diff --git a/src/element/types.ts b/src/element/types.ts index e8d71cae5..0d169f2b0 100644 --- a/src/element/types.ts +++ b/src/element/types.ts @@ -95,6 +95,7 @@ export type ExcalidrawEmbeddableElement = _ExcalidrawElementBase & * may not have access to host-app supplied url validator during restore. */ validated: boolean | null; + scale: [number, number]; }>; export type ExcalidrawImageElement = _ExcalidrawElementBase & diff --git a/src/tests/fixtures/elementFixture.ts b/src/tests/fixtures/elementFixture.ts index 7f1231a83..101b7a23c 100644 --- a/src/tests/fixtures/elementFixture.ts +++ b/src/tests/fixtures/elementFixture.ts @@ -35,6 +35,7 @@ export const embeddableFixture: ExcalidrawElement = { ...elementBase, type: "embeddable", validated: null, + scale: [1, 1], }; export const ellipseFixture: ExcalidrawElement = { ...elementBase,