diff --git a/package-lock.json b/package-lock.json
index 44d1213..7e054d6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,8 @@
"name": "fifty-shades-of-bully",
"version": "0.0.0",
"dependencies": {
+ "animejs": "^3.2.2",
+ "jszip": "^3.10.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.0.2"
@@ -1373,6 +1375,12 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/animejs": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/animejs/-/animejs-3.2.2.tgz",
+ "integrity": "sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ==",
+ "license": "MIT"
+ },
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -1711,6 +1719,12 @@
"node": ">=18"
}
},
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -2645,6 +2659,12 @@
"node": ">= 4"
}
},
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "license": "MIT"
+ },
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -2672,6 +2692,12 @@
"node": ">=0.8.19"
}
},
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
"node_modules/internal-slot": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
@@ -3155,6 +3181,18 @@
"node": ">=4.0"
}
},
+ "node_modules/jszip": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+ "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+ "license": "(MIT OR GPL-3.0-or-later)",
+ "dependencies": {
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "^1.0.5"
+ }
+ },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -3179,6 +3217,15 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -3431,6 +3478,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "license": "(MIT AND Zlib)"
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -3527,6 +3580,12 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "license": "MIT"
+ },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@@ -3631,6 +3690,27 @@
"react-dom": ">=18"
}
},
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "license": "MIT"
+ },
"node_modules/reflect.getprototypeof": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz",
@@ -3757,6 +3837,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
"node_modules/safe-regex-test": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
@@ -3834,6 +3920,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "license": "MIT"
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -3886,6 +3978,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
"node_modules/string.prototype.matchall": {
"version": "4.0.11",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz",
@@ -4168,6 +4269,12 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
"node_modules/vite": {
"version": "5.4.11",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz",
diff --git a/package.json b/package.json
index 5ba7baf..02f7212 100644
--- a/package.json
+++ b/package.json
@@ -4,12 +4,14 @@
"version": "0.0.0",
"type": "module",
"scripts": {
- "dev": "vite",
+ "dev": "vite --host",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
+ "animejs": "^3.2.2",
+ "jszip": "^3.10.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.0.2"
diff --git a/src/css/global.css b/src/css/global.css
index 580a519..07e828d 100644
--- a/src/css/global.css
+++ b/src/css/global.css
@@ -8,12 +8,13 @@
}
html * {
- background-color: rgb(var(--black));
+ /* background-color: rgb(var(--black)); */
color: rgb(var(--white));
}
body {
margin: 0;
+ background-color: rgb(var(--black));
}
.title {
diff --git a/src/css/spriteAnimation.css b/src/css/spriteAnimation.css
new file mode 100644
index 0000000..18645c7
--- /dev/null
+++ b/src/css/spriteAnimation.css
@@ -0,0 +1,21 @@
+.character {
+ width: 624px; /* Width of a single frame */
+ height: 814px; /* Height of a single frame */
+ background-color: wheat;
+ /* overflow: hidden; */
+ /* Ensure only one frame is visible */
+}
+
+.spriteAnimation {
+ width: 9984px;
+ animation: moveSprite 1s steps(16) infinite; /* 240 total frames */
+}
+
+@keyframes moveSprite {
+ form{
+ transform: translate3d(0,0,0)
+ }
+ to{
+ transform: translate3d(-100%,0,0);
+ }
+}
\ No newline at end of file
diff --git a/src/main.jsx b/src/main.jsx
index b7abab8..fa0fd25 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -6,6 +6,7 @@ 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/testAnimation_onefile.jsx';
createRoot(document.getElementById('root')).render(
+ );
+};
+
+export default CharacterAnimation;
diff --git a/src/pages/components/testAnimation_onefile.jsx b/src/pages/components/testAnimation_onefile.jsx
new file mode 100644
index 0000000..e460a7b
--- /dev/null
+++ b/src/pages/components/testAnimation_onefile.jsx
@@ -0,0 +1,77 @@
+import React, { useEffect, useState } from 'react';
+import JSZip from 'jszip';
+
+const Animation = () => {
+ const [images, setImages] = useState([]);
+ const [currentFrame, setCurrentFrame] = useState(0);
+ const [loading, setLoading] = useState(true);
+ const frameRate = 100; // Frame rate in milliseconds
+
+ useEffect(() => {
+ const loadImages = async () => {
+ const zip = new JSZip();
+ try {
+ const response = await fetch('src/assets/characters/sprite.zip'); // Adjust the path to your ZIP file
+ 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('blob')); // Convert file to Blob
+ }
+ });
+
+ const imgBlobs = await Promise.all(imgPromises);
+ const imgUrls = imgBlobs.map(blob => URL.createObjectURL(blob)); // Create object URLs
+
+ console.log('Loaded images:', imgUrls); // Log the loaded image URLs
+
+ setImages(imgUrls);
+ } catch (error) {
+ console.error('Error loading images:', error);
+ } finally {
+ setLoading(false); // Set loading to false after images are loaded
+ }
+ };
+
+ loadImages();
+
+ }, []);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setCurrentFrame((prevFrame) => (prevFrame + 1) % images.length);
+ }, frameRate);
+
+ return () => clearInterval(interval);
+ }, [images]);
+
+ useEffect(() => {
+ // Cleanup object URLs when the component unmounts
+ return () => {
+ images.forEach(url => URL.revokeObjectURL(url)); // Clean up object URLs
+ };
+ }, [images]);
+
+ if (loading) {
+ return