1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-07-25 07:25:04 +02:00
This commit is contained in:
syuilo
2026-07-10 17:08:47 +09:00
parent a129b453b0
commit c5dd17e7e2
2 changed files with 20 additions and 20 deletions

View File

@@ -102,11 +102,13 @@ onMounted(() => {
const padding = deviceKind === 'smartphone' ? 0 : 30;
const ANIMATION_DURATION = 200;
const headerAreaSize = 0;
const footerAreaSize = 30;
// maxからはみ出す場合は縮小、maxに満たない場合は拡大する(contain)
function calcImageRenderingSize(image: Image) {
const maxWidth = window.innerWidth - padding * 2;
const maxHeight = window.innerHeight - padding * 2;
const maxHeight = window.innerHeight - headerAreaSize - footerAreaSize - padding * 2;
const widthRatio = maxWidth / image.width;
const heightRatio = maxHeight / image.height;
@@ -119,6 +121,12 @@ function calcImageRenderingSize(image: Image) {
}
const imageRenderingSize = calcImageRenderingSize(props.image);
const imageRenderingRect = {
left: (window.innerWidth - imageRenderingSize.width) / 2,
top: headerAreaSize + (window.innerHeight - headerAreaSize - footerAreaSize - imageRenderingSize.height) / 2,
width: imageRenderingSize.width,
height: imageRenderingSize.height,
};
const transform = ref({ x: 0, y: 0, scale: 1 });
// 元のimg要素の位置・サイズ(とobject-fitの設定値)を取得して、そこからneutralの位置にアニメーションするためのscaleとtranslationを計算する
@@ -128,12 +136,8 @@ function getScaleAndTranslationForSourceElement(): { x: number; y: number; scale
return calculateSourceTransform({
fit: window.getComputedStyle(sourceElement).objectFit,
imageRenderingSize,
imageRenderingRect,
sourceRect: sourceElement.getBoundingClientRect(),
viewportSize: {
width: window.innerWidth,
height: window.innerHeight,
},
});
}
@@ -429,10 +433,10 @@ watch(thumbnailImageLoaded, () => {
-webkit-touch-callout: none;
user-select: none;
position: absolute;
top: 0;
top: v-bind("headerAreaSize + 'px'");
left: 0;
right: 0;
bottom: 0;
bottom: v-bind("footerAreaSize + 'px'");
margin: auto;
}

View File

@@ -15,29 +15,25 @@ type Rect = Size & {
export function calculateSourceTransform({
fit,
imageRenderingSize,
imageRenderingRect,
sourceRect,
viewportSize,
}: {
fit: string;
imageRenderingSize: Size;
imageRenderingRect: Rect;
sourceRect: Rect;
viewportSize: Size;
}): { x: number; y: number; scale: number } {
const scale = fit === 'cover'
? Math.max(sourceRect.width / imageRenderingSize.width, sourceRect.height / imageRenderingSize.height)
: Math.min(sourceRect.width / imageRenderingSize.width, sourceRect.height / imageRenderingSize.height);
? Math.max(sourceRect.width / imageRenderingRect.width, sourceRect.height / imageRenderingRect.height)
: Math.min(sourceRect.width / imageRenderingRect.width, sourceRect.height / imageRenderingRect.height);
const neutralLeft = (viewportSize.width - imageRenderingSize.width) / 2;
const neutralTop = (viewportSize.height - imageRenderingSize.height) / 2;
const sourceImageWidth = imageRenderingSize.width * scale;
const sourceImageHeight = imageRenderingSize.height * scale;
const sourceImageWidth = imageRenderingRect.width * scale;
const sourceImageHeight = imageRenderingRect.height * scale;
const sourceImageLeft = sourceRect.left + (sourceRect.width - sourceImageWidth) / 2;
const sourceImageTop = sourceRect.top + (sourceRect.height - sourceImageHeight) / 2;
return {
x: sourceImageLeft - neutralLeft * scale,
y: sourceImageTop - neutralTop * scale,
x: sourceImageLeft - imageRenderingRect.left * scale,
y: sourceImageTop - imageRenderingRect.top * scale,
scale,
};
}