1(function() { 2 var isMobile = window.innerWidth < 768; 3 var SEPARATION = isMobile ? 180 : 130, 4 AMOUNTX = isMobile ? 60 : 100, 5 AMOUNTY = isMobile ? 30 : 45; 6 7 var container; 8 var camera, scene, renderer; 9 var particles, count = 0; 10 var isVisible = true; 11 var animFrameId = null; 12 13 function init() { 14 var waveEl = document.getElementById('wave'); 15 if (!waveEl) return; 16 17 container = document.createElement('div'); 18 container.className = "wave-poistion"; 19 waveEl.appendChild(container); 20 21 camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000); 22 camera.position.set(300, 800, 122); 23 24 scene = new THREE.Scene(); 25 particles = new Array(); 26 27 var PI2 = Math.PI * 2; 28 var material = new THREE.SpriteCanvasMaterial({ 29 color: 0xf9b707, 30 program: function(context) { 31 context.beginPath(); 32 context.arc(0.9, 0, 0.5, 0, PI2, true); 33 context.fill(); 34 } 35 }); 36 37 var i = 0; 38 for (var ix = 0; ix < AMOUNTX; ix++) { 39 for (var iy = 0; iy < AMOUNTY; iy++) { 40 var particle = particles[i++] = new THREE.Sprite(material); 41 particle.position.x = ix * SEPARATION - ((AMOUNTX * SEPARATION) / 2); 42 particle.position.z = iy * SEPARATION - ((AMOUNTY * SEPARATION) / 2); 43 scene.add(particle); 44 } 45 } 46 47 renderer = new THREE.CanvasRenderer(); 48 renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2)); 49 renderer.setSize(window.innerWidth, window.innerHeight); 50 container.appendChild(renderer.domElement); 51 renderer.setClearColor(0x000411, 1); 52 53 window.addEventListener('resize', onWindowResize, false); 54 55 // IntersectionObserver: Pause rendering when offscreen 56 if ('IntersectionObserver' in window) { 57 var observer = new IntersectionObserver(function(entries) { 58 entries.forEach(function(entry) { 59 isVisible = entry.isIntersecting; 60 if (isVisible && !animFrameId) { 61 animate(); 62 } 63 }); 64 }, { threshold: 0.05 }); 65 observer.observe(waveEl); 66 } 67 } 68 69 function onWindowResize() { 70 if (!camera || !renderer) return; 71 camera.aspect = window.innerWidth / window.innerHeight; 72 camera.updateProjectionMatrix(); 73 renderer.setSize(window.innerWidth, window.innerHeight); 74 } 75 76 function animate() { 77 if (!isVisible) { 78 animFrameId = null; 79 return; 80 } 81 animFrameId = requestAnimationFrame(animate); 82 render(); 83 } 84 85 function render() { 86 if (!particles || !particles.length) return; 87 var i = 0; 88 for (var ix = 0; ix < AMOUNTX; ix++) { 89 var sinX = Math.sin((ix + count) * 0.3); 90 for (var iy = 0; iy < AMOUNTY; iy++) { 91 var particle = particles[i++]; 92 if (!particle) continue; 93 var sinY = Math.sin((iy + count) * 0.5); 94 particle.position.y = (sinX * 50) + (sinY * 50); 95 particle.scale.x = particle.scale.y = (sinX + 1) * 4 + (sinY + 1) * 4; 96 } 97 } 98 renderer.render(scene, camera); 99 count += 0.08; 100 } 101 102 if (document.readyState === 'loading') { 103 document.addEventListener('DOMContentLoaded', function() { 104 init(); 105 animate(); 106 }); 107 } else { 108 init(); 109 animate(); 110 } 111})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.