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-blend-mode: hard-light;
.motto {
// Initial for animation
filter: blur(10px);
opacity: 0;
width: 50vw;
margin-right: 10vw;
.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 { useLayoutEffect, useRef } from "react"
import gsap from "gsap";
import { useEffect, useRef, useState } from "react";
export default function Home() {
let timeline = gsap.timeline()
const motto = useRef(null)
function click() {
let timeline = gsap.timeline();
var updateTime = 10 * 1000;
const motto = useRef(null);
const [hitokoto, setHitokoto] = useState("");
const [fromWho, setFromWho] = useState("");
const [from, setFrom] = useState("");
let hitokoto_indicator = ""
async function updateMotto() {
console.log("refresh")
let ctx = gsap.context(async () => {
var data = await new Promise<{
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"
})
// Change contents here
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"
ease: "out",
})
} else {
console.log("not updated")
}
useLayoutEffect(() => {
let ctx = gsap.context(() => {
timeline.from(motto.current, {
opacity: 0,
filter: "blur(10px)",
duration: 0.2,
ease: "out"
})
ctx.revert()
}
useEffect(() => {
let ctx = gsap.context(() => {
loop(updateMotto, updateTime);
})
return () => ctx.revert()
}, [])
return () => ctx.revert();
}, []);
return (
<main className={`${style.main} ${style.dark}`}>
<div className={style.motto} ref={motto}>
<div className={style.content}></div>
<div className={style.author}></div>
<div className={style.content}>{hitokoto}</div>
<div className={style.author}>
{fromWho}{from}
</div>
</div>
</main>
)
);
}
function loop(task: () => void, time: number) {
task();
function f() {
setTimeout(() => {
task();
f();
}, time);
}
f();
}