diff --git a/src/material/Menu.tsx b/src/material/Menu.tsx index 04b8d86..9e23f62 100644 --- a/src/material/Menu.tsx +++ b/src/material/Menu.tsx @@ -8,10 +8,6 @@ import { } from "solid-js"; import { ANIM_CURVE_STD } from "./theme"; import "./Menu.css"; -import { - animateGrowFromTopRight, - animateShrinkToTopRight, -} from "../platform/anim"; type Props = { open?: boolean; @@ -55,7 +51,23 @@ const Menu: ParentComponent = (props) => { top, }); - animateGrowFromTopRight(root, { easing: ANIM_CURVE_STD }); + const overflow = root.style.overflow; + root.style.overflow = "hidden"; + const duration = (rend.height / 1600) * 1000; + const easing = ANIM_CURVE_STD; + const animation = root.animate( + { + height: [`${rend.height / 2}px`, `${rend.height}px`], + }, + { + duration, + easing, + }, + ); + animation.addEventListener( + "finish", + () => (root.style.overflow = overflow), + ); } else { openAnimationOrigin = "lt"; setAnchorPos({ left, top }); @@ -107,10 +119,19 @@ const Menu: ParentComponent = (props) => { root.close(); }); } else { - const animation = animateShrinkToTopRight(root, { - easing: ANIM_CURVE_STD, - }); + const overflow = root.style.overflow; + root.style.overflow = "hidden"; + const animation = root.animate( + { + height: [`${rend.height}px`, `${rend.height / 2}px`], + }, + { + duration: (rend.height / 2 / 1600) * 1000, + easing: ANIM_CURVE_STD, + }, + ); animation.addEventListener("finish", () => { + root.style.overflow = overflow; root.close(); }); } diff --git a/src/material/theme.css b/src/material/theme.css index 09cc746..e7cb4d9 100644 --- a/src/material/theme.css +++ b/src/material/theme.css @@ -117,7 +117,6 @@ --tutu-shadow-e24: 0px 24px 48px 0px var(--tutu-color-shadow-l2); - /* curves are also hard-coded in theme.ts */ --tutu-anim-curve-std: cubic-bezier(0.4, 0, 0.2, 1); --tutu-anim-curve-deceleration: cubic-bezier(0, 0, 0.2, 1); --tutu-anim-curve-aceleration: cubic-bezier(0.4, 0, 1, 1); diff --git a/src/platform/anim.ts b/src/platform/anim.ts index 3dd0ead..87549d0 100644 --- a/src/platform/anim.ts +++ b/src/platform/anim.ts @@ -53,145 +53,3 @@ export function useHeroSignal( return [() => undefined, () => undefined]; } } - -export function animateRollOutFromTop( - root: HTMLElement, - options?: Omit, -) { - const overflow = root.style.overflow; - root.style.overflow = "hidden"; - - const { height } = root.getBoundingClientRect(); - - const opts = Object.assign( - { - duration: Math.floor((height / 1600) * 1000), - }, - options, - ); - - const animation = root.animate( - { - height: ["0px", `${height}px`], - }, - opts, - ); - - const restore = () => (root.style.overflow = overflow); - - animation.addEventListener("finish", restore); - animation.addEventListener("cancel", restore); - - return animation; -} - - -export function animateRollInFromBottom( - root: HTMLElement, - options?: Omit, -) { - const overflow = root.style.overflow; - root.style.overflow = "hidden"; - - const { height } = root.getBoundingClientRect(); - - const opts = Object.assign( - { - duration: Math.floor((height / 1600) * 1000), - }, - options, - ); - - const animation = root.animate( - { - height: [`${height}px`, "0px"], - }, - opts, - ); - - const restore = () => (root.style.overflow = overflow); - - animation.addEventListener("finish", restore); - animation.addEventListener("cancel", restore); - - return animation; -} - -export function animateGrowFromTopRight( - root: HTMLElement, - options?: KeyframeAnimationOptions, -) { - const transformOrigin = root.style.transformOrigin; - root.style.transformOrigin = "top right"; - - const { width, height } = root.getBoundingClientRect(); - - const durationX = Math.floor((height / 1600) * 1000); - const durationY = Math.floor((width / 1600) * 1000); - - // finds the offset for the center frame, - // it will stops at the (minDuration / maxDuration)% - const minDuration = Math.min(durationX, durationY); - const maxDuration = Math.max(durationX, durationY); - - const centerOffset = minDuration / maxDuration; - - const keyframes = [ - { transform: "scaleX(0)", opacity: 0, height: "0px", offset: 0 }, - { - transform: `scaleX(${minDuration === durationX ? "1" : centerOffset})`, - height: `${(minDuration === durationY ? 1 : centerOffset) * height}px`, - offset: centerOffset, - opacity: 1, - }, - { transform: "scaleX(1)", height: `${height}px`, offset: 1 }, - ]; - - const animation = root.animate( - keyframes, - { ...options, duration: maxDuration }, - ); - - const restore = () => { - root.style.transformOrigin = transformOrigin; - }; - - animation.addEventListener("cancel", restore); - animation.addEventListener("finish", restore); - - return animation; -} - -export function animateShrinkToTopRight( - root: HTMLElement, - options?: KeyframeAnimationOptions, -) { - const overflow = root.style.overflow; - root.style.overflow = "hidden"; - const transformOrigin = root.style.transformOrigin; - root.style.transformOrigin = "top right"; - - const { width, height } = root.getBoundingClientRect(); - - const duration = Math.floor( - Math.max((width / 1600) * 1000, (height / 1600) * 1000), - ); - - const animation = root.animate( - { - transform: ["scale(1)", "scale(0.5)"], - opacity: [1, 0], - }, - { ...options, duration }, - ); - - const restore = () => { - root.style.overflow = overflow; - root.style.transformOrigin = transformOrigin; - }; - - animation.addEventListener("cancel", restore); - animation.addEventListener("finish", restore); - - return animation; -} diff --git a/src/timelines/TootList.tsx b/src/timelines/TootList.tsx index 6145b75..7c712b6 100644 --- a/src/timelines/TootList.tsx +++ b/src/timelines/TootList.tsx @@ -106,9 +106,9 @@ const TootList: Component<{ const target = actionableElement as HTMLAnchorElement; - const acct = encodeURIComponent( - target.dataset.client || `@${new URL(target.href).origin}`, - ); + const acct = + encodeURIComponent(target.dataset.client || + `@${new URL(target.href).origin}`); navigate(`/${acct}/profile/${target.dataset.acctId}`); @@ -116,11 +116,6 @@ const TootList: Component<{ } else { console.warn("unknown action", actionableElement.dataset.rel); } - } else if ( - event.target.parentElement && - event.target.parentElement.tagName === "A" - ) { - return; } // else if (!actionableElement || !checkIsExpended(status) || )