diff --git a/src/App.tsx b/src/App.tsx
index 9ee57a4..fb9df72 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,9 +1,22 @@
+import { useEffect, useRef } from "react";
import Background from "./components/Background";
import "./main.css";
+import { init } from "./scripts/lang";
export function App() {
+ const canvasRef = useRef(null);
+
+ useEffect(() => {
+ init(canvasRef.current);
+ }, []);
+
return (
-
+ <>
+
+
+
+
+ >
);
}
diff --git a/src/components/Background.tsx b/src/components/Background.tsx
index f7938a0..954c137 100644
--- a/src/components/Background.tsx
+++ b/src/components/Background.tsx
@@ -9,9 +9,11 @@ export default function Background() {
}, []);
return (
- <>
-
-
- >
+
);
}
\ No newline at end of file
diff --git a/src/main.css b/src/main.css
index 71c6a8d..0576e88 100644
--- a/src/main.css
+++ b/src/main.css
@@ -83,7 +83,7 @@ body {
rotate: 90deg;
}
#language-div {
- position: absolute; padding: 10px; padding-right: 20px; z-index: 3;
+ position: absolute; padding: 10px; z-index: 3; right: 20px;
}
#language-renderer {
width: 100%; height: 100vh; display: block; margin: 0; padding: 0; cursor: grab;
@@ -94,6 +94,10 @@ body {
#projects {
position: absolute; top: 50vh; left: 20%; transform: translateX(-50%); z-index: 11; width: 900px; height: auto; display: grid; grid-template-columns: 50% 50%; left: 50%; width: 90%;
}
+#background {
+ position: fixed;
+ z-index: -10;
+}
#footer {
background: linear-gradient(to bottom left, rgb(41, 11, 41), rgb(44, 18, 44));
margin-bottom: 0px;
@@ -128,7 +132,9 @@ body {
background: linear-gradient(to bottom right, rgba(0, 0, 0, 0.5), rgba(107, 29, 107, 0.3));
background: -webkit-linear-gradient(to bottom right, rgba(0, 0, 0, 0.5), rgba(107, 29, 107, 0.3) 100%);
background: -moz-linear-gradient(to bottom right, rgba(0, 0, 0, 0.5), rgba(107, 29, 107, 0.3) 100%);
- position: fixed; width: 100%; height: 100%;
+ position: fixed;
+ width: 100%; height: 100%;
+ top: 0px;
z-index: 1000000;
}
.devider {
@@ -287,6 +293,8 @@ a.icon:hover {
width: fit-content; height: fit-content; animation: float 5s ease-in-out infinite;
}
.gradient-overlay img {
+ position: absolute;
+ z-index: 100000000;
width: 7vh; height: 7vh; transform-origin: 50% 50%; animation: float-rotate 6s ease-in-out infinite;
filter: blur(0.5svh);
transition-duration: 0.5s;
@@ -294,6 +302,7 @@ a.icon:hover {
.gradient-overlay img:hover {
filter: none;
scale: 1.4;
+ cursor: pointer;
}
.rotate-away {
transform-origin: 50% 0px 50vh;
diff --git a/src/scripts/background.js b/src/scripts/background.js
index 28d9371..6fd2744 100644
--- a/src/scripts/background.js
+++ b/src/scripts/background.js
@@ -11,7 +11,7 @@ export async function init(canvas) {
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(0, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({antialias: false, canvas: canvas});
- renderer.setSize(window.innerWidth/2, window.innerHeight);
+ renderer.setSize(window.innerWidth, window.innerHeight);
const composer = new EffectComposer( renderer );
const uniforms = {
diff --git a/src/scripts/lang.js b/src/scripts/lang.js
index ee2e0d5..773e1cd 100644
--- a/src/scripts/lang.js
+++ b/src/scripts/lang.js
@@ -4,192 +4,192 @@ import engPath from '../images/english.png'
import nldPath from '../images/dutch.jpg'
import rusPath from '../images/russian.jpg'
-let language = "en";
+export async function init(canvas) {
+ let language = "en";
-function determineLanguage(){
- const userLang = localStorage.getItem("preferredLanguage") || navigator.language || navigator.userLanguage;
- switch (userLang) {
- case "ru": {
- language = "ru";
- cube.rotation.y = 1.5707963267948966;
- break;
- }
- case "nl": {
- language = "nl";
- cube.rotation.y = 4.71238898038469;
- }
- }
- if (language != "en") setLanguage(language);
-}
-
-var elements = document.querySelectorAll('[ts]');
-
-function setLanguage(l) {
- language = l;
- const arr = translations[language];
- elements.forEach(function(element) {
- var key = element.getAttribute('ts');
-
- if (arr.hasOwnProperty(key)) {
- element.innerHTML = arr[key];
- }
- });
-}
-
-
-const fov = 75;
-const aspect = 1;
-const near = 0.1;
-const far = 5;
-
-const canvas = document.querySelector('#language-renderer');
-const renderer = new THREE.WebGLRenderer({antialias: false, canvas});
-renderer.setSize( 90,90 );
-renderer.setClearColor( 0xffffff, 0);
-const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
-camera.position.z = 1.4;
-
-const scene = new THREE.Scene();
-
-const discardMaterial = new THREE.ShaderMaterial({
- vertexShader:`
- void main() {
- gl_Position = vec4(1.0);
- }`,
- fragmentShader: `
- void main() {
- gl_FragColor = vec4(1.0);
- discard;
- }
- `
-});
-
-var geometry = new THREE.BoxGeometry(1, 1, 1);
-var texture = new THREE.TextureLoader();
-var materials = [];
-const dutch = texture.load(nldPath);
-dutch.magFilter = THREE.NearestFilter;
-dutch.minFilter = THREE.NearestFilter;
-const english = texture.load(engPath);
-english.magFilter = THREE.NearestFilter;
-english.minFilter = THREE.NearestFilter;
-const russian = texture.load(rusPath);
-russian.magFilter = THREE.NearestFilter;
-russian.minFilter = THREE.NearestFilter;
-materials.push(new THREE.MeshPhongMaterial({map: dutch}));
-materials.push(new THREE.MeshPhongMaterial({map: russian}));
-materials.push(discardMaterial);
-materials.push(discardMaterial);
-materials.push(new THREE.MeshPhongMaterial({map: english}));
-materials.push(new THREE.MeshPhongMaterial({map: english}));
-
-var cube = new THREE.Mesh(geometry, materials);
-
-determineLanguage();
-
-scene.add(cube);
-
-
-const ambientLight = new THREE.AmbientLight(0xffffff, 2.8);
-scene.add(ambientLight);
-
-let isDragging = false;
-let previousX;
-let velocity = 0;
-const friction = 0.4;
-// Define the possible rotation positions
-const snapPositions = [0, Math.PI / 2, Math.PI, Math.PI * 3 / 2];
-
-// Store the current snapped position
-let currentSnapPosition = 0;
-
-function startDrag(event) {
- isDragging = true;
- previousX = event.clientX || event.touches[0].clientX;
- canvas.style.cursor = "grabbing";
-}
-
-function drag(event) {
- if (isDragging) {
- const currentX = event.clientX || event.touches[0].clientX;
- velocity += (currentX - previousX) * 0.05;
- previousX = currentX;
- }
-}
-
-function endDrag() {
- isDragging = false;
- canvas.style.cursor = "grab";
- snapCube();
-}
-
-function snapCube() {
- // Normalize the cube's rotation to be within the range [0, 2 * PI)
- let rotation = cube.rotation.y % (2 * Math.PI);
- if (rotation < -Math.PI/4) {
- rotation += 2 * Math.PI;
- } else if (rotation > 5.49778718038469) {
- rotation -= 2 * Math.PI;
- }
-
- // Calculate the closest snap position
- const closestSnapPosition = snapPositions.reduce((prev, curr) => {
- return Math.abs(curr - rotation) < Math.abs(prev - rotation) ? curr : prev;
- }, snapPositions[0]);
-
- // Interpolate to the closest snap position
- const snapTime = 0.5; // seconds
- const snapStart = rotation;
- const snapEnd = closestSnapPosition;
- const snapStartTime = performance.now();
-
- function snapRender(time) {
- const t = (time - snapStartTime) / (snapTime * 1000);
- cube.rotation.y = snapStart + (snapEnd - snapStart) * t;
- if (t < 1) {
- requestAnimationFrame(snapRender);
- } else {
- cube.rotation.y = snapEnd;
- currentSnapPosition = snapEnd;
- let lang;
- switch (snapEnd){
- case 1.5707963267948966:
- lang = "ru";
- break;
- case 0:
- lang = "en";
- break;
- case 3.141592653589793:
- lang = "en";
- break;
- case 4.71238898038469:
- lang = "nl";
- break;
+ function determineLanguage(){
+ const userLang = localStorage.getItem("preferredLanguage") || navigator.language || navigator.userLanguage;
+ switch (userLang) {
+ case "ru": {
+ language = "ru";
+ cube.rotation.y = 1.5707963267948966;
+ break;
}
- if (lang != language) {
- setLanguage(lang);
- localStorage.setItem("preferredLanguage",language);
+ case "nl": {
+ language = "nl";
+ cube.rotation.y = 4.71238898038469;
}
}
+ if (language != "en") setLanguage(language);
}
- requestAnimationFrame(snapRender);
-}
-canvas.addEventListener('mousedown', startDrag);
-canvas.addEventListener('touchstart', startDrag);
-canvas.addEventListener('mousemove', drag);
-canvas.addEventListener('touchmove', drag);
-canvas.addEventListener("mouseleave", endDrag);
-canvas.addEventListener('mouseup', endDrag);
-canvas.addEventListener('touchend', endDrag);
+ var elements = document.querySelectorAll('[ts]');
-//cube.rotation.x = 0.5;
-function render(time) {
- renderer.render(scene, camera);
+ function setLanguage(l) {
+ language = l;
+ const arr = translations[language];
+ elements.forEach(function(element) {
+ var key = element.getAttribute('ts');
+
+ if (arr.hasOwnProperty(key)) {
+ element.innerHTML = arr[key];
+ }
+ });
+ }
- velocity *= friction;
- cube.rotation.y += velocity;
+ const fov = 75;
+ const aspect = 1;
+ const near = 0.1;
+ const far = 5;
+
+ const renderer = new THREE.WebGLRenderer({antialias: false, canvas});
+ renderer.setSize( 90,90 );
+ renderer.setClearColor( 0xffffff, 0);
+ const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
+ camera.position.z = 1.4;
+
+ const scene = new THREE.Scene();
+
+ const discardMaterial = new THREE.ShaderMaterial({
+ vertexShader:`
+ void main() {
+ gl_Position = vec4(1.0);
+ }`,
+ fragmentShader: `
+ void main() {
+ gl_FragColor = vec4(1.0);
+ discard;
+ }
+ `
+ });
+
+ var geometry = new THREE.BoxGeometry(1, 1, 1);
+ var texture = new THREE.TextureLoader();
+ var materials = [];
+ const dutch = texture.load(nldPath);
+ dutch.magFilter = THREE.NearestFilter;
+ dutch.minFilter = THREE.NearestFilter;
+ const english = texture.load(engPath);
+ english.magFilter = THREE.NearestFilter;
+ english.minFilter = THREE.NearestFilter;
+ const russian = texture.load(rusPath);
+ russian.magFilter = THREE.NearestFilter;
+ russian.minFilter = THREE.NearestFilter;
+ materials.push(new THREE.MeshPhongMaterial({map: dutch}));
+ materials.push(new THREE.MeshPhongMaterial({map: russian}));
+ materials.push(discardMaterial);
+ materials.push(discardMaterial);
+ materials.push(new THREE.MeshPhongMaterial({map: english}));
+ materials.push(new THREE.MeshPhongMaterial({map: english}));
+
+ var cube = new THREE.Mesh(geometry, materials);
+
+ determineLanguage();
+
+ scene.add(cube);
+
+
+ const ambientLight = new THREE.AmbientLight(0xffffff, 2.8);
+ scene.add(ambientLight);
+
+ let isDragging = false;
+ let previousX;
+ let velocity = 0;
+ const friction = 0.4;
+ // Define the possible rotation positions
+ const snapPositions = [0, Math.PI / 2, Math.PI, Math.PI * 3 / 2];
+
+ // Store the current snapped position
+ let currentSnapPosition = 0;
+
+ function startDrag(event) {
+ isDragging = true;
+ previousX = event.clientX || event.touches[0].clientX;
+ canvas.style.cursor = "grabbing";
+ }
+
+ function drag(event) {
+ if (isDragging) {
+ const currentX = event.clientX || event.touches[0].clientX;
+ velocity += (currentX - previousX) * 0.05;
+ previousX = currentX;
+ }
+ }
+
+ function endDrag() {
+ isDragging = false;
+ canvas.style.cursor = "grab";
+ snapCube();
+ }
+
+ function snapCube() {
+ // Normalize the cube's rotation to be within the range [0, 2 * PI)
+ let rotation = cube.rotation.y % (2 * Math.PI);
+ if (rotation < -Math.PI/4) {
+ rotation += 2 * Math.PI;
+ } else if (rotation > 5.49778718038469) {
+ rotation -= 2 * Math.PI;
+ }
+
+ // Calculate the closest snap position
+ const closestSnapPosition = snapPositions.reduce((prev, curr) => {
+ return Math.abs(curr - rotation) < Math.abs(prev - rotation) ? curr : prev;
+ }, snapPositions[0]);
+
+ // Interpolate to the closest snap position
+ const snapTime = 0.5; // seconds
+ const snapStart = rotation;
+ const snapEnd = closestSnapPosition;
+ const snapStartTime = performance.now();
+
+ function snapRender(time) {
+ const t = (time - snapStartTime) / (snapTime * 1000);
+ cube.rotation.y = snapStart + (snapEnd - snapStart) * t;
+ if (t < 1) {
+ requestAnimationFrame(snapRender);
+ } else {
+ cube.rotation.y = snapEnd;
+ currentSnapPosition = snapEnd;
+ let lang;
+ switch (snapEnd){
+ case 1.5707963267948966:
+ lang = "ru";
+ break;
+ case 0:
+ lang = "en";
+ break;
+ case 3.141592653589793:
+ lang = "en";
+ break;
+ case 4.71238898038469:
+ lang = "nl";
+ break;
+ }
+ if (lang != language) {
+ setLanguage(lang);
+ localStorage.setItem("preferredLanguage",language);
+ }
+ }
+ }
+ requestAnimationFrame(snapRender);
+ }
+
+ canvas.addEventListener('mousedown', startDrag);
+ canvas.addEventListener('touchstart', startDrag);
+ canvas.addEventListener('mousemove', drag);
+ canvas.addEventListener('touchmove', drag);
+ canvas.addEventListener("mouseleave", endDrag);
+ canvas.addEventListener('mouseup', endDrag);
+ canvas.addEventListener('touchend', endDrag);
+
+ function render(time) {
+ renderer.render(scene, camera);
+
+ velocity *= friction;
+ cube.rotation.y += velocity;
+
+ requestAnimationFrame(render);
+ }
requestAnimationFrame(render);
-}
-requestAnimationFrame(render);
+}
\ No newline at end of file