diff --git a/src/pages/components/.animation_copy.jsx b/src/pages/components/.animation_copy.jsx new file mode 100644 index 0000000..8ed670e --- /dev/null +++ b/src/pages/components/.animation_copy.jsx @@ -0,0 +1,195 @@ +import React, { useEffect, useRef } from 'react'; +import JSZip from 'jszip'; + +const Animation = ({ src, animationWidth }) => { + const canvasRef = useRef(null); + const imageElementsRef = useRef([]); + const animationRef = useRef(null); + const currentFrameRef = useRef(0); + const loadingRef = useRef(true); + const frameRate = 1000 / 24; + + useEffect(() => { + const loadImages = async () => { + const zip = new JSZip(); + try { + const response = await fetch(src); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + const data = await response.arrayBuffer(); + const zipContent = await zip.loadAsync(data); + + const imgPromises = []; + zipContent.forEach((relativePath, file) => { + if (file.name.endsWith('.webp')) { + imgPromises.push( + file.async('base64').then(base64 => { + const img = new Image(); + img.src = `data:image/webp;base64,${base64}`; + return new Promise((resolve, reject) => { + img.onload = () => resolve(img); + img.onerror = reject; + }); + }) + ); + } + }); + + imageElementsRef.current = await Promise.all(imgPromises); + + if (imageElementsRef.current.length === 0) { + console.error('No images found in the ZIP file.'); + } + + loadingRef.current = false; // Set loading to false after images are loaded + } catch (error) { + console.error('Error loading images:', error); + } + }; + + loadImages(); + }, [src]); + + useEffect(() => { + if (loadingRef.current || imageElementsRef.current.length === 0) return; + + const canvas = canvasRef.current; + const gl = canvas.getContext('webgl'); + if (!gl) { + console.error("WebGL is not supported."); + return; + } + + // Set up WebGL context (basic) + gl.clearColor(0.0, 0.0, 0.0, 0.0); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.viewport(0, 0, canvas.width, canvas.height); + + // Enable blending + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + // gl.blendFunc(gl.SRC_COLOR, gl.DST_COLOR); + + // Shader program + const vertexShaderSource = ` + attribute vec2 a_position; + attribute vec2 a_texCoord; + varying vec2 v_texCoord; + void main() { + gl_Position = vec4(a_position, 0.0, 1.0); + v_texCoord = a_texCoord; + } + `; + const fragmentShaderSource = ` + precision mediump float; + uniform sampler2D u_texture; + varying vec2 v_texCoord; + void main() { + gl_FragColor = texture2D(u_texture, v_texCoord); + } + `; + + const createShader = (source, type) => { + const shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + console.error('ERROR compiling shader', gl.getShaderInfoLog(shader)); + } + return shader; + }; + + const vertexShader = createShader(vertexShaderSource, gl.VERTEX_SHADER); + const fragmentShader = createShader(fragmentShaderSource, gl.FRAGMENT_SHADER); + + const shaderProgram = gl.createProgram(); + gl.attachShader(shaderProgram, vertexShader); + gl.attachShader(shaderProgram, fragmentShader); + gl.linkProgram(shaderProgram); + if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { + console.error('ERROR linking program', gl.getProgramInfoLog(shaderProgram)); + } + gl.useProgram(shaderProgram); + + // Create buffer and set up attributes + const positionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + const vertices = new Float32Array([ + -1.0, -1.0, // Bottom-left + 1.0, -1.0, // Bottom-right + -1.0, 1.0, // Top-left + 1.0, 1.0 // Top-right + ]); + gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); + + const positionLocation = gl.getAttribLocation(shaderProgram, "a_position"); + gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(positionLocation); + + // Create texture and load image + const texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + + const loadTexture = (image) => { + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); + + gl.generateMipmap(gl.TEXTURE_2D); + }; + + loadTexture(imageElementsRef.current[0]); // Initially load the first image + + // Texture coordinates + const texCoordBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer); + const texCoords = new Float32Array([ + 0.0, 1.0, // Bottom-left (now corresponds to top-left of the image) + 1.0, 1.0, // Bottom-right (now corresponds to top-right of the image) + 0.0, 0.0, // Top-left (now corresponds to bottom-left of the image) + 1.0, 0.0 // Top-right (now corresponds to bottom-right of the image) + ]); + gl.bufferData(gl.ARRAY_BUFFER, texCoords, gl.STATIC_DRAW); + + const texCoordLocation = gl.getAttribLocation(shaderProgram, "a_texCoord"); + gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(texCoordLocation); + + const uTextureLocation = gl.getUniformLocation(shaderProgram, "u_texture"); + + let lastFrameTime = 0; + const animate = (timestamp) => { + if (lastFrameTime === 0) lastFrameTime = timestamp; + const elapsed = timestamp - lastFrameTime; + + if (elapsed > frameRate) { + currentFrameRef.current = (currentFrameRef.current + 1) % images.length; + loadTexture(imageElementsRef.current[currentFrameRef.current]); + lastFrameTime = timestamp; + } + gl.clear(gl.COLOR_BUFFER_BIT); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + + animationRef.current = requestAnimationFrame(animate); + }; + + animationRef.current = requestAnimationFrame(animate); + return () => cancelAnimationFrame(animationRef.current); + }, [imageElementsRef.current]); + + if (loadingRef.current) { + return