Published
Edited
Jan 1, 2022
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
// Continuously updates
{
const clock = new THREE.Clock()
while (true) {
const time = clock.getElapsedTime()
const deltaTime = 0.017
meshes.forEach(mesh => {
// Each mesh has its own time that increases each frame
mesh.time += deltaTime;

// If it hits the end of its life, reset it
if (mesh.time > mesh.duration) {
randomMesh(mesh);
}

// Scale meshes in and out
mesh.scale.copy(mesh.scaleAtTheMoment);
mesh.scale.multiplyScalar(Math.sin(mesh.time / mesh.duration * Math.PI));

// Move meshes up
mesh.position.y += deltaTime * 0.5;

// Add slight movement
mesh.scale.y = mesh.scaleAtTheMoment.y + 0.25 * random.noise3D(
mesh.poistionAtThisMoment.x * f,
mesh.poistionAtThisMoment.y * f,
mesh.poistionAtThisMoment.z * f,
time * 0.25
);
});

renderer.render(scene, camera);
yield renderer.domElement
}
}
Insert cell
height = 600
Insert cell
Insert cell
grid = (n, gridSize) => {
const max = gridSize - 1;
const snapped = Math.round(n * max) / max;
return snapped * 2 - 1;
};
Insert cell
Insert cell
Insert cell
meshes = {
// const material = new THREE.MeshNormalMaterial();
const geometry = new THREE.BoxGeometry(1, 1, 1);

const meshes = Array.from(new Array(chunks)).map(() => {
const material = new THREE.MeshStandardMaterial({
metalness: 0,
roughness: 1,
// wireframe: true
//? 因其通过randonMesh生成,所以此处color相当于 default,真正设置还是在randomMesh里
})
const mesh = new THREE.Mesh(geometry, material)
randomMesh(mesh)

return mesh
})
return meshes
}
Insert cell
containerGroup = {
const containerGroup = new THREE.Group()
meshes.forEach(m => containerGroup.add(m))
return containerGroup
}
Insert cell
scene = {
const scene = new THREE.Scene();
scene.background = new THREE.Color("black");
scene.add(containerGroup);
const ambientLight = new THREE.AmbientLight('white', .1)
scene.add(ambientLight)
const directionalLight = new THREE.DirectionalLight('tan', 0.4)
directionalLight.position.set(1, 0.25, 0)
scene.add(directionalLight)
const hemisphereLight = new THREE.HemisphereLight("pink", "cyan", 0.3)
scene.add(hemisphereLight)
const pointLight = new THREE.PointLight('gold', 0.3)
pointLight.position.set(1, 0.1, 0)
scene.add(pointLight)
const rectAreaLight = new THREE.RectAreaLight('fuchsia', 0.2, 3, 3)
scene.add(rectAreaLight)
const spotLight = new THREE.SpotLight('ivory', 0.1, 10, 0, 0.25, 1)
spotLight.position.set(0, 0, 3)
scene.add(spotLight)
return scene;
}
Insert cell
camera = {
const fov = 45;
const aspect = width / height;
const near = 1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(2, 2, -2)
camera.lookAt(new THREE.Vector3(0, 0, 0));
return camera;
}
Insert cell
renderer = {
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(width, height);
renderer.setPixelRatio(devicePixelRatio);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => renderer.render(scene, camera));
invalidation.then(() => (controls.dispose(), renderer.dispose()));
// const tbControls = new THREE.OrbitControls(camera, renderer.domElement);
// (function animate() { // IIFE
// threeForceData.tickFrame();

// // Frame cycle
// tbControls.update();
// renderer.render(scene, camera);
// requestAnimationFrame(animate);
// })();
return renderer;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
random = CSUtils.random
Insert cell
Insert cell
gsap = gs.gsap
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more