Skip to content

Commit 2f7509c

Browse files
committed
Adding loading effect.
1 parent 34badda commit 2f7509c

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

astro/src/components/LoadingImage.tsx

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { useEffect, useRef, useState } from "react";
2+
3+
export function LoadingImage({
4+
src,
5+
slices = 8,
6+
delay = 60,
7+
}: {
8+
src: string;
9+
slices?: number;
10+
delay?: number;
11+
}) {
12+
const [imageLoaded, setImageLoaded] = useState(false);
13+
const [loadProgress, setLoadProgress] = useState(0);
14+
const canvasRef = useRef<HTMLCanvasElement>(null);
15+
const imageRef = useRef<HTMLImageElement>(null);
16+
17+
const drawPartialImage = (progress: number) => {
18+
const canvas = canvasRef.current;
19+
const image = imageRef.current;
20+
if (!canvas || !image) return;
21+
22+
const ctx = canvas.getContext("2d");
23+
if (!ctx) return;
24+
25+
// Clear canvas
26+
ctx.clearRect(0, 0, canvas.width, canvas.height);
27+
28+
// Calculate how much of the image to show based on progress
29+
const sliceHeight = image.height / slices;
30+
const height = Math.floor(sliceHeight * (progress / 100));
31+
32+
for (let i = 0; i < slices; i++) {
33+
const y = i * sliceHeight;
34+
ctx.drawImage(
35+
image,
36+
0, y, image.width, height, // Source rectangle
37+
0, y, canvas.width, height // Destination rectangle
38+
);
39+
}
40+
};
41+
42+
useEffect(() => {
43+
const img = new Image();
44+
img.onload = () => {
45+
if (canvasRef.current) {
46+
canvasRef.current.width = img.width;
47+
canvasRef.current.height = img.height;
48+
imageRef.current = img;
49+
setImageLoaded(true);
50+
51+
// Simulate slow loading
52+
let progress = 0;
53+
const interval = setInterval(() => {
54+
progress += 2;
55+
setLoadProgress(progress);
56+
drawPartialImage(progress);
57+
58+
if (progress >= 100) {
59+
clearInterval(interval);
60+
}
61+
}, delay); // Adjust speed by changing interval time
62+
}
63+
};
64+
img.src = src;
65+
}, [src]);
66+
67+
return (
68+
<canvas
69+
ref={canvasRef}
70+
style={{
71+
display: "block",
72+
maxWidth: "100%",
73+
height: "auto",
74+
}}
75+
/>
76+
);
77+
}

0 commit comments

Comments
 (0)