Trying to add floating logos
This commit is contained in:
15
src/App.tsx
15
src/App.tsx
@@ -1,9 +1,22 @@
|
|||||||
|
import { useEffect, useRef } from "react";
|
||||||
import Background from "./components/Background";
|
import Background from "./components/Background";
|
||||||
import "./main.css";
|
import "./main.css";
|
||||||
|
import { init } from "./scripts/lang";
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
|
const canvasRef = useRef(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
init(canvasRef.current);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Background />
|
<>
|
||||||
|
<div id="language-div">
|
||||||
|
<canvas ref={canvasRef} id="language-renderer"></canvas>
|
||||||
|
</div>
|
||||||
|
<Background />
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ export default function Background() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div id="background">
|
||||||
<div className="gradient-overlay"></div>
|
<div className="gradient-overlay">
|
||||||
<canvas ref={canvasRef} />
|
<div style={{marginTop: "10%", marginLeft: "85%", animationDelay: "-1s"}}><img src={require("../images/android.svg")} /></div>
|
||||||
</>
|
</div>
|
||||||
|
<canvas ref={canvasRef} id="background-renderer" />
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
13
src/main.css
13
src/main.css
@@ -83,7 +83,7 @@ body {
|
|||||||
rotate: 90deg;
|
rotate: 90deg;
|
||||||
}
|
}
|
||||||
#language-div {
|
#language-div {
|
||||||
position: absolute; padding: 10px; padding-right: 20px; z-index: 3;
|
position: absolute; padding: 10px; z-index: 3; right: 20px;
|
||||||
}
|
}
|
||||||
#language-renderer {
|
#language-renderer {
|
||||||
width: 100%; height: 100vh; display: block; margin: 0; padding: 0; cursor: grab;
|
width: 100%; height: 100vh; display: block; margin: 0; padding: 0; cursor: grab;
|
||||||
@@ -94,6 +94,10 @@ body {
|
|||||||
#projects {
|
#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%;
|
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 {
|
#footer {
|
||||||
background: linear-gradient(to bottom left, rgb(41, 11, 41), rgb(44, 18, 44));
|
background: linear-gradient(to bottom left, rgb(41, 11, 41), rgb(44, 18, 44));
|
||||||
margin-bottom: 0px;
|
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: 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: -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%);
|
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;
|
z-index: 1000000;
|
||||||
}
|
}
|
||||||
.devider {
|
.devider {
|
||||||
@@ -287,6 +293,8 @@ a.icon:hover {
|
|||||||
width: fit-content; height: fit-content; animation: float 5s ease-in-out infinite;
|
width: fit-content; height: fit-content; animation: float 5s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
.gradient-overlay img {
|
.gradient-overlay img {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 100000000;
|
||||||
width: 7vh; height: 7vh; transform-origin: 50% 50%; animation: float-rotate 6s ease-in-out infinite;
|
width: 7vh; height: 7vh; transform-origin: 50% 50%; animation: float-rotate 6s ease-in-out infinite;
|
||||||
filter: blur(0.5svh);
|
filter: blur(0.5svh);
|
||||||
transition-duration: 0.5s;
|
transition-duration: 0.5s;
|
||||||
@@ -294,6 +302,7 @@ a.icon:hover {
|
|||||||
.gradient-overlay img:hover {
|
.gradient-overlay img:hover {
|
||||||
filter: none;
|
filter: none;
|
||||||
scale: 1.4;
|
scale: 1.4;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.rotate-away {
|
.rotate-away {
|
||||||
transform-origin: 50% 0px 50vh;
|
transform-origin: 50% 0px 50vh;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export async function init(canvas) {
|
|||||||
const scene = new THREE.Scene();
|
const scene = new THREE.Scene();
|
||||||
const camera = new THREE.PerspectiveCamera(0, window.innerWidth / window.innerHeight, 0.1, 1000);
|
const camera = new THREE.PerspectiveCamera(0, window.innerWidth / window.innerHeight, 0.1, 1000);
|
||||||
const renderer = new THREE.WebGLRenderer({antialias: false, canvas: canvas});
|
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 composer = new EffectComposer( renderer );
|
||||||
|
|
||||||
const uniforms = {
|
const uniforms = {
|
||||||
|
|||||||
@@ -4,192 +4,192 @@ import engPath from '../images/english.png'
|
|||||||
import nldPath from '../images/dutch.jpg'
|
import nldPath from '../images/dutch.jpg'
|
||||||
import rusPath from '../images/russian.jpg'
|
import rusPath from '../images/russian.jpg'
|
||||||
|
|
||||||
let language = "en";
|
export async function init(canvas) {
|
||||||
|
let language = "en";
|
||||||
|
|
||||||
function determineLanguage(){
|
function determineLanguage(){
|
||||||
const userLang = localStorage.getItem("preferredLanguage") || navigator.language || navigator.userLanguage;
|
const userLang = localStorage.getItem("preferredLanguage") || navigator.language || navigator.userLanguage;
|
||||||
switch (userLang) {
|
switch (userLang) {
|
||||||
case "ru": {
|
case "ru": {
|
||||||
language = "ru";
|
language = "ru";
|
||||||
cube.rotation.y = 1.5707963267948966;
|
cube.rotation.y = 1.5707963267948966;
|
||||||
break;
|
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;
|
|
||||||
}
|
}
|
||||||
if (lang != language) {
|
case "nl": {
|
||||||
setLanguage(lang);
|
language = "nl";
|
||||||
localStorage.setItem("preferredLanguage",language);
|
cube.rotation.y = 4.71238898038469;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (language != "en") setLanguage(language);
|
||||||
}
|
}
|
||||||
requestAnimationFrame(snapRender);
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.addEventListener('mousedown', startDrag);
|
var elements = document.querySelectorAll('[ts]');
|
||||||
canvas.addEventListener('touchstart', startDrag);
|
|
||||||
canvas.addEventListener('mousemove', drag);
|
|
||||||
canvas.addEventListener('touchmove', drag);
|
|
||||||
canvas.addEventListener("mouseleave", endDrag);
|
|
||||||
canvas.addEventListener('mouseup', endDrag);
|
|
||||||
canvas.addEventListener('touchend', endDrag);
|
|
||||||
|
|
||||||
//cube.rotation.x = 0.5;
|
function setLanguage(l) {
|
||||||
function render(time) {
|
language = l;
|
||||||
renderer.render(scene, camera);
|
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);
|
||||||
}
|
}
|
||||||
requestAnimationFrame(render);
|
|
||||||
Reference in New Issue
Block a user