feat(editor): scale video embeddables based on zoom (#11251)
This commit is contained in:
@@ -603,6 +603,8 @@ const YOUTUBE_VIDEO_STATES = new Map<
|
|||||||
ValueOf<typeof YOUTUBE_STATES>
|
ValueOf<typeof YOUTUBE_STATES>
|
||||||
>();
|
>();
|
||||||
|
|
||||||
|
const MAX_EMBEDDABLE_VIEWPORT_SCALE = 4;
|
||||||
|
|
||||||
let IS_PLAIN_PASTE = false;
|
let IS_PLAIN_PASTE = false;
|
||||||
let IS_PLAIN_PASTE_TIMER = 0;
|
let IS_PLAIN_PASTE_TIMER = 0;
|
||||||
let PLAIN_PASTE_TOAST_SHOWN = false;
|
let PLAIN_PASTE_TOAST_SHOWN = false;
|
||||||
@@ -1735,6 +1737,18 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
this.state.activeEmbeddable?.element === el &&
|
this.state.activeEmbeddable?.element === el &&
|
||||||
this.state.activeEmbeddable?.state === "hover";
|
this.state.activeEmbeddable?.state === "hover";
|
||||||
|
|
||||||
|
// scale video embeds based on zoom (capped) so that smaller embeds
|
||||||
|
// on canvas when zoomed are still of legible quality
|
||||||
|
// (note: for some embed types like gdrive, the quality is poor when
|
||||||
|
// scaling mid playback and works only when you initially start the
|
||||||
|
// playback at the higher zoom level)
|
||||||
|
const shouldScaleEmbeddableViewport = src?.type === "video";
|
||||||
|
const embeddableViewportScale = clamp(
|
||||||
|
shouldScaleEmbeddableViewport ? scale : 1,
|
||||||
|
0.75,
|
||||||
|
MAX_EMBEDDABLE_VIEWPORT_SCALE,
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={el.id}
|
key={el.id}
|
||||||
@@ -1800,6 +1814,14 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
style={{
|
style={{
|
||||||
padding: `${el.strokeWidth}px`,
|
padding: `${el.strokeWidth}px`,
|
||||||
}}
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="excalidraw__embeddable__content"
|
||||||
|
style={{
|
||||||
|
width: `${embeddableViewportScale * 100}%`,
|
||||||
|
height: `${embeddableViewportScale * 100}%`,
|
||||||
|
transform: `scale(${1 / embeddableViewportScale})`,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{(isEmbeddableElement(el)
|
{(isEmbeddableElement(el)
|
||||||
? this.props.renderEmbeddable?.(el, this.state)
|
? this.props.renderEmbeddable?.(el, this.state)
|
||||||
@@ -1822,13 +1844,16 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||||
allowFullScreen={true}
|
allowFullScreen={true}
|
||||||
sandbox={`${
|
sandbox={`${
|
||||||
src?.sandbox?.allowSameOrigin ? "allow-same-origin" : ""
|
src?.sandbox?.allowSameOrigin
|
||||||
|
? "allow-same-origin"
|
||||||
|
: ""
|
||||||
} allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-downloads`}
|
} allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-downloads`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -814,6 +814,14 @@ body.excalidraw-cursor-resize * {
|
|||||||
.excalidraw__embeddable__outer {
|
.excalidraw__embeddable__outer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.excalidraw__embeddable__content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
transform-origin: top left;
|
||||||
|
|
||||||
|
&,
|
||||||
& > * {
|
& > * {
|
||||||
border-radius: var(--embeddable-radius);
|
border-radius: var(--embeddable-radius);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user