From 43dd81842e91ffe8cb41a2b66f5070fa93bd8873 Mon Sep 17 00:00:00 2001 From: fufu-girl-meow Date: Sun, 22 Jun 2025 23:47:15 +0700 Subject: [PATCH] Ditching animation.jsx, and replace with WebM. Concept is already on Porchese --- public/yml/DialogPorsche.yml | 48 ++-- src/main.jsx | 2 - src/pages/components/animation.jsx | 210 ------------------ .../components/testAnimation_manyfiles.jsx | 46 ---- .../components/testAnimation_onefile.jsx | 81 ------- src/pages/conversationPage.jsx | 6 +- src/pages/introductionPage.jsx | 1 - src/pages/optionPage.jsx | 7 +- 8 files changed, 31 insertions(+), 370 deletions(-) delete mode 100644 src/pages/components/animation.jsx delete mode 100644 src/pages/components/testAnimation_manyfiles.jsx delete mode 100644 src/pages/components/testAnimation_onefile.jsx diff --git a/public/yml/DialogPorsche.yml b/public/yml/DialogPorsche.yml index 55ab37d..69b73eb 100644 --- a/public/yml/DialogPorsche.yml +++ b/public/yml/DialogPorsche.yml @@ -8,7 +8,7 @@ type: conversation name: Porsche text: ”Hi! I haven’t seen you around before so you must be new. I’m Porsche. Why don’t you sit with me and my friends? We'll tell you about the school!” - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 3 @@ -18,7 +18,7 @@ option: - text: Sure! goTo: 4 - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" - id: 4 @@ -43,7 +43,7 @@ type: conversation name: Porsche text: “Seems like people have been losing their stuff a lot lately. I can’t think of who would do it though, since we all know each other.” - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 8 @@ -55,14 +55,14 @@ goTo: 9 - text: "I don’t know either, I’m not familiar with anyone." goTo: 10 - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" - id: 9 type: conversation name: Porsche text: “No! I don’t think so! But people might think it’s you because you’re new. It’s unfair but it’s just how it is sometimes.” - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 11 @@ -70,7 +70,7 @@ type: conversation name: Porsche text: “Yeah I know. It’s ok. People will calm down. You don’t have to worry!” - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 11 @@ -106,7 +106,7 @@ type: conversation name: Porsche text: “Hey, why are people saying that the thief might be me? How could it even be me? Did someone tell everyone it was me?” - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 17 @@ -114,7 +114,7 @@ type: conversation name: Porsche text: "What? I don’t know, people started talking, but I did say it can’t be you. But it is strange that it happens around you." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 18 @@ -126,14 +126,14 @@ goTo: 19 - text: "But... I haven’t done anything." goTo: 20 - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" - id: 19 type: conversation name: Porsche text: "Ha? Are you trying to say that I might be the one who spread the rumor? How could you! Even though I was the one who befriended and defended you." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 22 @@ -141,7 +141,7 @@ type: conversation name: Porsche text: "Calm down! If you are innocent, which I think you are, people will figure it out and calm down as well!" - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 21 @@ -149,7 +149,7 @@ type: conversation name: Porsche text: "I have to go, see you later!" - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 22 @@ -157,7 +157,7 @@ type: conversation name: Porsche text: "I’ll try asking a classmate about this." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 23 @@ -165,7 +165,7 @@ type: conversation name: Porsche text: "Hey sorry to bother but can you tell me what Porsche has been telling everyone these days?" - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 24 @@ -173,7 +173,7 @@ type: conversation name: Porsche text: "Uhhh I’m not sure but they keep saying stuff like how things keep disappearing right after you transferred here. But they did say it probably isn’t you though." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 25 @@ -197,7 +197,7 @@ type: conversation name: Porsche text: "Ok, things keep disappearing and everyone has been saying it’s you, and this time it’s my pencil case! Maybe you should just admit it already?" - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 29 @@ -211,7 +211,7 @@ type: conversation name: Porsche text: "I understand everyone’s concern right now, but I really did not take anything from anyone." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 31 @@ -219,7 +219,7 @@ type: conversation name: Porsche text: "I don’t know why and how the rumor started, but I think it’s because I’m new here." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 32 @@ -227,7 +227,7 @@ type: conversation name: Porsche text: "It’s hurtful to think that some of you would believe that I would steal..." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 33 @@ -253,7 +253,7 @@ type: conversation name: Porsche text: "After conferring with your classmates, you decided to speak with Porsche alone about the origin of the rumor." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 37 @@ -261,7 +261,7 @@ type: conversation name: Porsche text: "The evidence pointed to them as the one who started it, yet they continue to deny it." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 38 @@ -269,7 +269,7 @@ type: conversation name: Porsche text: "As much as you want Porsche to just admit it, you take a deep breath and choose to..." - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" goTo: 39 @@ -281,7 +281,7 @@ goTo: 40 - text: "Distance yourself from Porsche." goTo: 43 - sprite: "_Porsche_normal.zip" + sprite: "F_Porsche_normal.webm" background: "bg-hallway.png" - id: 40 @@ -318,4 +318,4 @@ type: story text: "But for now, you are determined to set clear boundaries to protect yourself, so situations like this don't happen again." background: "bg-hallway.png" - goTo: end \ No newline at end of file + goTo: end diff --git a/src/main.jsx b/src/main.jsx index 64a918f..9a8dd44 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -6,7 +6,6 @@ import './css/global.css'; import HomePage from './pages/homePage.jsx'; import WarningPage from './pages/warningPage.jsx'; import NamePage from './pages/namePage.jsx'; -import Animation from './pages/components/animation.jsx'; import IntroductionPage from './pages/introductionPage.jsx'; import PlayVideo from './pages/components/playVideo.jsx' import VitualNovelHandler from './pages/vistualNovelHandler.jsx'; @@ -19,7 +18,6 @@ createRoot(document.getElementById('root')).render( } /> } /> } /> - } /> } /> } /> } /> diff --git a/src/pages/components/animation.jsx b/src/pages/components/animation.jsx deleted file mode 100644 index 6e06d56..0000000 --- a/src/pages/components/animation.jsx +++ /dev/null @@ -1,210 +0,0 @@ -import React, { useEffect, useState, useRef } from 'react'; -import JSZip from 'jszip'; - -const Animation = ({ src = "M_Porsche_cross_arm.zip", h = '100%', w = '100%' }) => { - const [images, setImages] = useState([]); - const [loading, setLoading] = useState(true); - const frameRate = 1000 / 24; // 24 FPS - const canvasRef = useRef(null); - const animationRef = useRef(null); - const currentFrameRef = useRef(0); - const imageElementsRef = useRef([]); - const urlSource = `${import.meta.env.VITE_ASSETS_URL}/${src}`; - - useEffect(() => { - const loadImages = async () => { - const zip = new JSZip(); - try { - const response = await fetch(urlSource); - 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; - }); - }) - ); - } - }); - - const imgElements = await Promise.all(imgPromises); - if (imgElements.length === 0) { - console.error('No images found in the ZIP file.'); - } - - imageElementsRef.current = imgElements; - setImages(imgElements); - } catch (error) { - console.error('Error loading images:', error); - } finally { - setLoading(false); - } - }; - - loadImages(); - }, [urlSource]); - - useEffect(() => { - if (images.length > 0) { - const canvas = canvasRef.current; - const gl = canvas.getContext('webgl'); - if (!gl) { - console.error("WebGL is not supported."); - return; - } - - const rect = canvas.getBoundingClientRect(); - const dpr = window.devicePixelRatio || 1; - canvas.width = rect.width * dpr; - canvas.height = rect.height * dpr; - gl.viewport(0, 0, canvas.width, canvas.height); - - canvas.style.width = `${rect.width}px`; - canvas.style.height = `${rect.height}px`; - - gl.clearColor(0.0, 0.0, 0.0, 0.0); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.enable(gl.BLEND); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); - - 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('Shader compile error:', 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('Program link error:', gl.getProgramInfoLog(shaderProgram)); - } - gl.useProgram(shaderProgram); - - const positionBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); - const vertices = new Float32Array([ - -1.0, -1.0, - 1.0, -1.0, - -1.0, 1.0, - 1.0, 1.0, - ]); - 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); - - const texCoordBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer); - const texCoords = new Float32Array([ - 0.0, 1.0, - 1.0, 1.0, - 0.0, 0.0, - 1.0, 0.0, - ]); - 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 texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); - 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); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - // Optionally use NEAREST for sharper image: - // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - - const uTextureLocation = gl.getUniformLocation(shaderProgram, "u_texture"); - - 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]); - - 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 () => { - if (animationRef.current) { - cancelAnimationFrame(animationRef.current); - } - }; - } - }, [images]); - - if (loading) { - return
Loading...
; - } else { - return ( - - ); - } -}; - -export default Animation; diff --git a/src/pages/components/testAnimation_manyfiles.jsx b/src/pages/components/testAnimation_manyfiles.jsx deleted file mode 100644 index cb86fbb..0000000 --- a/src/pages/components/testAnimation_manyfiles.jsx +++ /dev/null @@ -1,46 +0,0 @@ -import React, { useEffect, useRef, useState } from 'react'; -import anime from 'animejs'; - -const startNumber = 1000; -const endNumber = 1239; -const imageCount = endNumber - startNumber + 1; -const images = []; - -for (let i = startNumber; i <= endNumber; i++) { - const formattedNumber = String(i).padStart(5, '0'); - images.push(import(`../../assets/characters/F_porche_akimbo_AME/Porsche${formattedNumber}.png`)); -} - -const CharacterAnimation = () => { - const totalFrames = imageCount; - const frameDuration = 20; - const [currentFrame, setCurrentFrame] = useState(0); - const [loadedImages, setLoadedImages] = useState([]); - const characterRef = useRef(null); - - useEffect(() => { - Promise.all(images).then((resolvedImages) => { - setLoadedImages(resolvedImages.map(image => image.default)); - }); - }, []); - - useEffect(() => { - const interval = setInterval(() => { - setCurrentFrame((prevFrame) => (prevFrame + 1) % totalFrames); - }, frameDuration); - - return () => clearInterval(interval); - }, []); - - return ( - Character Animation - ); -}; - - -export default CharacterAnimation; diff --git a/src/pages/components/testAnimation_onefile.jsx b/src/pages/components/testAnimation_onefile.jsx deleted file mode 100644 index 9dca1db..0000000 --- a/src/pages/components/testAnimation_onefile.jsx +++ /dev/null @@ -1,81 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import JSZip from 'jszip'; - -const TestAnimation = () => { - const [images, setImages] = useState([]); - const [currentFrame, setCurrentFrame] = useState(0); - const [loading, setLoading] = useState(true); - const frameRate = 60; - - useEffect(() => { - const loadImages = async () => { - const zip = new JSZip(); - try { - const response = await fetch('src/assets/mainCharacters/M_Porsche_cross_arm.zip'); - 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 => { - return `data:image/webp;base64,${base64}`; - }) - ); - } - }); - - const imgUrls = await Promise.all(imgPromises); - - // console.log('Loaded images:', imgUrls); - - if (imgUrls.length === 0) { - console.error('No images found in the ZIP file.'); - } - - setImages(imgUrls); - } catch (error) { - console.error('Error loading images:', error); - } finally { - setLoading(false); - } - }; - - loadImages(); - - }, []); - - useEffect(() => { - if (images.length > 0) { - const interval = setInterval(() => { - setCurrentFrame((prevFrame) => (prevFrame + 1) % images.length); - }, frameRate); - - return () => clearInterval(interval); - } - }, [images]); - - if (loading) { - return
Loading...
; - } else { - return ( -
- {images.length > 0 ? ( - {`Animation - ) : ( -
No images to display.
- )} -
- ); - } -}; - -export default TestAnimation; diff --git a/src/pages/conversationPage.jsx b/src/pages/conversationPage.jsx index 47a014d..a1988e5 100644 --- a/src/pages/conversationPage.jsx +++ b/src/pages/conversationPage.jsx @@ -4,19 +4,17 @@ import '../css/global.css'; import '../css/textBox.css'; import '../css/nameBox.css'; import '../css/conversation.css' -import { useNavigate, useParams } from 'react-router-dom'; -import Animation from './components/animation.jsx'; function ConversationPage({data , onClicked}) { const backgroundSRC = `${import.meta.env.VITE_ASSETS_URL}/${data.background}` const [name] = useState(() => { return sessionStorage.getItem("name") || ''; }); - const { char } = useParams(); const DialogText = data.text.replace("{name}", name); const DialogName = data.name.replace("{name}", name); - const videoPath = `https://dl.techtransthai.org/fsob-assets/F_${char}_normal.webm`; + const videoPath = `${import.meta.env.VITE_ASSETS_URL}/${data.sprite}`; // data.sprite return webm file name + // https://dl.techtransthai.org/fsob-assets/F_Porsche_normal.webm //console.log(data.sprite); diff --git a/src/pages/introductionPage.jsx b/src/pages/introductionPage.jsx index 9047a0e..9b093f1 100644 --- a/src/pages/introductionPage.jsx +++ b/src/pages/introductionPage.jsx @@ -2,7 +2,6 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import '../css/global.css'; import BlackButton from './components/customButton'; -import Animation from './components/animation.jsx'; import PlayVideo from './components/playVideo.jsx'; import LoadingScene from './components/loadingScene.jsx'; import IntroductionData from './components/introductionData.jsx'; diff --git a/src/pages/optionPage.jsx b/src/pages/optionPage.jsx index 042a349..2d10d91 100644 --- a/src/pages/optionPage.jsx +++ b/src/pages/optionPage.jsx @@ -4,10 +4,10 @@ import '../css/global.css'; import '../css/textBox.css'; import '../css/nameBox.css'; import '../css/option.css' -import Animation from './components/animation.jsx'; function OptionPage({data , onClicked}) { const backgroundSRC = `${import.meta.env.VITE_ASSETS_URL}/${data.background}` + const videoPath = `${import.meta.env.VITE_ASSETS_URL}/${data.sprite}`; // data.sprite return webm file name return (
- +
{