// 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();
Made on
Tilda