JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/simplex-noise/2.4.0/simplex-noise.min.js"></script>
<div id="controls-panel">
<label for="speed-slider">Speed (ms): <span id="speed-label">100</span></label>
<input type="range" id="speed-slider" min="5" max="500" value="200" step="10" />
<br />
<label for="people-input">People: </label>
<!-- Add a "Confirm" button for the people input -->
<input id="people-input" type="number" value="30" min="1" max="200">
<button id="confirm-button">Confirm</button>
<br />
<button id="reset-button">Reset</button>
</div>
CSS
body { margin: 0; }
canvas { display: block; }
body {
margin: 0;
}
#controls-panel {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background-color: white;
padding: 15px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
}
#controls-panel label,
#controls-panel input,
#controls-panel button {
display: inline-block;
vertical-align: middle;
margin: 0 5px;
}
JavaScript
const scene = new THREE.Scene();
// Add a light source
const light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(0, 0, 20);
scene.add(light);
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
let nodeCount = 30;
const radius = 15;
const circleGeometry = new THREE.CircleGeometry(0.5, 32);
const lineMaterial = new THREE.LineBasicMaterial({ color: 0xffa500, opacity: 1, transparent: true });
const nodes = [];
let currentNodeIndex = 0;
let currentConnectionIndex = 1;
let connectionCount = 0;
let matchLikelihood = 0;
function initializeNodes() {
for (let i = 0; i < nodeCount; i++) {
const circleMaterial = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });
const circle = new THREE.Mesh(circleGeometry, circleMaterial);
const angle = (i / nodeCount) * 2 * Math.PI;
circle.position.set(radius * Math.cos(angle), radius * Math.sin(angle), 0);
scene.add(circle);
nodes.push(circle);
}
animate();
}
let previousLines = [];
// Add this function to reduce color saturation
function reduceSaturation(material, amount) {
const color = material.color;
const hsl = color.getHSL({ h: 0, s: 0, l: 0 });
hsl.s -= amount;
color.setHSL(hsl.h, Math.max(hsl.s, 0), hsl.l);
}
function connectNodes(nodeA, nodeB) {
if (previousLines.length > 0) {
// Change the color of all other lines to white
previousLines.forEach((line, index) => {
line.material.color.set(0xffffff);
// Reduce the opacity of all previous lines by 5% (except the current line)
if (index !== previousLines.length - 1) {
line.material.opacity = Math.max(line.material.opacity * 0.95, 0.5);
}
});
// Remove the thickness from the previous line
const lastLine = previousLines[previousLines.length - 1];
...