以前に実装したThree.jsで複数のランダム配置をした記事のコードに、マウスに合わせて動作する処理を追加してみます。
サンプルコード
まずはマウスの動きに合わせて、画面内に配置した要素を回転させてみます。
import * as THREE from 'three'; // シーンの作成 const scene = new THREE.Scene(); // カメラの作成 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 10); // レンダラーの作成 const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor("white"); document.body.appendChild(renderer.domElement); // ライトの作成 const directionalLight = new THREE.DirectionalLight("white", 3); directionalLight.position.set(0, 0, 10); scene.add(directionalLight); // オブジェクトの作成 const objectCount = 150; const objects = []; for (let i = 0; i < objectCount; i++) { // ランダムなサイズ設定 const geometry = new THREE.DodecahedronGeometry( Math.random() * 1 + 1 // 1~2 ); // ランダムな色設定 const color = new THREE.Color().setRGB(Math.random(), Math.random(), Math.random()); const material = new THREE.MeshStandardMaterial({ color }); const object = new THREE.Mesh(geometry, material); // ランダムな位置設定 object.position.set( Math.random() * 40 - 20, // X: -20~20 Math.random() * 30 - 15, // Y: -15~15 Math.random() * 20 - 20 // Z: -20~0 ); scene.add(object); objects.push(object); } renderer.render(scene, camera); // リサイズの対応 const resize_canvas = () => { const w = window.innerWidth; const h = window.innerHeight; renderer.setSize(w, h); camera.aspect = w / h; camera.updateProjectionMatrix(); renderer.render(scene, camera); } window.addEventListener('resize', resize_canvas); // マウスの位置を取得 let mouseX = 0, mouseY = 0; document.addEventListener('mousemove', (e) => { mouseX = (e.clientX / window.innerWidth - 0.5) * 2; // x: -1〜1 mouseY = (e.clientY / window.innerHeight - 0.5) * 2; // y: -1〜1 }); // アニメーション設定 const animate = () => { requestAnimationFrame(animate); objects.forEach((object) => { const speedFactor = Math.random() * 0.065 + 0.005;// 0.07~0.005 object.rotation.y += (mouseX * Math.PI) * speedFactor; object.rotation.x += (-mouseY * Math.PI) * speedFactor; }); renderer.render(scene, camera); } animate();
次にマウスに合わせてカメラも同時に動かしてみます。
import * as THREE from 'three'; // シーンの作成 const scene = new THREE.Scene(); // カメラの作成 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 10); // レンダラーの作成 const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearColor("white"); document.body.appendChild(renderer.domElement); // ライトの作成 const directionalLight = new THREE.DirectionalLight("white", 3); directionalLight.position.set(0, 0, 10); scene.add(directionalLight); // オブジェクトの作成 const objectCount = 150; const objects = []; for (let i = 0; i < objectCount; i++) { // ランダムなサイズ設定 const geometry = new THREE.DodecahedronGeometry( Math.random() * 1 + 1 // 1~2 ); // ランダムな色設定 const color = new THREE.Color().setRGB(Math.random(), Math.random(), Math.random()); const material = new THREE.MeshStandardMaterial({ color }); const object = new THREE.Mesh(geometry, material); // ランダムな位置設定 object.position.set( Math.random() * 40 - 20, // X: -20~20 Math.random() * 30 - 15, // Y: -15~15 Math.random() * 20 - 20 // Z: -20~0 ); scene.add(object); objects.push(object); } renderer.render(scene, camera); // リサイズの対応 const resize_canvas = () => { const w = window.innerWidth; const h = window.innerHeight; renderer.setSize(w, h); camera.aspect = w / h; camera.updateProjectionMatrix(); renderer.render(scene, camera); } window.addEventListener('resize', resize_canvas); // マウスの位置を取得 let mouseX = 0, mouseY = 0; document.addEventListener('mousemove', (e) => { mouseX = (e.clientX / window.innerWidth - 0.5) * 2; // x: -1〜1 mouseY = (e.clientY / window.innerHeight - 0.5) * 2; // y: -1〜1 }); // アニメーション設定 const animate = () => { requestAnimationFrame(animate); objects.forEach((object) => { const speedFactor = Math.random() * 0.065 + 0.005;// 0.07~0.005 object.rotation.y += (mouseX * Math.PI) * speedFactor; object.rotation.x += (-mouseY * Math.PI) * speedFactor; }); camera.rotation.y = THREE.MathUtils.lerp(camera.rotation.y, mouseX * 0.1, 0.05); camera.rotation.x = THREE.MathUtils.lerp(camera.rotation.x, -mouseY * 0.1, 0.05); renderer.render(scene, camera); } animate();
MathUtils.lerp()は線形補間を行う関数で、滑らかに移動させるために使用しています。
マウスに合わせてカメラを動かすデモページ
コメントが承認されるまで時間がかかります。