From f72edcaf3a978b66f2f2690ca67fff847a03fd46 Mon Sep 17 00:00:00 2001 From: Isaac Bowen Date: Sun, 25 Feb 2024 11:02:02 +1300 Subject: [PATCH] awww yeah thats the stuff --- dist/bundle.js | 2 +- src/main.ts | 32 ++++++++++++++++++-------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/dist/bundle.js b/dist/bundle.js index b9ce9d4..616eedf 100644 --- a/dist/bundle.js +++ b/dist/bundle.js @@ -16,7 +16,7 @@ \*********************/ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { -eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst THREE = __webpack_require__(/*! three */ \"./node_modules/three/build/three.cjs\");\nclass SphereWithRods {\n constructor() {\n this.rods = [];\n this.totalDuration = 10; // seconds\n this.animate = () => {\n requestAnimationFrame(this.animate);\n const orbitSpeed = 0.0005;\n const time = Date.now() * orbitSpeed;\n this.camera.position.x = 5 * Math.sin(time);\n this.camera.position.y = 0;\n this.camera.position.z = 5 * Math.cos(time);\n this.camera.lookAt(new THREE.Vector3(0, 0, 0));\n this.renderer.render(this.scene, this.camera);\n };\n this.constructSphere();\n this.constructSparkline();\n }\n constructSphere() {\n this.scene = new THREE.Scene();\n this.scene.background = new THREE.Color(0x0a0a0a); // Dark grey\n this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);\n this.renderer = new THREE.WebGLRenderer({ alpha: true });\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n document.body.appendChild(this.renderer.domElement);\n this.camera.position.set(5, 5, 5);\n this.camera.lookAt(this.scene.position);\n this.rodMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.5 });\n const ambientLight = new THREE.AmbientLight(0x404040);\n this.scene.add(ambientLight);\n this.startPlacingRods();\n this.animate();\n }\n constructSparkline() {\n this.sparklineCanvas = document.getElementById('sparkline-canvas');\n this.sparklineContext = this.sparklineCanvas.getContext('2d');\n this.startTime = Date.now();\n this.drawSparkline();\n }\n drawSparkline() {\n const currentTime = Date.now();\n const elapsedTime = (currentTime - this.startTime) / 1000; // in seconds\n const progress = elapsedTime / this.totalDuration;\n this.sparklineContext.clearRect(0, 0, this.sparklineCanvas.width, this.sparklineCanvas.height);\n this.sparklineContext.beginPath();\n for (let x = 0; x <= this.sparklineCanvas.width; x++) {\n const t = x / this.sparklineCanvas.width;\n const y = this.calculateFrequency(t) * this.sparklineCanvas.height;\n this.sparklineContext.lineTo(x, this.sparklineCanvas.height - y);\n }\n this.sparklineContext.stroke();\n const lineX = (progress % 1) * this.sparklineCanvas.width;\n this.sparklineContext.beginPath();\n this.sparklineContext.moveTo(lineX, 0);\n this.sparklineContext.lineTo(lineX, this.sparklineCanvas.height);\n this.sparklineContext.strokeStyle = 'white';\n this.sparklineContext.stroke();\n requestAnimationFrame(this.drawSparkline.bind(this));\n }\n calculateFrequency(t) {\n // Sine function adjusted for [0, 1] range, peaking in the middle\n const sineWave = Math.sin(Math.PI * t);\n // Raise the sine wave to a power to make the curve more dramatic\n const power = 20; // Adjust this power to make the curve more or less dramatic\n const dramaticSineWave = Math.pow(sineWave, power);\n return dramaticSineWave;\n }\n placeRod() {\n const baseLength = 1; // Assuming R = 1\n const maxLength = 4; // 4R\n const randomFactor = Math.random(); // Direct random factor for simplicity\n const rodLength = baseLength + (maxLength - baseLength) * randomFactor;\n const rodGeometry = new THREE.CylinderGeometry(0.01, 0.01, rodLength, 32);\n const rod = new THREE.Mesh(rodGeometry, this.rodMaterial);\n const phi = Math.random() * 2 * Math.PI; // Azimuthal angle\n const theta = Math.random() * Math.PI; // Polar angle\n const jitter = 0.9 + Math.random() * 0.2; // Jitter for radius\n const x = jitter * Math.sin(theta) * Math.cos(phi);\n const y = jitter * Math.sin(theta) * Math.sin(phi);\n const z = jitter * Math.cos(theta);\n rod.position.set(x, y, z);\n rod.lookAt(this.scene.position);\n this.scene.add(rod);\n this.rods.push(rod);\n }\n startPlacingRods() {\n const minInterval = 25; // Minimum interval time in ms\n const maxInterval = 1000; // Maximum interval time in ms\n const placeRodWithVariableTiming = () => {\n const elapsedTime = (Date.now() - this.startTime) / 1000; // in seconds\n const t = elapsedTime / this.totalDuration; // Normalize time based on total duration\n const frequency = this.calculateFrequency(t);\n // Use an exponential function to decrease the delay more significantly at higher frequencies\n const delayFactor = Math.pow(1 - frequency, 100); // The exponent can be adjusted to control the \"dramatic\" effect\n const delay = maxInterval - (maxInterval - minInterval) * (1 - delayFactor);\n this.placeRod();\n setTimeout(placeRodWithVariableTiming, delay);\n };\n placeRodWithVariableTiming();\n }\n}\nnew SphereWithRods();\n\n\n//# sourceURL=webpack://flow/./src/main.ts?"); +eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst THREE = __webpack_require__(/*! three */ \"./node_modules/three/build/three.cjs\");\nclass SphereWithRods {\n constructor() {\n this.rods = [];\n this.totalDuration = 60; // seconds\n this.animate = () => {\n requestAnimationFrame(this.animate);\n const orbitSpeed = 0.0005;\n const time = Date.now() * orbitSpeed;\n this.camera.position.x = 5 * Math.sin(time);\n this.camera.position.y = 0;\n this.camera.position.z = 5 * Math.cos(time);\n this.camera.lookAt(new THREE.Vector3(0, 0, 0));\n this.renderer.render(this.scene, this.camera);\n };\n this.constructSphere();\n this.constructSparkline();\n }\n constructSphere() {\n this.scene = new THREE.Scene();\n this.scene.background = new THREE.Color(0x0a0a0a); // Dark grey\n this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100);\n this.renderer = new THREE.WebGLRenderer({ alpha: true });\n this.renderer.setSize(window.innerWidth, window.innerHeight);\n document.body.appendChild(this.renderer.domElement);\n this.camera.position.set(5, 5, 5);\n this.camera.lookAt(this.scene.position);\n this.rodMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.5 });\n const ambientLight = new THREE.AmbientLight(0x404040);\n this.scene.add(ambientLight);\n this.startPlacingRods();\n this.animate();\n }\n constructSparkline() {\n this.sparklineCanvas = document.getElementById('sparkline-canvas');\n this.sparklineContext = this.sparklineCanvas.getContext('2d');\n this.startTime = Date.now();\n this.drawSparkline();\n }\n drawSparkline() {\n const currentTime = Date.now();\n const elapsedTime = (currentTime - this.startTime) / 1000; // in seconds\n const cycle = elapsedTime % (2 * this.totalDuration); // Complete cycle for back and forth\n const progress = (cycle > this.totalDuration) ? 2 - cycle / this.totalDuration : cycle / this.totalDuration;\n this.sparklineContext.clearRect(0, 0, this.sparklineCanvas.width, this.sparklineCanvas.height);\n this.sparklineContext.beginPath();\n for (let x = 0; x <= this.sparklineCanvas.width; x++) {\n const t = x / this.sparklineCanvas.width;\n const y = this.calculateFrequency(t) * this.sparklineCanvas.height;\n this.sparklineContext.lineTo(x, this.sparklineCanvas.height - y);\n }\n this.sparklineContext.stroke();\n const lineX = progress * this.sparklineCanvas.width;\n this.sparklineContext.beginPath();\n this.sparklineContext.moveTo(lineX, 0);\n this.sparklineContext.lineTo(lineX, this.sparklineCanvas.height);\n this.sparklineContext.strokeStyle = 'white';\n this.sparklineContext.stroke();\n requestAnimationFrame(this.drawSparkline.bind(this));\n }\n calculateFrequency(t) {\n // Sine function adjusted for [0, 1] range, peaking in the middle\n const sineWave = Math.sin(Math.PI * t);\n // Raise the sine wave to a power to make the curve more dramatic\n const power = 20; // Adjust this power to make the curve more or less dramatic\n const dramaticSineWave = Math.pow(sineWave, power);\n return dramaticSineWave;\n }\n placeRod() {\n const baseLength = 1; // Assuming R = 1\n const maxLength = 4; // 4R\n const randomFactor = Math.random(); // Direct random factor for simplicity\n const rodLength = baseLength + (maxLength - baseLength) * randomFactor;\n const rodGeometry = new THREE.CylinderGeometry(0.01, 0.01, rodLength, 32);\n const rod = new THREE.Mesh(rodGeometry, this.rodMaterial);\n const phi = Math.random() * 2 * Math.PI; // Azimuthal angle\n const theta = Math.random() * Math.PI; // Polar angle\n const jitter = 0.9 + Math.random() * 0.2; // Jitter for radius\n const x = jitter * Math.sin(theta) * Math.cos(phi);\n const y = jitter * Math.sin(theta) * Math.sin(phi);\n const z = jitter * Math.cos(theta);\n rod.position.set(x, y, z);\n rod.lookAt(this.scene.position);\n this.scene.add(rod);\n this.rods.push(rod);\n }\n startPlacingRods() {\n const placeOrRemoveRod = () => {\n const elapsedTime = (Date.now() - this.startTime) / 1000; // in seconds\n const cycle = Math.floor(elapsedTime / this.totalDuration);\n const t = (elapsedTime % this.totalDuration) / this.totalDuration; // Normalized time for current half-cycle\n const frequency = this.calculateFrequency(t);\n const delayFactor = Math.pow(1 - frequency, 4); // Adjust the exponent as needed\n const delay = 1000 - (1000 - 25) * (1 - delayFactor);\n if (cycle % 2 === 0) {\n this.placeRod(); // Add rod during even cycles\n }\n else if (this.rods.length > 0) {\n const removeIndex = Math.floor(Math.random() * this.rods.length);\n const [removedRod] = this.rods.splice(removeIndex, 1); // Remove random rod during odd cycles\n this.scene.remove(removedRod);\n }\n setTimeout(placeOrRemoveRod, delay);\n };\n placeOrRemoveRod();\n }\n}\nnew SphereWithRods();\n\n\n//# sourceURL=webpack://flow/./src/main.ts?"); /***/ }), diff --git a/src/main.ts b/src/main.ts index 51fe641..3420cdb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,7 +9,7 @@ class SphereWithRods { sparklineCanvas: HTMLCanvasElement; sparklineContext: CanvasRenderingContext2D; startTime: number; - totalDuration: number = 10; // seconds + totalDuration: number = 60; // seconds constructor() { this.constructSphere(); @@ -46,7 +46,8 @@ class SphereWithRods { drawSparkline(): void { const currentTime = Date.now(); const elapsedTime = (currentTime - this.startTime) / 1000; // in seconds - const progress = elapsedTime / this.totalDuration; + const cycle = elapsedTime % (2 * this.totalDuration); // Complete cycle for back and forth + const progress = (cycle > this.totalDuration) ? 2 - cycle / this.totalDuration : cycle / this.totalDuration; this.sparklineContext.clearRect(0, 0, this.sparklineCanvas.width, this.sparklineCanvas.height); @@ -58,7 +59,7 @@ class SphereWithRods { } this.sparklineContext.stroke(); - const lineX = (progress % 1) * this.sparklineCanvas.width; + const lineX = progress * this.sparklineCanvas.width; this.sparklineContext.beginPath(); this.sparklineContext.moveTo(lineX, 0); this.sparklineContext.lineTo(lineX, this.sparklineCanvas.height); @@ -105,24 +106,27 @@ class SphereWithRods { } startPlacingRods(): void { - const minInterval = 25; // Minimum interval time in ms - const maxInterval = 1000; // Maximum interval time in ms - - const placeRodWithVariableTiming = () => { + const placeOrRemoveRod = () => { const elapsedTime = (Date.now() - this.startTime) / 1000; // in seconds - const t = elapsedTime / this.totalDuration; // Normalize time based on total duration + const cycle = Math.floor(elapsedTime / this.totalDuration); + const t = (elapsedTime % this.totalDuration) / this.totalDuration; // Normalized time for current half-cycle const frequency = this.calculateFrequency(t); - // Use an exponential function to decrease the delay more significantly at higher frequencies - const delayFactor = Math.pow(1 - frequency, 100); // The exponent can be adjusted to control the "dramatic" effect - const delay = maxInterval - (maxInterval - minInterval) * (1 - delayFactor); + const delayFactor = Math.pow(1 - frequency, 4); // Adjust the exponent as needed + const delay = 1000 - (1000 - 25) * (1 - delayFactor); - this.placeRod(); + if (cycle % 2 === 0) { + this.placeRod(); // Add rod during even cycles + } else if (this.rods.length > 0) { + const removeIndex = Math.floor(Math.random() * this.rods.length); + const [removedRod] = this.rods.splice(removeIndex, 1); // Remove random rod during odd cycles + this.scene.remove(removedRod); + } - setTimeout(placeRodWithVariableTiming, delay); + setTimeout(placeOrRemoveRod, delay); }; - placeRodWithVariableTiming(); + placeOrRemoveRod(); } animate = (): void => {