125 lines
3.4 KiB
JavaScript
125 lines
3.4 KiB
JavaScript
|
//Get window size
|
||
|
var ww = window.innerWidth,
|
||
|
wh = window.innerHeight;
|
||
|
|
||
|
//Create a WebGL renderer
|
||
|
var renderer = new THREE.WebGLRenderer({
|
||
|
canvas: document.querySelector("canvas")
|
||
|
});
|
||
|
renderer.setSize(ww, wh);
|
||
|
|
||
|
//Create an empty scene
|
||
|
var scene = new THREE.Scene();
|
||
|
scene.fog = new THREE.Fog(0x000000, 30, 150);
|
||
|
|
||
|
//Create a perpsective camera
|
||
|
var camera = new THREE.PerspectiveCamera(45, ww / wh, 0.1, 150);
|
||
|
camera.position.y = 400;
|
||
|
camera.position.z = 400;
|
||
|
|
||
|
//Array of points
|
||
|
var points = [
|
||
|
[68.5, 185.5],
|
||
|
[1, 262.5],
|
||
|
[270.9, 281.9],
|
||
|
[345.5, 212.8],
|
||
|
[178, 155.7],
|
||
|
[240.3, 72.3],
|
||
|
[153.4, 0.6],
|
||
|
[52.6, 53.3],
|
||
|
[68.5, 185.5]
|
||
|
];
|
||
|
|
||
|
//Convert the array of points into vertices
|
||
|
for (var i = 0; i < points.length; i++) {
|
||
|
var x = points[i][0];
|
||
|
var y = Math.random() * 100;
|
||
|
var z = points[i][1];
|
||
|
points[i] = new THREE.Vector3(x, y, z);
|
||
|
}
|
||
|
//Create a path from the points
|
||
|
var path = new THREE.CatmullRomCurve3(points);
|
||
|
path.closed = true;
|
||
|
|
||
|
// Define the precision of the finale tube, the amount of divisions
|
||
|
var tubeDetail = 1600;
|
||
|
// Define the precision of the circles
|
||
|
var circlesDetail = 40;
|
||
|
|
||
|
// Define the radius of the finale tube
|
||
|
var radius = 4;
|
||
|
// Get all the circles that will compose the tube
|
||
|
var frames = path.computeFrenetFrames(tubeDetail, true);
|
||
|
|
||
|
// Create an empty Geometry where we will put the particles
|
||
|
var geometry = new THREE.Geometry();
|
||
|
|
||
|
// Define a basic color
|
||
|
var color = new THREE.Color(0x000000);
|
||
|
|
||
|
// First loop through all the circles
|
||
|
for (var i = 0; i < tubeDetail; i++) {
|
||
|
// Get the normal values for each circle
|
||
|
var normal = frames.normals[i];
|
||
|
// Get the binormal values
|
||
|
var binormal = frames.binormals[i];
|
||
|
|
||
|
// Calculate the index of the circle (from 0 to 1)
|
||
|
var index = i / tubeDetail;
|
||
|
// Get the coordinates of the point in the center of the circle
|
||
|
var p = path.getPointAt(index);
|
||
|
|
||
|
// Loop for the amount of particles we want along each circle
|
||
|
for (var j = 0; j < circlesDetail; j++) {
|
||
|
// Clone the position of the point in the center
|
||
|
var position = p.clone();
|
||
|
|
||
|
// Calculate the angle for each particle along the circle (from 0 to Pi*2)
|
||
|
var angle = (j / circlesDetail) * Math.PI * 2 + (index * Math.PI * 5);
|
||
|
// Calculate the sine of the angle
|
||
|
var sin = Math.sin(angle);
|
||
|
// Calculate the cosine from the angle
|
||
|
var cos = -Math.cos(angle);
|
||
|
|
||
|
// Calculate the normal of each point based on its angle
|
||
|
var normalPoint = new THREE.Vector3(0, 0, 0);
|
||
|
normalPoint.x = (cos * normal.x + sin * binormal.x);
|
||
|
normalPoint.y = (cos * normal.y + sin * binormal.y);
|
||
|
normalPoint.z = (cos * normal.z + sin * binormal.z);
|
||
|
// Multiple the normal by the radius
|
||
|
normalPoint.multiplyScalar(radius);
|
||
|
|
||
|
// We add the normal values for each point
|
||
|
position.add(normalPoint);
|
||
|
var color = new THREE.Color("hsl(" + (index * 360 * 4) + ", 100%, 50%)");
|
||
|
geometry.colors.push(color);
|
||
|
geometry.vertices.push(position);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Material for the points
|
||
|
var material = new THREE.PointsMaterial({
|
||
|
size: 0.2,
|
||
|
vertexColors: THREE.VertexColors
|
||
|
});
|
||
|
|
||
|
var tube = new THREE.Points(geometry, material);
|
||
|
//Add tube into the scene
|
||
|
scene.add(tube);
|
||
|
|
||
|
var percentage = 0;
|
||
|
|
||
|
function render() {
|
||
|
|
||
|
percentage += 0.0005;
|
||
|
var p1 = path.getPointAt(percentage % 1);
|
||
|
var p2 = path.getPointAt((percentage + 0.01) % 1);
|
||
|
camera.position.set(p1.x, p1.y, p1.z);
|
||
|
camera.lookAt(p2);
|
||
|
|
||
|
//Render the scene
|
||
|
renderer.render(scene, camera);
|
||
|
|
||
|
requestAnimationFrame(render);
|
||
|
}
|
||
|
requestAnimationFrame(render);
|