import * as THREE from 'three'; import { SpiralSegment } from './spiral.js'; import { SpiralCamera } from './controls.js'; import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; import { FontLoader } from 'three/addons/loaders/FontLoader.js'; const spiralMaterial = new THREE.ShaderMaterial( { uniforms: { time: { value: 1.0 }, resolution: { value: new THREE.Vector2() }, position: new THREE.Vector3() }, // vertexShader: document.getElementById( 'vertexShader' ).textContent, // fragmentShader: document.getElementById( 'fragmentShader' ).textContent, vertexShader: ` const float PI = 3.14159; varying vec4 v_color; varying float deg; void main() { deg = degrees(atan(position.z, position.x)) ; if (deg <= 0.) deg = 360. + deg; gl_Position = projectionMatrix * modelViewMatrix * vec4(position.x, position.y, position.z, 1.0); } `, fragmentShader: ` const float PI = 3.14159; varying vec4 v_color; varying float deg; varying float toDiscard; vec4 colors[12] = vec4[12]( vec4(0.202, 0.2406, 0.5922, 1), // jan vec4(0.0980, 0.4627, 0.8235, 1), // feb vec4(0.3984, 0.7305, 0.4141, 1), // mar vec4(0.2188, 0.5547, 0.2344, 1), // apr vec4(27./256., 94./256., 32./256., 1), // may vec4(205./256., 220./256., 57./256., 1), // jun vec4(255./256., 238./256., 88./256., 1), // jul vec4(251./256., 192./256., 45./256., 1), // aug vec4(255./256., 160./256., 0, 1), // sep vec4(245./256., 124./256., 0, 1), // oct vec4(230./256., 74./256., 25./256., 1), // nov vec4(144./256., 164./256., 174./256., 1) // dec ); void main() { if (int(round(deg)) % 30 == 0) discard; int month = int((deg / 30.)); vec4 color = mix(colors[month], colors[month + 1], (deg - float(month) * 30.) / 30.); gl_FragColor = color; } ` } ); const segmentHeight = 2; let segments = []; let viewingYear = new Date().getFullYear(); let viewDistance = 5; //setting scene const scene = new THREE.Scene(); //setting canvas var canvas = document.querySelector('#canvas'); const renderer = new THREE.WebGLRenderer({ antialias: true, canvas }); document.body.appendChild(renderer.domElement); //setting camera const camera = (new SpiralCamera(canvas, segmentHeight)); // setting light const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.set(0, 0, 1); const ambientLight = new THREE.AmbientLight(0xffffff, 10); scene.add(pointLight); scene.add(ambientLight); //Creating first segments for (let i = 0; i < viewDistance * 2 + 1; i++) { segments.push(new SpiralSegment(viewingYear - viewDistance + i, segmentHeight, spiralMaterial)); scene.add(segments[i].getSegment()); scene.add(segments[i].getText()); }; addEventListener("changedViewYear", (e) => { let newYear = camera.getViewingYear(); if (newYear > viewingYear) { // + scene.remove(segments[0].getSegment()) scene.remove(segments[0].getText()) segments.shift(); segments.push(new SpiralSegment(newYear + viewDistance, segmentHeight, spiralMaterial)); scene.add(segments[segments.length - 1].getSegment()); scene.add(segments[segments.length - 1].getText()); } else { // - scene.remove(segments[segments.length - 1].getSegment()) scene.remove(segments[segments.length - 1].getText()) segments.pop(); segments.unshift(new SpiralSegment(newYear - viewDistance, segmentHeight, spiralMaterial)) scene.add(segments[0].getSegment()); scene.add(segments[0].getText()); } viewingYear = newYear; }); //main loop function animate() { if (resizeRendererToDisplaySize(renderer)) { const canvas = renderer.domElement; camera.getCamera().aspect = canvas.clientWidth / canvas.clientHeight; camera.getCamera().updateProjectionMatrix(); } // moving text along with the camera and spiral for (let i = 0; i < segments.length; i++) { segments[i].getSegment().position.y = ((segments[i].year - camera.getViewingYear()) * segmentHeight + camera.getOffset()); segments[i].getText().position.y = segmentHeight / 2 +(segments[i].year - camera.getViewingYear()) * segmentHeight + camera.getOffset(); segments[i].getText().position.x = 2.5*Math.cos(THREE.MathUtils.degToRad(camera.getAngle() + 90)) * 3 segments[i].getText().position.z = 2.5*Math.sin(THREE.MathUtils.degToRad(camera.getAngle() + 90)) * 3 segments[i].getText().lookAt(camera.getCamera().position) } camera.getCamera().lookAt(0, 0, 0); renderer.render(scene, camera.getCamera()); requestAnimationFrame(animate); } function resizeRendererToDisplaySize(renderer) { const canvas = renderer.domElement; const width = canvas.clientWidth; const height = canvas.clientHeight; const needResize = canvas.width !== width || canvas.height !== height; if (needResize) renderer.setSize(width, height, false); return needResize; } animate();