// INIT
mainColor = #070707
secondaryColor = #80d0c7
bgColor = #13547a
body, html width: 100%; height: 100%; overflow: hidden background-color: bgColor margin: 0 font-family: Century Gothic,CenturyGothic,AppleGothic,sans-serif background: bgColor; background: linear-gradient(45deg, bgColor 0%,secondaryColor 100%);
.f position: fixed bottom: 5px right: 15px font-family: 'Arial' font-size: 0.7rem color: mainColor text-align: center; a font-size: 0.8rem color: secondaryColor
const { WebGLRenderer, Scene, PerspectiveCamera, Color, Line, SplineCurve, Path, Vector2, ShaderMaterial,
} = THREE;
const getRandomFloat = (min, max) => (Math.random() * (max - min) + min);
/* ---- CORE ---- */
let windowWidth = window.innerWidth;
let windowHeight = window.innerHeight;
class Webgl { constructor(w, h) { this.meshCount = 0; this.meshListeners = []; this.renderer = new WebGLRenderer({ antialias: true, alpha: true }); this.renderer.setPixelRatio(window.devicePixelRatio); this.scene = new Scene(); this.camera = new PerspectiveCamera(50, w / h, 1, 1000); this.camera.position.set(0, 0, 2); this.dom = this.renderer.domElement; this.update = this.update.bind(this); this.resize = this.resize.bind(this); this.resize(w, h); // set render size this.mouseX = 0; this.mouseY = 0; document.addEventListener('mousemove', this.handleMouseMove.bind(this)); } add(mesh) { this.scene.add(mesh); if (!mesh.update) return; this.meshListeners.push(mesh.update); this.meshCount++; } handleMouseMove(event) { const AMPL = 5; this.mouseX = -((event.clientX / window.innerWidth) - 0.5) * AMPL; this.mouseY = ((event.clientY / window.innerHeight) - 0.5) * AMPL; } update() { this.camera.position.x += (this.mouseX - this.camera.position.x) * .05; this.camera.position.y += (this.mouseY - this.camera.position.y) * .05; this.camera.lookAt(this.scene.position); let i = this.meshCount; while (--i >= 0) { this.meshListeners[i].apply(this, null); } this.renderer.render(this.scene, this.camera); } resize(w, h) { this.camera.aspect = w / h; this.camera.updateProjectionMatrix(); this.renderer.setSize(w, h); }
}
const webgl = new Webgl(windowWidth, windowHeight);
document.body.appendChild(webgl.dom);
/* ---- ------------- ---- */
/* ---- CREATING ZONE ---- */
const lineVert = ` varying vec2 vUv; varying vec3 vPos; void main() { vUv = uv; vPos = position; vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); gl_Position = projectionMatrix * mvPosition; }
`;
const lineFrag = ` uniform vec3 color; uniform float timer; uniform float lineHeight; uniform float spaceHeight; varying vec2 vUv; varying vec3 vPos; void main() { float t = ceil(lineHeight - mod(vPos.x + timer, spaceHeight)); gl_FragColor = vec4(color, t); }
`;
// OBJECTS
class RandomLineCurve extends Line { constructor({ amplitude = 0.5, nbrOfPoints = 4, length = 5, orientationY = -2, speed = 0.04 } = {}) { const MAX_LENGTH = length / nbrOfPoints; const MIN_LENGTH = MAX_LENGTH * 0.5; const points = []; points.push(new Vector2(0, 0)); for (let i = 0; i < nbrOfPoints; i++) { points.push(new Vector2( (MAX_LENGTH * i) + getRandomFloat(MIN_LENGTH, MAX_LENGTH), (amplitude * orientationY * i) + getRandomFloat(-amplitude, amplitude), )); } const curve = new SplineCurve(points); const path = new Path(curve.getPoints(50)); const geometry = path.createPointsGeometry(50); const material = new ShaderMaterial({ vertexShader: lineVert, fragmentShader: lineFrag, uniforms: { color: { type: 'v3', value: new Color(0xffffff) }, timer: { type: 'f', value: getRandomFloat(0, 100) }, lineHeight: { type: 'f', value: 2 }, spaceHeight: { type: 'f', value: 20 }, }, transparent: true, }); super(geometry, material); this.speed = speed; this.update = this.update.bind(this); } update() { // this.rotation.x += 0.01; this.material.uniforms.timer.value += this.speed; // this.rotation.y += 0.03; }
}
function addLine() { const curve = new RandomLineCurve({ orientationY: getRandomFloat(0, 2), length: getRandomFloat(1, 4), amplitude: getRandomFloat(0.2, 0.6), nbrOfPoints: getRandomFloat(2, 6), speed: getRandomFloat(0.02, 0.08), }); curve.rotation.x = getRandomFloat(0, Math.PI * 180); curve.position.set( getRandomFloat(-4, 2), getRandomFloat(-2, 2), getRandomFloat(-2, 2), ); // curve.rotation.x = getRandomFloat(0, Math.PI * 180); webgl.add(curve);
}
// START
for (let i = 0; i < 500; i++) { addLine();
}
/* ---- CREATING ZONE END ---- */
/**/
/**/
/**/ /* ---- ON RESIZE ---- */
/**/ function onResize() {
/**/ windowWidth = window.innerWidth;
/**/ windowHeight = window.innerHeight;
/**/ webgl.resize(windowWidth, windowHeight);
/**/ }
/**/ window.addEventListener('resize', onResize);
/**/ window.addEventListener('orientationchange', onResize);
/**/ /* ---- LOOP ---- */
/**/ function _loop() {
/**/ webgl.update();
/**/ requestAnimationFrame(_loop);
/**/ }
/**/ _loop();