JSFiddle - React, Tailwind, and code Playground
HTML
<script src="//cdn.rawgit.com/mrdoob/three.js/master/build/three.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.min.js"></script>
<canvas id="map"></canvas>
CSS
body,html, canvas{width:100%;height:100%;padding:0;margin:0;overflow: hidden;}
JavaScript
let renderer, scene, camera, particles, vertices;
const RESOLUTION = 30;
const POINT_SIZE = 40.0;
const imageSourceUrl = "https://upload.wikimedia.org/wikipedia/commons/e/ec/World_map_blank_without_borders.svg";
let width = window.innerWidth;
let height = window.innerHeight;
const centerVector = new THREE.Vector3(0, 0, 0);
const color = new THREE.Color();
function getImageData(image) {
const canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
const ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
return ctx.getImageData(0, 0, image.width, image.height);
}
function makeVertices(imageData) {
const arr = [];
for (var y = 0, y2 = imageData.height; y < y2; y += RESOLUTION) {
for (var x = 0, x2 = imageData.width; x < x2; x += RESOLUTION) {
if (imageData.data[(x * 4 + y * 4 * imageData.width) + 3] > 128) {
const vertex = new THREE.Vector3();
vertex.x = x - imageData.width * 0.5;
vertex.y = -y + imageData.height * 0.5;
vertex.z = 2000;
vertex.delay = Math.random() * 600;
vertex.destination = {
x: x - imageData.width * 0.5,
y: -y + imageData.height * 0.5,
z: -2500
};
vertex.datapointCount = Math.floor(Math.random() * 100)
vertex.speed = Math.random() + 0.04;
arr.push(vertex);
}
}
}
return arr;
}
function makeGeometry(vertices) {
let geo = new THREE.BufferGeometry().setFromPoints( vertices );
// feed color attribute data
const aggregatedDatapoints = vertices.map(v => v.datapointCount);
const maxDatapoints = Math.max(...aggregatedDatapoints);
const colorScale = d3.scaleOrdinal()
.domain([0, maxDatapoints])
.range([ '#d3eaff', '#79beff', '#2596ff', '#fbb05f', '#fa8c16' ])
const colors = new Float32Array(vertices.length * 3);
vertices.forEach((v, i) => {
const { r, g, b } = color.setStyle(colorScale(v.datapointCount));
var stride = i * 3;
...