JSFiddle - React, Tailwind, and code Playground
by Paul West
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.0/gsap.min.js"></script>
CSS
body{
overflow: hidden;
margin: 0;
}
JavaScript
import * as THREE from "https://threejs.org/build/three.module.js";
import {
OrbitControls
} from "https://threejs.org/examples/jsm/controls/OrbitControls.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 0, 10);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
let controls = new OrbitControls(camera, renderer.domElement);
let model = new THREE.Mesh(new THREE.SphereBufferGeometry(2, 32, 16), new THREE.MeshNormalMaterial({
wireframe: true
}));
scene.add(model);
// hotspots
let hotspots = [];
setHotspot(0xffff00);
setHotspot(0xff00ff);
setHotspot(0x00ffff);
let raycaster = new THREE.Raycaster();
let mouse = new THREE.Vector2();
let triangle = new THREE.Triangle();
let axis = new THREE.Vector3();
let camPos = new THREE.Vector3();
let intersects;
document.addEventListener("pointerup", onMouseUp);
function onMouseUp(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
intersects = raycaster.intersectObjects(hotspots);
if (intersects.length > 0) {
let obj = intersects[0].object;
triangle.set(obj.position, scene.position, camera.position);
triangle.getNormal(axis);
let angle = camera.position.angleTo(obj.position);
let a = {
angle: 0
};
let duration = angle / Math.PI * 2;
camPos.copy(camera.position);
gsap.to(a, {
angle: angle,
duration: duration,
onStart: function() {
controls.enabled = false;
},
onUpdate: function(value) {
camera.position.copy(camPos).applyAxisAngle(axis, value.angle);
controls.update();
},
onUpdateParams:[a],
onComplete: function() {
controls.enabled = true;
}
}).play();
...