TootList: add hero animation

This commit is contained in:
thislight 2024-11-17 17:37:58 +08:00
parent 1641f3e75b
commit 6879eb5292
No known key found for this signature in database
GPG key ID: FCFE5192241CCD4E

View file

@ -13,7 +13,6 @@ import { useDefaultSession } from "../masto/clients";
import { useHeroSource } from "../platform/anim"; import { useHeroSource } from "../platform/anim";
import { HERO as BOTTOM_SHEET_HERO } from "../material/BottomSheet"; import { HERO as BOTTOM_SHEET_HERO } from "../material/BottomSheet";
import { setCache as setTootBottomSheetCache } from "./TootBottomSheet"; import { setCache as setTootBottomSheetCache } from "./TootBottomSheet";
import { useNavigate } from "@solidjs/router";
import RegularToot, { import RegularToot, {
findElementActionable, findElementActionable,
findRootToot, findRootToot,
@ -21,6 +20,21 @@ import RegularToot, {
import cardStyle from "../material/cards.module.css"; import cardStyle from "../material/cards.module.css";
import type { ThreadNode } from "../masto/timelines"; import type { ThreadNode } from "../masto/timelines";
import { useNavigator } from "../platform/StackedRouter"; import { useNavigator } from "../platform/StackedRouter";
import { ANIM_CURVE_STD } from "../material/theme";
function durationOf(rect0: DOMRect, rect1: DOMRect) {
const distancelt = Math.sqrt(
Math.pow(Math.abs(rect0.top - rect1.top), 2) +
Math.pow(Math.abs(rect0.left - rect1.left), 2),
);
const distancerb = Math.sqrt(
Math.pow(Math.abs(rect0.bottom - rect1.bottom), 2) +
Math.pow(Math.abs(rect0.right - rect1.right), 2),
);
const distance = distancelt + distancerb;
const duration = distance / 1.6;
return duration;
}
function positionTootInThread(index: number, threadLength: number) { function positionTootInThread(index: number, threadLength: number) {
if (index === 0) { if (index === 0) {
@ -100,7 +114,7 @@ const TootList: Component<{
const openFullScreenToot = ( const openFullScreenToot = (
toot: mastodon.v1.Status, toot: mastodon.v1.Status,
srcElement?: HTMLElement, srcElement: HTMLElement,
reply?: boolean, reply?: boolean,
) => { ) => {
const p = session()?.account; const p = session()?.account;
@ -116,12 +130,55 @@ const TootList: Component<{
const acct = `${inf.username}@${p.site}`; const acct = `${inf.username}@${p.site}`;
setTootBottomSheetCache(acct, toot); setTootBottomSheetCache(acct, toot);
push(`/${encodeURIComponent(acct)}/toot/${toot.id}`, { push(`/${encodeURIComponent(acct)}/toot/${toot.id}`, {
state: reply animateOpen(element) {
? { const rect0 = srcElement.getBoundingClientRect(); // the start rect
tootReply: true, const rect1 = element.getBoundingClientRect(); // the end rect
}
: undefined, const duration = durationOf(rect0, rect1);
const keyframes = {
top: [`${rect0.top}px`, `${rect1.top}px`],
bottom: [`${rect0.bottom}px`, `${rect1.bottom}px`],
left: [`${rect0.left}px`, `${rect1.left}px`],
right: [`${rect0.right}px`, `${rect1.right}px`],
height: [`${rect0.height}px`, `${rect1.height}px`],
margin: 0,
};
srcElement.style.visibility = "hidden";
const animation = element.animate(keyframes, {
duration,
easing: ANIM_CURVE_STD,
});
return animation;
},
animateClose(element) {
const rect0 = element.getBoundingClientRect(); // the start rect
const rect1 = srcElement.getBoundingClientRect(); // the end rect
const duration = durationOf(rect0, rect1);
const keyframes = {
top: [`${rect0.top}px`, `${rect1.top}px`],
bottom: [`${rect0.bottom}px`, `${rect1.bottom}px`],
left: [`${rect0.left}px`, `${rect1.left}px`],
right: [`${rect0.right}px`, `${rect1.right}px`],
height: [`${rect0.height}px`, `${rect1.height}px`],
margin: 0,
};
srcElement.style.visibility = "";
const animation = element.animate(keyframes, {
duration,
easing: ANIM_CURVE_STD,
});
return animation;
},
}); });
}; };