Published
Edited
Mar 17, 2022
2 forks
7 stars
Insert cell
Insert cell
canvas = html`<canvas class="webgl"></canvas>`
Insert cell
THREE = {
const THREE = (window.THREE = await require("three@0.137.5/build/three.min.js"));
await require("three@0.137.5/examples/js/controls/OrbitControls.js").catch(
() => {}
);
return window.THREE;
}
Insert cell
{
// Canvas
const canvas = document.querySelector("canvas.webgl");

// Scene
const scene = new THREE.Scene();

/**
* Galaxy
*/
const params = {
count: 300000,
size: 0.01,
radius: 10,
branches: 3,
spin: 1,
randomness: 1,
randomnessPower: 1,
insideColor: "#ff6030",
outsideColor: "#1b3984"
};

let geometry = null;
let material = null;
let points = null;

const generateGalaxy = () => {
if (points) {
scene.remove(points);
material.dispose();
geometry.dispose();
}

// Galaxy

geometry = new THREE.BufferGeometry();
const positions = new Float32Array(params.count * 3);
const colors = new Float32Array(params.count * 3);

const colorInside = new THREE.Color(params.insideColor);
const colorOutside = new THREE.Color(params.outsideColor);

for (let i = 0; i < params.count; i++) {
const i3 = i * 3;

const r = Math.random() * params.radius;

const mixedColor = colorInside.clone();
mixedColor.lerp(colorOutside, r / params.radius);
colors[i3] = mixedColor.r;
colors[i3 + 1] = mixedColor.g;
colors[i3 + 2] = mixedColor.b;

const branchIndex = i % params.branches;
const branchAngle = branchIndex / params.branches;
const rotation = branchAngle * Math.PI * 2;
const spinAngle = r * params.spin;

const randomX =
Math.pow(Math.random(), params.randomnessPower) *
(Math.random() - 0.5) *
params.randomness *
r;
const randomY =
Math.pow(Math.random(), params.randomnessPower) *
(Math.random() - 0.5) *
params.randomness *
r;
const randomZ =
Math.pow(Math.random(), params.randomnessPower) *
(Math.random() - 0.5) *
params.randomness *
r;

positions[i3] = Math.cos(rotation + spinAngle) * r + randomX;
positions[i3 + 1] = randomY;
positions[i3 + 2] = Math.sin(rotation + spinAngle) * r + randomZ;
}

// Branches

geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));

material = new THREE.PointsMaterial({
color: "#6359ee",
size: params.size,
sizeAttenuation: true,
depthWrite: false,
blending: THREE.AdditiveBlending,
vertexColors: true
});
points = new THREE.Points(geometry, material);
scene.add(points);

console.log("generateGalaxy");
};
generateGalaxy();

/**
* Sizes
*/
const sizes = {
width: width,
height: 900
};

window.addEventListener("resize", () => {
// Update sizes
sizes.width = width;
sizes.height = 900;

// Update camera
camera.aspect = sizes.width / sizes.height;
camera.updateProjectionMatrix();

// Update renderer
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});

/**
* Camera
*/
// Base camera
const camera = new THREE.PerspectiveCamera(
75,
sizes.width / sizes.height,
0.1,
100
);
camera.position.x = 3;
camera.position.y = 3;
camera.position.z = 3;
scene.add(camera);

// Controls
const controls = new OrbitControls(camera, canvas);
controls.enableDamping = true;
controls.autoRotate = true;

/**
* Renderer
*/
const renderer = new THREE.WebGLRenderer({
canvas: canvas
});
renderer.setSize(sizes.width, sizes.height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

/**
* Animate
*/
const clock = new THREE.Clock();

const tick = () => {
const elapsedTime = clock.getElapsedTime();

// Update controls
controls.update();

// Render
renderer.render(scene, camera);

// Call tick again on the next frame
window.requestAnimationFrame(tick);
};

tick();
}
Insert cell
OrbitControls = THREE.OrbitControls
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more