-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
281 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title>three.js webgl - dodecahedron buttons</title> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> | ||
<link rel="preconnect" href="https://fonts.googleapis.com"> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||
<link href="https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet"> | ||
<link rel="stylesheet" href="styles.css"> | ||
</head> | ||
<body> | ||
<!-- Título centrado superior --> | ||
<div id="titleContainer"> | ||
<img src="img/Jei_Dsgn.png" alt="Jei_Dsgn Logo" id="pageTitle"> | ||
</div> | ||
<div id="container"></div> | ||
|
||
<!-- Ícono en la parte inferior derecha solo visible en móviles --> | ||
<img id="mobileIcon" src="img/360.png" alt="360 Icon"> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"three": "https://unpkg.com/[email protected]/build/three.module.js", | ||
"three/addons/": "https://unpkg.com/[email protected]/examples/jsm/" | ||
} | ||
} | ||
</script> | ||
<script src="script.js"></script> | ||
</body> | ||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
import * as THREE from 'three'; | ||
import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js'; | ||
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; | ||
|
||
let camera, scene, renderer, controls; | ||
let dodecahedronGroup; | ||
let raycaster, mouse; | ||
const cursorDefault = 'img/360_cursor.png'; | ||
const cursorPointer = 'img/clic.png'; | ||
|
||
init(); | ||
animate(); | ||
|
||
function generateDarkerColor() { | ||
let r, g, b; | ||
|
||
do { | ||
r = Math.floor(Math.random() * 256); | ||
g = Math.floor(Math.random() * 256); | ||
b = Math.floor(Math.random() * 256); | ||
} while (r + g + b > 400); | ||
|
||
return `rgba(${r},${g},${b},0.9)`; | ||
} | ||
|
||
function createCircularButton(name, url) { | ||
const div = document.createElement('div'); | ||
div.className = 'button'; | ||
div.innerText = name; | ||
div.style.backgroundColor = generateDarkerColor(); | ||
div.setAttribute('data-url', url); | ||
|
||
div.addEventListener('pointerdown', (event) => { | ||
event.stopPropagation(); | ||
event.preventDefault(); | ||
window.open(url, '_blank'); | ||
}); | ||
|
||
const object = new CSS3DObject(div); | ||
object.scale.set(-1, 1, 1); | ||
object.position.set(0, 0, 0); | ||
|
||
return object; | ||
} | ||
|
||
function createDodecahedron() { | ||
const group = new THREE.Group(); | ||
const radius = 70; | ||
|
||
const buttonData = [ | ||
{ name: 'About Me', url: 'https://linktr.ee/jeidsgn' }, | ||
{ name: 'Textil Design', url: 'https://jeidsgn.tumblr.com/tagged/textil' }, | ||
{ name: 'Illustration', url: 'https://jeidsgn.tumblr.com/tagged/Ilustraciondigitaln' }, | ||
{ name: 'UX/UI', url: 'https://jeidsgn.tumblr.com/tagged/interface' }, | ||
{ name: 'Concept Art', url: 'https://linktr.ee/jeidsgn' }, | ||
{ name: 'Animation', url: 'https://www.instagram.com/' }, | ||
{ name: 'Branding', url: 'https://jeidsgn.tumblr.com/tagged/corporativo' }, | ||
{ name: 'Editorial Design', url: 'https://jeidsgn.tumblr.com/tagged/editorial' }, | ||
{ name: 'Programming', url: 'https://github.com/Jeidsgn' }, | ||
{ name: 'Math', url: 'https://www.youtube.com/@JeiDsgn' }, | ||
{ name: 'Digital Adaptation', url: 'https://linktr.ee/jeidsgn' }, | ||
{ name: 'Visual Content Pack', url: 'https://jeidsgn.github.io/Boost-Visual-Content-Pack/' } | ||
]; | ||
|
||
const pentagonCenters = [ | ||
new THREE.Vector3(0, -1.618, 1).multiplyScalar(radius), | ||
new THREE.Vector3(0, 1.618, 1).multiplyScalar(radius), | ||
new THREE.Vector3(0, 1.618, -1).multiplyScalar(radius), | ||
new THREE.Vector3(0, -1.618, -1).multiplyScalar(radius), | ||
new THREE.Vector3(1, 0, 1.618).multiplyScalar(radius), | ||
new THREE.Vector3(-1, 0, 1.618).multiplyScalar(radius), | ||
new THREE.Vector3(-1, 0, -1.618).multiplyScalar(radius), | ||
new THREE.Vector3(1, 0, -1.618).multiplyScalar(radius), | ||
new THREE.Vector3(1.618, 1, 0).multiplyScalar(radius), | ||
new THREE.Vector3(-1.618, 1, 0).multiplyScalar(radius), | ||
new THREE.Vector3(1.618, -1, 0).multiplyScalar(radius), | ||
new THREE.Vector3(-1.618, -1, 0).multiplyScalar(radius) | ||
]; | ||
|
||
pentagonCenters.forEach((center, index) => { | ||
const geometry = new THREE.CircleGeometry(1, 32); | ||
geometry.rotateX(Math.PI / 2); | ||
|
||
const material = new THREE.MeshBasicMaterial({ visible: false }); | ||
const faceMesh = new THREE.Mesh(geometry, material); | ||
|
||
faceMesh.position.copy(center); | ||
|
||
const button = createCircularButton(buttonData[index].name, buttonData[index].url); | ||
button.position.copy(center); | ||
button.lookAt(new THREE.Vector3(0, 0, 0)); | ||
|
||
group.add(button); | ||
}); | ||
|
||
return group; | ||
} | ||
|
||
function init() { | ||
const container = document.getElementById('container'); | ||
|
||
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | ||
scene = new THREE.Scene(); | ||
|
||
renderer = new CSS3DRenderer(); | ||
renderer.setSize(window.innerWidth, window.innerHeight); | ||
container.appendChild(renderer.domElement); | ||
|
||
dodecahedronGroup = createDodecahedron(); | ||
scene.add(dodecahedronGroup); | ||
|
||
controls = new OrbitControls(camera, renderer.domElement); | ||
controls.enableZoom = false; | ||
controls.enablePan = false; | ||
controls.maxPolarAngle = Math.PI * 1; | ||
controls.minPolarAngle = Math.PI * -0.5; | ||
|
||
// Configuración de Raycaster | ||
raycaster = new THREE.Raycaster(); | ||
mouse = new THREE.Vector2(); | ||
|
||
// Eventos de mouse | ||
window.addEventListener('mousemove', onMouseMove, false); | ||
|
||
// Ajustar la posición de la cámara | ||
updateCameraPosition(); | ||
|
||
window.addEventListener('resize', () => { | ||
onWindowResize(); | ||
updateCameraPosition(); // Actualizar la posición de la cámara en el redimensionamiento | ||
}); | ||
} | ||
|
||
function onMouseMove(event) { | ||
// Calcula las coordenadas del mouse en el rango de -1 a +1 para cada eje | ||
mouse.x = (event.clientX / window.innerWidth) * 2 - 1; | ||
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; | ||
|
||
// Actualiza el raycaster con la posición del mouse | ||
raycaster.setFromCamera(mouse, camera); | ||
|
||
// Calcula los objetos intersectados | ||
const intersects = raycaster.intersectObjects(dodecahedronGroup.children); | ||
|
||
if (intersects.length > 0) { | ||
// Si el cursor está sobre un objeto 3D, cambia el cursor | ||
document.body.style.cursor = `url('${cursorPointer}'), auto`; | ||
} else { | ||
// Si el cursor no está sobre un objeto 3D, usa el cursor por defecto | ||
document.body.style.cursor = `url('${cursorDefault}'), auto`; | ||
} | ||
} | ||
|
||
function onWindowResize() { | ||
camera.aspect = window.innerWidth / window.innerHeight; | ||
camera.updateProjectionMatrix(); | ||
renderer.setSize(window.innerWidth, window.innerHeight); | ||
} | ||
|
||
function updateCameraPosition() { | ||
// Ajusta la posición de la cámara en función del tamaño de la pantalla | ||
if (window.innerWidth <= 768) { // Asumir que 768px o menos es móvil | ||
camera.position.z = 500; | ||
} else { | ||
camera.position.z = 300; | ||
} | ||
} | ||
|
||
function animate() { | ||
requestAnimationFrame(animate); | ||
|
||
dodecahedronGroup.rotation.y += 0.005; | ||
|
||
renderer.render(scene, camera); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
body { | ||
margin: 0; | ||
overflow: hidden; | ||
background-color: #000000; | ||
cursor: url('img/360_cursor.png'), auto; /* Cursor por defecto */ | ||
} | ||
/* Título superior centrado */ | ||
#titleContainer { | ||
position: absolute; | ||
top: 20px; | ||
left: 50%; | ||
transform: translateX(-50%); | ||
z-index: 2; | ||
pointer-events: none; /* Evitar que interfiera con las interacciones de la página */ | ||
text-align: center; | ||
} | ||
|
||
#pageTitle { | ||
width: 150px; /* Ajusta el tamaño según sea necesario */ | ||
height: auto; | ||
} | ||
|
||
#container { | ||
position: relative; | ||
z-index: 1; | ||
pointer-events: auto; | ||
} | ||
|
||
.button { | ||
width: 150px; | ||
height: 150px; | ||
font-family: "Raleway", sans-serif; | ||
font-size: 18px; | ||
color: #ffffff; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
text-align: center; | ||
border: none; | ||
cursor: pointer; | ||
border-radius: 50%; | ||
background-color: #4682B4; | ||
position: absolute; | ||
pointer-events: auto; | ||
} | ||
|
||
.button:hover { | ||
cursor: url('img/clic.png'), auto; /* Cursor al pasar sobre el botón */ | ||
} | ||
|
||
/* Ícono en la parte inferior derecha */ | ||
#mobileIcon { | ||
display: none; | ||
position: fixed; | ||
bottom: 50px; | ||
left: 50%; | ||
transform: translateX(-50%); | ||
width: 75px; | ||
height: 75px; | ||
cursor: pointer; | ||
} | ||
|
||
/* Mostrar el ícono solo en dispositivos móviles */ | ||
@media only screen and (max-width: 768px) { | ||
#mobileIcon { | ||
display: block; | ||
} | ||
#titleContainer { | ||
top: 80px; | ||
} | ||
#pageTitle { | ||
width: 200px; /* Ajustar el tamaño para dispositivos móviles si es necesario */ | ||
} | ||
} |