added transitions between locations
This commit is contained in:
+144
-66
@@ -2,102 +2,180 @@ import * as THREE from 'three';
|
||||
import { OrbitControls } from 'three-orbitcontrols-ts';
|
||||
import { gsap } from "gsap";
|
||||
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
let camera, scene, renderer, labelRenderer;
|
||||
let camera, scene, renderer, labelRenderer, currentTexture, currentMaterial;
|
||||
const ENTITY_NAME = 'sphere'
|
||||
|
||||
init();
|
||||
animate();
|
||||
|
||||
function init() {
|
||||
scene = new THREE.Scene();
|
||||
function createSphere(radius, widthS, heightS, texture, material, isVisible = false){
|
||||
const sphere = new THREE.SphereGeometry(radius, widthS, heightS)
|
||||
sphere.scale( - 1, 1, 1 );
|
||||
|
||||
texture.colorSpace = THREE.SRGBColorSpace;
|
||||
|
||||
material.transparent = true
|
||||
material.opacity = isVisible ? 1 : 0
|
||||
|
||||
const mesh = new THREE.Mesh(sphere, material)
|
||||
mesh.position.set(4.5, 2, 4.5)
|
||||
mesh.name = ENTITY_NAME
|
||||
|
||||
scene.add(mesh)
|
||||
}
|
||||
|
||||
function removeEntity(entityName) {
|
||||
var selectedEntity = scene.getObjectByName(entityName);
|
||||
if(selectedEntity){
|
||||
scene.remove( selectedEntity );
|
||||
}
|
||||
}
|
||||
|
||||
function createPoint(title, x, y, z){
|
||||
const label = document.createElement('p')
|
||||
label.textContent = title
|
||||
label.style.backgroundColor = '#fff'
|
||||
label.style.borderRadius = '50%'
|
||||
label.style.height = '60px'
|
||||
label.style.width = '60px'
|
||||
label.style.textAlign = 'center'
|
||||
label.style.pointerEvents = 'auto'
|
||||
label.style.cursor = 'pointer'
|
||||
|
||||
const cPointLabel = new CSS2DObject(label)
|
||||
cPointLabel.name = title
|
||||
scene.add(cPointLabel)
|
||||
|
||||
cPointLabel.position.set(x, y, z)
|
||||
|
||||
return label
|
||||
}
|
||||
|
||||
function createScene(){
|
||||
const container = document.getElementById('root');
|
||||
|
||||
scene = new THREE.Scene();
|
||||
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 2, 1100 );
|
||||
camera.position.set(5,2,4.5)
|
||||
|
||||
const geometry = new THREE.SphereGeometry( 5, 60, 40 );
|
||||
const largeGeometry = new THREE.SphereGeometry( 10, 60, 40 );
|
||||
geometry.scale( - 1, 1, 1 );
|
||||
largeGeometry.scale( - 1, 1, 1 );
|
||||
|
||||
const texture = new THREE.TextureLoader().load( '/src/assets/sea.jpg' );
|
||||
texture.colorSpace = THREE.SRGBColorSpace;
|
||||
const texture1 = new THREE.TextureLoader().load( '/src/assets/podval.jpg' );
|
||||
texture1.colorSpace = THREE.SRGBColorSpace;
|
||||
const material = new THREE.MeshBasicMaterial( { map: texture1 } );
|
||||
const material1 = new THREE.MeshBasicMaterial( { map: texture } );
|
||||
|
||||
const mesh = new THREE.Mesh( geometry, material );
|
||||
const meshLarge = new THREE.Mesh( largeGeometry, material );
|
||||
const mesh1 = new THREE.Mesh( geometry, material1 );
|
||||
const mesh1Large = new THREE.Mesh( largeGeometry, material1 );
|
||||
|
||||
mesh.position.set(4.5,2,4.5)
|
||||
meshLarge.position.set(4.5,2,4.5)
|
||||
mesh1.position.set(23.5,2,4.5)
|
||||
mesh1Large.position.set(23.5,2,4.5)
|
||||
|
||||
scene.add( meshLarge );
|
||||
scene.add( mesh1Large );
|
||||
camera.position.set(5, 2, 4.5)
|
||||
|
||||
renderer = new THREE.WebGLRenderer();
|
||||
renderer.setPixelRatio( window.devicePixelRatio );
|
||||
renderer.setSize( window.innerWidth, window.innerHeight );
|
||||
container.appendChild( renderer.domElement );
|
||||
|
||||
const controls = new OrbitControls(camera, renderer.domElement)
|
||||
controls.update()
|
||||
controls.target.set(4.5, 2, 4.5)
|
||||
controls.maxPolarAngle = Math.PI / 2.1
|
||||
controls.rotateSpeed = 0.95
|
||||
|
||||
labelRenderer = new CSS2DRenderer();
|
||||
labelRenderer.setSize(window.innerWidth, window.innerHeight);
|
||||
labelRenderer.domElement.style.position = 'absolute'
|
||||
labelRenderer.domElement.style.top = '0px'
|
||||
labelRenderer.domElement.style.pointerEvents = 'none'
|
||||
document.body.appendChild(labelRenderer.domElement);
|
||||
container.appendChild(labelRenderer.domElement);
|
||||
|
||||
const p = document.createElement('p')
|
||||
p.textContent = 'Sea'
|
||||
p.style.backgroundColor = '#fff'
|
||||
p.style.borderRadius = '50%'
|
||||
|
||||
const controls = new OrbitControls(camera, renderer.domElement)
|
||||
controls.update()
|
||||
controls.target.set(4.5, 2, 4.5)
|
||||
controls.maxPolarAngle = Math.PI / 2.1
|
||||
controls.rotateSpeed = 0.95
|
||||
}
|
||||
|
||||
p.style.height = '50px'
|
||||
p.style.width = '50px'
|
||||
p.style.textAlign = 'center'
|
||||
p.style.verticalAlign = 'middle'
|
||||
p.style.pointerEvents = 'auto'
|
||||
p.style.cursor = 'pointer'
|
||||
const cPointLabel = new CSS2DObject(p)
|
||||
scene.add(cPointLabel)
|
||||
cPointLabel.position.set(9, 2.1, 4.5)
|
||||
function init() {
|
||||
createScene()
|
||||
|
||||
let isMoved = false;
|
||||
p.addEventListener('click', () => {
|
||||
if(!isMoved){
|
||||
controls.target.set(23.5, 2, 4.5)
|
||||
p.textContent = 'House'
|
||||
gsap.to(camera.position, {x: 24, y: 2, z: 4.5, duration: 1.5})
|
||||
isMoved = true
|
||||
}
|
||||
else if(isMoved){
|
||||
gsap.to(camera.position, {x: 5, y: 2, z: 4.5, duration: 1.5})
|
||||
p.textContent = 'Sea'
|
||||
controls.target.set(4.5, 2, 4.5)
|
||||
isMoved = false
|
||||
}
|
||||
const firstTexture = new THREE.TextureLoader().load( '/src/assets/sea.jpg' );
|
||||
const firstMaterial = new THREE.MeshBasicMaterial( { map: firstTexture } );
|
||||
|
||||
const secondTexture = new THREE.TextureLoader().load( '/src/assets/podval.jpg' );
|
||||
const secondMaterial = new THREE.MeshBasicMaterial( { map: secondTexture } );
|
||||
|
||||
const thirdTexture = new THREE.TextureLoader().load( '/src/assets/loc3.jpg' );
|
||||
const thirdMaterial = new THREE.MeshBasicMaterial( { map: thirdTexture } );
|
||||
|
||||
currentTexture = firstTexture
|
||||
currentMaterial = firstMaterial
|
||||
|
||||
createSphere(5, 60, 40, firstTexture, firstMaterial, true);
|
||||
|
||||
const firstPoint = createPoint('Loc 1', 9, 2.1, 4.5)
|
||||
const secondPoint = createPoint('Loc 2', -9, 2.1, 4.5)
|
||||
const thirdPoint = createPoint('Loc 3', -12, 2.1, 11.5)
|
||||
|
||||
secondPoint.style.opacity = 0
|
||||
|
||||
firstPoint.addEventListener('click', () => {
|
||||
const timeline = gsap.timeline()
|
||||
|
||||
createSphere(5, 60, 40, secondTexture, secondMaterial)
|
||||
|
||||
timeline
|
||||
.to(currentTexture, {opacity: 0,
|
||||
onComplete: () => {
|
||||
firstPoint.style.opacity = 0
|
||||
secondPoint.style.opacity = 1
|
||||
thirdPoint.style.opacity = 1
|
||||
|
||||
currentTexture = secondTexture
|
||||
currentMaterial = secondMaterial
|
||||
|
||||
removeEntity(ENTITY_NAME)
|
||||
}})
|
||||
.to(secondMaterial, {opacity: 1})
|
||||
|
||||
|
||||
})
|
||||
|
||||
secondPoint.addEventListener('click', () => {
|
||||
const timeline = gsap.timeline()
|
||||
|
||||
createSphere(5, 60, 40, firstTexture, firstMaterial)
|
||||
|
||||
|
||||
timeline
|
||||
.to(currentTexture, {opacity: 0,
|
||||
onComplete: () => {
|
||||
firstPoint.style.opacity = 1
|
||||
secondPoint.style.opacity = 0
|
||||
thirdPoint.style.opacity = 1
|
||||
|
||||
currentTexture = firstTexture
|
||||
currentMaterial = firstMaterial
|
||||
|
||||
removeEntity(ENTITY_NAME)
|
||||
}})
|
||||
.to(firstMaterial, {opacity: 1})
|
||||
|
||||
|
||||
})
|
||||
|
||||
thirdPoint.addEventListener('click', () => {
|
||||
const timeline = gsap.timeline()
|
||||
|
||||
createSphere(5, 60, 40, thirdTexture, thirdMaterial)
|
||||
|
||||
timeline
|
||||
.to(currentTexture, {opacity: 0,
|
||||
onComplete: () => {
|
||||
firstPoint.style.opacity = 1
|
||||
secondPoint.style.opacity = 1
|
||||
thirdPoint.style.opacity = 0
|
||||
|
||||
currentTexture = thirdTexture
|
||||
currentMaterial = thirdMaterial
|
||||
|
||||
removeEntity(ENTITY_NAME)
|
||||
}})
|
||||
.to(thirdMaterial, {opacity: 1})
|
||||
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function animate() {
|
||||
|
||||
requestAnimationFrame( animate );
|
||||
update();
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.6 MiB |
+1
-1
@@ -6,7 +6,7 @@ import './index.css'
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<App1 />
|
||||
{/* <App1 /> */}
|
||||
{/* <App /> */}
|
||||
</React.StrictMode>,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user