Skip to content

Commit

Permalink
feat(PageTracker): 添加动效
Browse files Browse the repository at this point in the history
  • Loading branch information
Yue-plus committed Sep 8, 2024
1 parent edc2009 commit 442b268
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 21 deletions.
81 changes: 62 additions & 19 deletions src/components/PageTracker.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,68 @@
import {useStore} from "@nanostores/react";
import {viewIndex} from "./store/rootLayoutStore.ts";
import arknightsConfig from "../../arknights.config";
import {type RefObject, useCallback, useEffect, useMemo, useRef, useState} from "react"
import {useStore} from "@nanostores/react"
import {viewIndex} from "./store/rootLayoutStore.ts"
import arknightsConfig from "../../arknights.config"

export default function PageTracker() {
const labels = arknightsConfig.pageTracker.labels
const $viewIndex = useStore(viewIndex)
const [showIndex, setShowIndex] = useState($viewIndex)
const [showLabel, setShowLabel] = useState(labels[$viewIndex])

// TODO: 添加动效
return <div className={"w-[10rem] portrait:w-[4rem] absolute top-[44.4444444444%] portrait:top-[auto]"
+ " right-[7.375rem] portrait:right-[2.875rem] portrait:bottom-[12.5rem]"
+ " translate-x-1/2 z-[6] whitespace-nowrap leading-[normal] select-none"}>
<div className={"font-n15eDemiBold"}></div>
<div className={"text-ark-blue text-[5.4rem] portrait:text-[3.6rem] portrait:text-center font-n15eDemiBold"
+ " leading-[.55] overflow-hidden"}
>{"0" + $viewIndex}</div>
<div className={"mt-[-1.55em] text-right text-[1.125rem] portrait:text-[1rem] portrait:text-center"
+ " font-benderRegular portrait:writing-rl portrait:absolute portrait:right-0 bottom-0"}
>{`// 0${$viewIndex} / 0${arknightsConfig.pageTracker.labels.length - 1}`}</div>
<div className={"text-right text-[.375rem] font-n15eMedium tracking-[.5em] portrait:hidden"}
>{arknightsConfig.pageTracker.microInfo}</div>
<div className={"text-right portrait:text-center text-[1.125rem] portrait:text-[.625rem] font-n15eDemiBold"
+ " tracking-widest portrait:absolute portrait:right-[1.5rem] portrait:bottom-0 portrait:writing-rl"}
>{arknightsConfig.pageTracker.labels[$viewIndex]}</div>
const nowIndexElement = useRef<HTMLDivElement>(null)
const nowIndexDuration = 240
const nowIndex = useMemo(() => showIndex.toString().padStart(2, "0"), [showIndex])

const tinyIndexElement = useRef<HTMLDivElement>(null)
const tinyIndexDuration = 260
const tinyIndex = useMemo(() => {
const maxIndex = labels.length - 1
return `// ${nowIndex} / ${maxIndex.toString().padStart(2, "0")}`
}, [nowIndex])

const microInfoElement = useRef<HTMLDivElement>(null)
const microInfoDuration = tinyIndexDuration

const labelElement = useRef<HTMLDivElement>(null)
const labelElementDuration = 280

const handleElementAnimation = useCallback((element: RefObject<HTMLDivElement>, timeout: number) => {
const translateY = $viewIndex > showIndex ? "-translate-y-8" : "translate-y-8"

element.current?.classList.add(translateY, "opacity-0")
setTimeout(() => element.current?.classList.replace(translateY, $viewIndex > showIndex ? "translate-y-8" : "-translate-y-8"), timeout)
setTimeout(() => element.current?.classList.remove("translate-y-8", "-translate-y-8", "opacity-0"), timeout * 2)
}, [$viewIndex, showIndex])

useEffect(() => {
handleElementAnimation(nowIndexElement, nowIndexDuration)
handleElementAnimation(tinyIndexElement, tinyIndexDuration)
handleElementAnimation(microInfoElement, microInfoDuration)
handleElementAnimation(labelElement, labelElementDuration)

setTimeout(() => {
setShowIndex($viewIndex)
setShowLabel(labels[$viewIndex])
}, Math.max(nowIndexDuration, tinyIndexDuration))
}, [$viewIndex])

return <div
className="w-[10rem] portrait:w-[4rem] absolute top-[44.4444444444%] portrait:top-[auto] right-[7.375rem] portrait:right-[2.875rem] portrait:bottom-[12.5rem] translate-x-1/2 z-[6] whitespace-nowrap leading-[normal] select-none">
<div ref={nowIndexElement} style={{transitionDuration: nowIndexDuration + "ms"}}
className="text-ark-blue text-[5.4rem] portrait:text-[3.6rem] portrait:text-center font-n15eDemiBold leading-[.55] overflow-hidden transition-[opacity,transform]">
{nowIndex}
</div>
<div ref={tinyIndexElement} style={{transitionDuration: tinyIndexDuration + "ms"}}
className="mt-[-1.55em] text-right text-[1.125rem] portrait:text-[1rem] portrait:text-center font-benderRegular portrait:writing-rl portrait:absolute portrait:right-0 bottom-0 transition-[opacity,transform]">
{tinyIndex}
</div>
<div ref={microInfoElement} style={{transitionDuration: microInfoDuration + "ms"}}
className="text-right text-[.375rem] font-n15eMedium tracking-[.5em] portrait:hidden transition-[opacity,transform]">
{arknightsConfig.pageTracker.microInfo}
</div>
<div ref={labelElement} style={{transitionDuration: labelElementDuration + "ms"}}
className="text-right portrait:text-center text-[1.125rem] portrait:text-[.625rem] font-n15eDemiBold tracking-widest portrait:absolute portrait:right-[1.5rem] portrait:bottom-0 portrait:writing-rl transition-[opacity,transform]">
{showLabel}
</div>
</div>
}
7 changes: 5 additions & 2 deletions src/pages/_views/RootPageViewTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ export default function RootPageViewTemplate({selfIndex, children}: { selfIndex:
if (selfIndex > $viewIndex) return setLeft("auto")
}, [selfIndex, $viewIndex])

return <div style={{width, left}} className={"w-0 h-full absolute top-0 right-0 bottom-0 left-0"
+ " overflow-hidden transition-[width] duration-1000"}>{children}</div>
return <div
className="w-0 h-full absolute top-0 right-0 bottom-0 left-0 overflow-hidden transition-[width] duration-1000"
style={{width, left}}>
{children}
</div>
}

0 comments on commit 442b268

Please sign in to comment.