JSFiddle - React, Tailwind, and code Playground
HTML
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.162.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.162.0/examples/jsm/"
}
}
</script>
JavaScript
import * as THREE from 'three';
import {
OrbitControls
} from 'three/addons/controls/OrbitControls.js';
// init
const color = new THREE.Color();
const matrix = new THREE.Matrix4();
matrix.scale(5, 5, 5);
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 125;
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x8FBCD4);
scene.add(new THREE.AmbientLight(0xffffff, 0.4));
const dirLight = new THREE.DirectionalLight(0xffffff, 1);
dirLight.position.set(0, 100, 50);
scene.add(dirLight);
const geometry = createMorphGeometry();
const material = new THREE.MeshStandardMaterial({
flatShading: true
});
const count = 74;
const instancedMesh = new THREE.InstancedMesh(geometry, material, count);
const halfCount = count / 2;
for (let i = 0; i < count; i++) {
const x = Math.random() * 100 - 50;
const y = Math.random() * 100 - 50;
const z = Math.random() * 100 - 50;
matrix.makeTranslation(x, y, z);
matrix.scale({
x: 3,
y: 3,
z: 3
});
instancedMesh.setMatrixAt(i, matrix);
instancedMesh.setColorAt(i, color.set((i <= halfCount ? 0x4BE501 : 0xF90000) ));
instancedMesh.setMorphAt(i, {
morphTargetInfluences: [0, 0]
});
}
scene.add(instancedMesh);
const renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(animation);
document.body.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
// animation
function animation(time) {
animateMorph();
renderer.render(scene, camera);
}
window.onresize = () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animateMorph() {
const halfCount = count / 2;
for (let i = 0; i < count; i++) {
instancedMesh.getMatrixAt(i, matrix);
let x =...