diff --git a/src/platform/MediaQuickview.css b/src/platform/MediaQuickview.css
index 0161fcf..3ad798c 100644
--- a/src/platform/MediaQuickview.css
+++ b/src/platform/MediaQuickview.css
@@ -47,8 +47,6 @@
max-width: 100vw;
max-height: 100vh;
contain: strict;
- display: grid;
- place-items: center;
cursor: grab;
diff --git a/src/platform/MediaQuickview.tsx b/src/platform/MediaQuickview.tsx
index e06cf0c..c4b2cde 100644
--- a/src/platform/MediaQuickview.tsx
+++ b/src/platform/MediaQuickview.tsx
@@ -56,19 +56,39 @@ export function createMediaQuickview() {
return createCallback(renderIsolateMediaQuickview);
}
+type VisualMediaMeta = {
+ width: number;
+ height: number;
+};
+
function ImagePage(props: {
src: string;
alt?: string;
scale: number;
offsetX: number;
offsetY: number;
+
+ onMetadata?(metadata: VisualMediaMeta): void;
}) {
+ const [loaded, setLoaded] = createSignal(false);
+
return (
{
+ const { naturalHeight, naturalWidth } = currentTarget;
+
+ props.onMetadata?.({
+ width: naturalWidth,
+ height: naturalHeight,
+ });
+
+ setLoaded(true);
+ }}
src={props.src}
alt={props.alt}
style={{
transform: `scale(${props.scale}) translateX(${-props.offsetX}px) translateY(${-props.offsetY}px)`,
+ opacity: loaded() ? 1 : 0,
}}
>
);
@@ -88,10 +108,6 @@ export type MediaQuickviewProps = {
onClose?(): void;
};
-function clamp(value: T, min: T, max: T) {
- return Math.max(Math.min(value, max), min);
-}
-
const MediaQuickview: Component = (props) => {
let root: HTMLDialogElement;
@@ -126,6 +142,11 @@ const MediaQuickview: Component = (props) => {
* positive = the top edge move towards top
*/
offsetY: number;
+
+ size?: {
+ width: number;
+ height: number;
+ };
}[],
);
@@ -185,7 +206,7 @@ const MediaQuickview: Component = (props) => {
return;
}
const dx = movOriginX - event.clientX;
- const dy = movOriginY - event.clientY ;
+ const dy = movOriginY - event.clientY;
setTransformations(index, ({ offsetX, offsetY }) => {
return {
@@ -202,6 +223,40 @@ const MediaQuickview: Component = (props) => {
setIsMoving(false);
};
+ const recenter = (index: number) => {
+ const sz = transformations[index].size;
+ if (!sz) return;
+ const { width, height } = sz;
+
+ const xscale = Math.min(window.innerWidth / width, 1);
+ const yscale = Math.min(window.innerHeight / height, 1);
+
+ const finalScale = Math.min(xscale, yscale);
+
+ const nheight = height * finalScale;
+ const top = (window.innerHeight - nheight) / 2;
+
+ const nwidth = width * finalScale;
+ const left = (window.innerWidth - nwidth) / 2;
+
+ setTransformations(index, {
+ scale: finalScale,
+ offsetX: -left,
+ offsetY: -top,
+ });
+ };
+
+ const onMetadata = (index: number, { width, height }: VisualMediaMeta) => {
+ setTransformations(index, {
+ size: {
+ width,
+ height,
+ },
+ });
+
+ recenter(index);
+ };
+
return (