preform animation only content has changed

This commit is contained in:
Astrian Zheng 2023-10-13 14:06:51 +11:00
parent 08e387f959
commit c647b92a29
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA
2 changed files with 90 additions and 32 deletions

View File

@ -7,6 +7,10 @@
background-image: url("/noise.png"); background-image: url("/noise.png");
background-blend-mode: hard-light; background-blend-mode: hard-light;
.motto { .motto {
// Initial for animation
filter: blur(10px);
opacity: 0;
width: 50vw; width: 50vw;
margin-right: 10vw; margin-right: 10vw;
.content { .content {

View File

@ -1,47 +1,101 @@
"use client" "use client";
import style from "./page.module.scss" import "./global.scss";
import "./global.scss" import style from "./page.module.scss";
import gsap from 'gsap' import gsap from "gsap";
import { useLayoutEffect, useRef } from "react" import { useEffect, useRef, useState } from "react";
export default function Home() { export default function Home() {
let timeline = gsap.timeline() let timeline = gsap.timeline();
const motto = useRef(null)
function click() { var updateTime = 10 * 1000;
timeline.to(motto.current, { const motto = useRef(null);
opacity: 0, const [hitokoto, setHitokoto] = useState("");
filter: "blur(10px)", const [fromWho, setFromWho] = useState("");
duration: 0.2, const [from, setFrom] = useState("");
ease: "in"
}) let hitokoto_indicator = ""
// Change contents here
timeline.to(motto.current, { async function updateMotto() {
opacity: 1, console.log("refresh")
filter: "blur(0px)", let ctx = gsap.context(async () => {
duration: 0.2, var data = await new Promise<{
ease: "out" hitokoto: string;
from_who: string;
from: string;
}>(async (res, rej) => {
try {
const response = await fetch("https://v1.hitokoto.cn");
if (response.ok) {
res(await response.json());
return;
} else {
rej(await response.json());
return;
}
} catch (error) {
rej(String(error));
return;
}
});
if (data.hitokoto !== hitokoto_indicator) {
hitokoto_indicator = data.hitokoto
timeline.to(motto.current, {
opacity: 0,
filter: "blur(10px)",
duration: 0.2,
ease: "in",
});
setHitokoto(data.hitokoto);
setFromWho(data.from_who);
setFrom(data.from);
timeline.to(motto.current, {
opacity: 1,
filter: "blur(0px)",
duration: 0.2,
ease: "out",
})
} else {
console.log("not updated")
}
}) })
ctx.revert()
} }
useLayoutEffect(() => {
useEffect(() => {
let ctx = gsap.context(() => { let ctx = gsap.context(() => {
timeline.from(motto.current, { loop(updateMotto, updateTime);
opacity: 0,
filter: "blur(10px)",
duration: 0.2,
ease: "out"
})
}) })
return () => ctx.revert()
}, []) return () => ctx.revert();
}, []);
return ( return (
<main className={`${style.main} ${style.dark}`}> <main className={`${style.main} ${style.dark}`}>
<div className={style.motto} ref={motto}> <div className={style.motto} ref={motto}>
<div className={style.content}></div> <div className={style.content}>{hitokoto}</div>
<div className={style.author}></div> <div className={style.author}>
{fromWho}{from}
</div>
</div> </div>
</main> </main>
) );
}
function loop(task: () => void, time: number) {
task();
function f() {
setTimeout(() => {
task();
f();
}, time);
}
f();
} }