<div id="app">
<canvas id="canvas"></canvas>
</div>
body {
margin: 0;
}
#app {
background-image: radial-gradient( circle farthest-corner at 83.7% 4.3%, rgba(35,10,45,1) 0%, rgba(10,10,10,1) 90% );
width: 100vw;
height: 100vh;
}
canvas {
position: fixed;
left: 0;
top: 0;
}
import * as THREE from "https://threejs.org/build/three.module.js";
import Stats from 'https://threejs.org/examples/jsm/libs/stats.module.js';
import anime from "https://cdn.skypack.dev/animejs@3.2.1";
const PARTICLE_SIZE = 500
const SPREAD_RADIUS = 450
// let params = {
// maxSpeed: 0.5
// }
// let warp = anime({
// targets: params,
// maxSpeed: 1.5,
// easing: 'easeInOutQuad',
// duration: 3000,
// })
// let notWarp = anime({
// targets: params,
// maxSpeed: 0.5,
// easing: 'easeInOutQuad',
// duration: 3000,
// })
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 100
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#canvas'),
antialias: true,
alpha: true
})
renderer.setSize(window.innerWidth, window.innerHeight)
const stats = new Stats()
document.querySelector('#app').appendChild(stats.dom)
let positions = []
let velocity = []
let acceleration = []
for(let i=0; i<PARTICLE_SIZE; i++) {
let pos = new THREE.Vector3(
THREE.MathUtils.randFloatSpread(SPREAD_RADIUS),
THREE.MathUtils.randFloatSpread(SPREAD_RADIUS),
THREE.MathUtils.randFloatSpread(SPREAD_RADIUS)
)
positions.push(
pos,
pos.clone()
)
velocity.push(0)
acceleration.push(0.05)
}
const geo = new THREE.BufferGeometry().setFromPoints(positions)
// geo.setAttribute('position', new THREE.Float32BufferAttribute(positions, 6))
geo.setAttribute('velocity', new THREE.Float32BufferAttribute(velocity, 1))
geo.setAttribute('acceleration', new THREE.Float32BufferAttribute(acceleration, 1))
const mat = new THREE.LineBasicMaterial({
color: 0xE6E6E6
})
const stars = new THREE.LineSegments(geo, mat)
const group = new THREE.Group()
group.add(stars)
scene.add(group)
let d = 0
function animate() {
requestAnimationFrame(animate)
let positions = stars.geometry.attributes.position.array
let velocity = stars.geometry.attributes.velocity.array
let acceleration = stars.geometry.attributes.acceleration.array
let index = 0
for(let i=0; i<PARTICLE_SIZE; i++) {
let v = velocity[i]
let a = acceleration[i]
v += a
v = THREE.MathUtils.clamp(v, 0, 3.5)
let x = positions[index++]
let y = positions[index++]
let z = positions[index++]
let xx = positions[index++]
let yy = positions[index++]
let zz = positions[index++]
if(z > 100) {
x = xx = THREE.MathUtils.randFloatSpread(SPREAD_RADIUS)
y = yy = THREE.MathUtils.randFloatSpread(SPREAD_RADIUS)
z = zz = -100
// v = 1
positions[index-3] = x
positions[index-2] = y
positions[index-6] = xx
positions[index-5] = yy
}
z += v
zz += v * 1.5
velocity[i] = v
positions[index-1] = zz
positions[index-4] = z
}
stars.geometry.attributes.position.needsUpdate = true
stars.geometry.attributes.velocity.needsUpdate = true
stats.update()
renderer.render(scene, camera)
}
animate()
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})
// document.querySelector('#app').addEventListener('mousedown', () => {
// warp.restart()
// })
// document.querySelector('#app').addEventListener('mouseup', () => {
// notWarp.restart()
// })
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.