1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-07-25 10:54:56 +02:00
This commit is contained in:
syuilo
2026-07-10 13:46:45 +09:00
parent b48321154f
commit b47303f6d6
2 changed files with 56 additions and 11 deletions

View File

@@ -48,6 +48,7 @@ import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { makeDoubleTapDetector } from '@/utility/double-tap.js';
import { beginAnimation, easing_easeInOutQuad } from '@/utility/animation.js';
import { calculateSourceTransform } from '@/components/MkImageGallery.utils.js';
export type Image = {
id: string;
@@ -399,17 +400,18 @@ onBeforeUnmount(() => {
// 元のimg要素の位置・サイズ(とobject-fitの設定値)を取得して、そこからneutralの位置にアニメーションするためのscaleとtranslationを計算する
function getScaleAndTranslationForSourceElement(): { x: number; y: number; scale: number } {
const elementStyles = window.getComputedStyle(props.image.sourceElement);
const fit = elementStyles.objectFit;
const sourceElement = props.image.sourceElement;
if (sourceElement == null) return { x: 0, y: 0, scale: 1 };
const sourceRect = props.image.sourceElement.getBoundingClientRect();
if (fit === 'contain') {
// TODO
} else if (fit === 'cover') {
// TODO
} else {
// TODO
}
return calculateSourceTransform({
fit: window.getComputedStyle(sourceElement).objectFit,
neutralSize,
sourceRect: sourceElement.getBoundingClientRect(),
viewportSize: {
width: window.innerWidth,
height: window.innerHeight,
},
});
}
onMounted(async () => {
@@ -458,6 +460,6 @@ onMounted(async () => {
}
.transition {
transition: translate 200ms ease, width 200ms ease, height 200ms ease;
transition: translate 200ms ease, scale 200ms ease;
}
</style>

View File

@@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
type Size = {
width: number;
height: number;
};
type Rect = Size & {
left: number;
top: number;
};
export function calculateSourceTransform({
fit,
neutralSize,
sourceRect,
viewportSize,
}: {
fit: string;
neutralSize: Size;
sourceRect: Rect;
viewportSize: Size;
}): { x: number; y: number; scale: number } {
const scale = fit === 'cover'
? Math.max(sourceRect.width / neutralSize.width, sourceRect.height / neutralSize.height)
: Math.min(sourceRect.width / neutralSize.width, sourceRect.height / neutralSize.height);
const neutralLeft = (viewportSize.width - neutralSize.width) / 2;
const neutralTop = (viewportSize.height - neutralSize.height) / 2;
const sourceImageWidth = neutralSize.width * scale;
const sourceImageHeight = neutralSize.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,
scale,
};
}