Update the 404 Page #1
@ -10,11 +10,9 @@
|
|||||||
@keyframes click-bounce {
|
@keyframes click-bounce {
|
||||||
0%, 100% {
|
0%, 100% {
|
||||||
transform: translate(0px, 0px) scale(1, 1);
|
transform: translate(0px, 0px) scale(1, 1);
|
||||||
/* animation-timing-function: linear(0.2, 0.8, 1); */
|
|
||||||
}
|
}
|
||||||
20% {
|
15% {
|
||||||
transform: translate(0px, 14px) scale(1.2, 0.9);
|
transform: translate(0px, 14px) scale(1.2, 0.9);
|
||||||
/* animation-timing-function: cubic-bezier(0.8, 0, 1, 1); */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,8 +19,10 @@ export default function NotFound() {
|
|||||||
</div>
|
</div>
|
||||||
</noscript>
|
</noscript>
|
||||||
<WobblingImage
|
<WobblingImage
|
||||||
img1="/images/coralz_0.png"
|
images={{
|
||||||
img2="/images/coralz_1.png"
|
idle: "/images/coralz_0.png",
|
||||||
|
poked: "/images/coralz_1.png"
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="-mt-2">
|
<div className="-mt-2">
|
||||||
<Link className="text-xs" target="_blank" href="https://x.com/JoelGuerraC/status/1840178999546319101">{">]"}Image source</Link>
|
<Link className="text-xs" target="_blank" href="https://x.com/JoelGuerraC/status/1840178999546319101">{">]"}Image source</Link>
|
||||||
|
|||||||
@ -5,14 +5,20 @@ import Image from "next/image";
|
|||||||
import { useCallback, useEffect, useRef, useState } from "react"
|
import { useCallback, useEffect, useRef, useState } from "react"
|
||||||
|
|
||||||
interface WobblingImageInterface {
|
interface WobblingImageInterface {
|
||||||
img1: string
|
images: {
|
||||||
img2?: string
|
idle: string;
|
||||||
|
poked?: string;
|
||||||
|
weird?: string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function WobblingImage ({
|
function WobblingImage ({
|
||||||
img1, img2
|
images
|
||||||
}: WobblingImageInterface) {
|
}: WobblingImageInterface) {
|
||||||
const size = 400;
|
const size = 400;
|
||||||
|
const [isPoked, setPoked] = useState(false);
|
||||||
|
const pokeTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
|
|
||||||
const [isAnimating, setIsAnimating] = useState(false);
|
const [isAnimating, setIsAnimating] = useState(false);
|
||||||
|
|
||||||
const audioPath = "/sound/poke.wav";
|
const audioPath = "/sound/poke.wav";
|
||||||
@ -82,11 +88,20 @@ function WobblingImage ({
|
|||||||
function handleClick() {
|
function handleClick() {
|
||||||
setIsAnimating(false);
|
setIsAnimating(false);
|
||||||
requestAnimationFrame(() => setIsAnimating(true));
|
requestAnimationFrame(() => setIsAnimating(true));
|
||||||
|
|
||||||
playRandomPitch();
|
playRandomPitch();
|
||||||
if (dummyAudio && !audioLoaded) {
|
if (dummyAudio && !audioLoaded) {
|
||||||
dummyAudio.currentTime = 0;
|
dummyAudio.currentTime = 0;
|
||||||
dummyAudio.play();
|
dummyAudio.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pokeTimeoutRef.current) {
|
||||||
|
clearTimeout(pokeTimeoutRef.current);
|
||||||
|
}
|
||||||
|
setPoked(true);
|
||||||
|
pokeTimeoutRef.current = setTimeout(() => {
|
||||||
|
setPoked(false);
|
||||||
|
}, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAnimationEnd() {
|
function handleAnimationEnd() {
|
||||||
@ -98,7 +113,7 @@ function WobblingImage ({
|
|||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"relative mx-auto cursor-grab h-[400px] select-none",
|
"relative mx-auto cursor-grab h-[400px] select-none",
|
||||||
isAnimating && "animate-[click-bounce_230ms_ease-out]"
|
isAnimating && "animate-[click-bounce_250ms_ease-out]"
|
||||||
)}
|
)}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
onAnimationEnd={handleAnimationEnd}
|
onAnimationEnd={handleAnimationEnd}
|
||||||
@ -109,17 +124,17 @@ function WobblingImage ({
|
|||||||
onPointerDown={(e) => e.preventDefault()}
|
onPointerDown={(e) => e.preventDefault()}
|
||||||
>
|
>
|
||||||
<Image
|
<Image
|
||||||
className={clsx("absolute left-1/2 -translate-x-1/2 top-0 pointer-events-none", isAnimating ? "opacity-0" : "opacity-100")}
|
className={clsx("absolute left-1/2 -translate-x-1/2 top-0 pointer-events-none", isPoked ? "opacity-0" : "opacity-100")}
|
||||||
alt="clip1"
|
alt="clip1"
|
||||||
src={img1}
|
src={images.idle}
|
||||||
width={size}
|
width={size}
|
||||||
height={size}
|
height={size}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
/>
|
/>
|
||||||
<Image
|
<Image
|
||||||
className={clsx("absolute left-1/2 -translate-x-1/2 top-0 pointer-events-none", isAnimating ? "opacity-100" : "opacity-0")}
|
className={clsx("absolute left-1/2 -translate-x-1/2 top-0 pointer-events-none", isPoked ? "opacity-100" : "opacity-0")}
|
||||||
alt="clip2"
|
alt="clip2"
|
||||||
src={img2 || img1}
|
src={images.poked || images.idle}
|
||||||
width={size}
|
width={size}
|
||||||
height={size}
|
height={size}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user