summaryrefslogtreecommitdiff
path: root/web-timeplot/src/demos.js
diff options
context:
space:
mode:
authorgrothedev <grothedev@gmail.com>2026-05-29 21:49:20 -0400
committergrothedev <grothedev@gmail.com>2026-05-29 21:49:20 -0400
commit6196004b51a6850909c154f5402ff4858eab479a (patch)
tree126b8bb1600d0a656e0df016e25d08c390f3540e /web-timeplot/src/demos.js
parent27dc5849c3eaf4824d79938e7077abdbe2c82e24 (diff)
mv web stuff to root project dirHEADprototypeframeworkmain
Diffstat (limited to 'web-timeplot/src/demos.js')
-rw-r--r--web-timeplot/src/demos.js697
1 files changed, 0 insertions, 697 deletions
diff --git a/web-timeplot/src/demos.js b/web-timeplot/src/demos.js
deleted file mode 100644
index 1dd6785..0000000
--- a/web-timeplot/src/demos.js
+++ /dev/null
@@ -1,697 +0,0 @@
-/**
- * Preloaded Graphics Demos
- *
- * Each demo exports:
- * - name: Display name
- * - description: Short description
- * - setup(app, state): Called once to create objects
- * - update(app, state, objects): Called every frame
- * - cleanup(app, objects): Called when switching demos
- */
-
-// ============================================================================
-// DEMO 1: BOUNCING PARTICLES
-// ============================================================================
-
-export const bouncingParticles = {
- name: "Bouncing Particles",
- description: "Colorful particles bouncing around the screen",
-
- setup(app, state) {
- const particles = [];
- const colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0xf9ca24, 0x6c5ce7];
-
- for (let i = 0; i < 50; i++) {
- const particle = new PIXI.Graphics();
- const size = 5 + Math.random() * 10;
- particle.circle(0, 0, size);
- particle.fill(colors[Math.floor(Math.random() * colors.length)]);
-
- particle.x = Math.random() * app.screen.width;
- particle.y = Math.random() * app.screen.height;
- particle.vx = (Math.random() - 0.5) * 8;
- particle.vy = (Math.random() - 0.5) * 8;
- particle.size = size;
-
- app.stage.addChild(particle);
- particles.push(particle);
- }
-
- return { particles };
- },
-
- update(app, state, objects) {
- objects.particles.forEach(p => {
- p.x += p.vx;
- p.y += p.vy;
-
- // Bounce off edges
- if (p.x < p.size || p.x > app.screen.width - p.size) p.vx *= -1;
- if (p.y < p.size || p.y > app.screen.height - p.size) p.vy *= -1;
-
- // Clamp to screen
- p.x = Math.max(p.size, Math.min(app.screen.width - p.size, p.x));
- p.y = Math.max(p.size, Math.min(app.screen.height - p.size, p.y));
- });
- },
-
- cleanup(app, objects) {
- objects.particles.forEach(p => p.destroy());
- }
-};
-
-// ============================================================================
-// DEMO 2: SPIROGRAPH
-// ============================================================================
-
-export const spirograph = {
- name: "Spirograph",
- description: "Mesmerizing geometric spiral patterns",
-
- setup(app, state) {
- const graphics = new PIXI.Graphics();
- app.stage.addChild(graphics);
-
- return {
- graphics,
- angle: 0,
- points: []
- };
- },
-
- update(app, state, objects) {
- const cx = app.screen.width / 2;
- const cy = app.screen.height / 2;
- const t = state.state.time.current;
-
- // Generate new point
- const r1 = 150;
- const r2 = 50;
- const r3 = 30;
-
- const x = cx + Math.cos(t * 0.5) * r1 + Math.cos(t * 2) * r2 + Math.cos(t * 5) * r3;
- const y = cy + Math.sin(t * 0.5) * r1 + Math.sin(t * 2) * r2 + Math.sin(t * 5) * r3;
-
- objects.points.push({ x, y });
-
- // Keep only last 500 points
- if (objects.points.length > 500) {
- objects.points.shift();
- }
-
- // Draw trail
- objects.graphics.clear();
- if (objects.points.length > 1) {
- for (let i = 1; i < objects.points.length; i++) {
- const alpha = i / objects.points.length;
- const hue = (i / objects.points.length) * 360;
- objects.graphics.moveTo(objects.points[i-1].x, objects.points[i-1].y);
- objects.graphics.lineTo(objects.points[i].x, objects.points[i].y);
- objects.graphics.stroke({ width: 2, color: hslToHex(hue, 100, 60), alpha });
- }
- }
- },
-
- cleanup(app, objects) {
- objects.graphics.destroy();
- }
-};
-
-// ============================================================================
-// DEMO 3: STARFIELD
-// ============================================================================
-
-export const starfield = {
- name: "Starfield",
- description: "Flying through space at warp speed",
-
- setup(app, state) {
- const stars = [];
-
- for (let i = 0; i < 200; i++) {
- const star = new PIXI.Graphics();
- star.circle(0, 0, 2);
- star.fill(0xffffff);
-
- star.x = (Math.random() - 0.5) * app.screen.width * 2;
- star.y = (Math.random() - 0.5) * app.screen.height * 2;
- star.z = Math.random() * 1000;
-
- app.stage.addChild(star);
- stars.push(star);
- }
-
- return { stars };
- },
-
- update(app, state, objects) {
- const cx = app.screen.width / 2;
- const cy = app.screen.height / 2;
- const speed = 5;
-
- objects.stars.forEach(star => {
- star.z -= speed;
-
- if (star.z <= 0) {
- star.z = 1000;
- star.x = (Math.random() - 0.5) * app.screen.width * 2;
- star.y = (Math.random() - 0.5) * app.screen.height * 2;
- }
-
- const screenX = cx + (star.x / star.z) * 200;
- const screenY = cy + (star.y / star.z) * 200;
- const size = (1 - star.z / 1000) * 4 + 1;
-
- star.x = star.x;
- star.y = star.y;
- star.position.set(screenX, screenY);
- star.scale.set(size);
- star.alpha = 1 - star.z / 1000;
- });
- },
-
- cleanup(app, objects) {
- objects.stars.forEach(s => s.destroy());
- }
-};
-
-// ============================================================================
-// DEMO 4: WAVE INTERFERENCE
-// ============================================================================
-
-export const waveInterference = {
- name: "Wave Interference",
- description: "Rippling wave patterns",
-
- setup(app, state) {
- const gridSize = 20;
- const cols = Math.floor(app.screen.width / gridSize);
- const rows = Math.floor(app.screen.height / gridSize);
- const circles = [];
-
- for (let i = 0; i < cols; i++) {
- for (let j = 0; j < rows; j++) {
- const circle = new PIXI.Graphics();
- circle.circle(0, 0, 4);
- circle.fill(0x4ecdc4);
- circle.x = i * gridSize + gridSize / 2;
- circle.y = j * gridSize + gridSize / 2;
- circle.baseX = circle.x;
- circle.baseY = circle.y;
-
- app.stage.addChild(circle);
- circles.push(circle);
- }
- }
-
- return { circles, sources: [
- { x: app.screen.width * 0.3, y: app.screen.height * 0.5 },
- { x: app.screen.width * 0.7, y: app.screen.height * 0.5 }
- ]};
- },
-
- update(app, state, objects) {
- const t = state.state.time.current;
-
- objects.circles.forEach(c => {
- let totalOffset = 0;
-
- objects.sources.forEach(source => {
- const dx = c.baseX - source.x;
- const dy = c.baseY - source.y;
- const dist = Math.sqrt(dx * dx + dy * dy);
- totalOffset += Math.sin(dist * 0.05 - t * 3) * 10;
- });
-
- c.y = c.baseY + totalOffset;
- c.alpha = 0.3 + (Math.sin(totalOffset * 0.1) + 1) * 0.35;
- });
- },
-
- cleanup(app, objects) {
- objects.circles.forEach(c => c.destroy());
- }
-};
-
-// ============================================================================
-// DEMO 5: CIRCLE PACKING
-// ============================================================================
-
-export const circlePacking = {
- name: "Circle Packing",
- description: "Organic growth simulation",
-
- setup(app, state) {
- const circles = [];
- return { circles, attempts: 0 };
- },
-
- update(app, state, objects) {
- // Try to add a new circle each frame
- const maxAttempts = 100;
- const maxCircles = 150;
-
- if (objects.circles.length >= maxCircles) return;
-
- for (let i = 0; i < 10; i++) {
- const x = Math.random() * app.screen.width;
- const y = Math.random() * app.screen.height;
- const minRadius = 5;
- const maxRadius = 60;
-
- let valid = true;
- let radius = minRadius;
-
- // Find largest radius that doesn't overlap
- for (let r = minRadius; r < maxRadius; r++) {
- let overlaps = false;
-
- for (const other of objects.circles) {
- const dx = x - other.x;
- const dy = y - other.y;
- const dist = Math.sqrt(dx * dx + dy * dy);
-
- if (dist < r + other.radius + 2) {
- overlaps = true;
- break;
- }
- }
-
- if (overlaps) {
- break;
- }
- radius = r;
- }
-
- if (radius > minRadius) {
- const circle = new PIXI.Graphics();
- circle.circle(0, 0, radius);
- const hue = (objects.circles.length * 137.5) % 360;
- circle.fill(hslToHex(hue, 70, 60));
- circle.x = x;
- circle.y = y;
- circle.radius = radius;
-
- app.stage.addChild(circle);
- objects.circles.push(circle);
- break;
- }
- }
- },
-
- cleanup(app, objects) {
- objects.circles.forEach(c => c.destroy());
- }
-};
-
-// ============================================================================
-// DEMO 6: PERLIN FLOW FIELD
-// ============================================================================
-
-export const flowField = {
- name: "Flow Field",
- description: "Particles following a noise field",
-
- setup(app, state) {
- const particles = [];
- const colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0xf9ca24, 0x6c5ce7, 0xfeca57];
-
- for (let i = 0; i < 300; i++) {
- const particle = new PIXI.Graphics();
- particle.circle(0, 0, 2);
- particle.fill(colors[Math.floor(Math.random() * colors.length)]);
- particle.alpha = 0.6;
-
- particle.x = Math.random() * app.screen.width;
- particle.y = Math.random() * app.screen.height;
- particle.vx = 0;
- particle.vy = 0;
- particle.color = colors[Math.floor(Math.random() * colors.length)];
-
- app.stage.addChild(particle);
- particles.push(particle);
- }
-
- return { particles };
- },
-
- update(app, state, objects) {
- const t = state.state.time.current;
-
- objects.particles.forEach(p => {
- // Simple noise-like function using sin/cos
- const angle = noise(p.x * 0.005, p.y * 0.005, t * 0.3) * Math.PI * 2;
-
- p.vx += Math.cos(angle) * 0.3;
- p.vy += Math.sin(angle) * 0.3;
-
- // Damping
- p.vx *= 0.95;
- p.vy *= 0.95;
-
- p.x += p.vx;
- p.y += p.vy;
-
- // Wrap around screen
- if (p.x < 0) p.x = app.screen.width;
- if (p.x > app.screen.width) p.x = 0;
- if (p.y < 0) p.y = app.screen.height;
- if (p.y > app.screen.height) p.y = 0;
- });
- },
-
- cleanup(app, objects) {
- objects.particles.forEach(p => p.destroy());
- }
-};
-
-// ============================================================================
-// DEMO 7: DNA HELIX
-// ============================================================================
-
-export const dnaHelix = {
- name: "DNA Helix",
- description: "Rotating double helix structure",
-
- setup(app, state) {
- const helix1 = [];
- const helix2 = [];
- const connectors = [];
- const segments = 40;
-
- for (let i = 0; i < segments; i++) {
- const sphere1 = new PIXI.Graphics();
- sphere1.circle(0, 0, 8);
- sphere1.fill(0x4ecdc4);
- app.stage.addChild(sphere1);
- helix1.push(sphere1);
-
- const sphere2 = new PIXI.Graphics();
- sphere2.circle(0, 0, 8);
- sphere2.fill(0xff6b6b);
- app.stage.addChild(sphere2);
- helix2.push(sphere2);
-
- const connector = new PIXI.Graphics();
- app.stage.addChild(connector);
- connectors.push(connector);
- }
-
- return { helix1, helix2, connectors };
- },
-
- update(app, state, objects) {
- const t = state.state.time.current;
- const cx = app.screen.width / 2;
- const cy = app.screen.height / 2;
- const radius = 100;
- const height = app.screen.height * 0.8;
- const spacing = height / objects.helix1.length;
-
- objects.helix1.forEach((sphere, i) => {
- const y = i * spacing - height / 2 + cy;
- const angle = t + i * 0.3;
- const x = cx + Math.cos(angle) * radius;
- const z = Math.sin(angle) * radius;
-
- sphere.x = x;
- sphere.y = y;
- sphere.scale.set(1 + z / 200);
- sphere.alpha = 0.5 + z / 400;
- });
-
- objects.helix2.forEach((sphere, i) => {
- const y = i * spacing - height / 2 + cy;
- const angle = t + i * 0.3 + Math.PI;
- const x = cx + Math.cos(angle) * radius;
- const z = Math.sin(angle) * radius;
-
- sphere.x = x;
- sphere.y = y;
- sphere.scale.set(1 + z / 200);
- sphere.alpha = 0.5 + z / 400;
- });
-
- // Draw connectors
- objects.connectors.forEach((connector, i) => {
- connector.clear();
- connector.moveTo(objects.helix1[i].x, objects.helix1[i].y);
- connector.lineTo(objects.helix2[i].x, objects.helix2[i].y);
- connector.stroke({ width: 2, color: 0x666666, alpha: 0.3 });
- });
- },
-
- cleanup(app, objects) {
- objects.helix1.forEach(s => s.destroy());
- objects.helix2.forEach(s => s.destroy());
- objects.connectors.forEach(c => c.destroy());
- }
-};
-
-// ============================================================================
-// DEMO 8: FIREWORKS
-// ============================================================================
-
-export const fireworks = {
- name: "Fireworks",
- description: "Explosive particle celebration",
-
- setup(app, state) {
- return {
- explosions: [],
- nextExplosion: 0
- };
- },
-
- update(app, state, objects) {
- const t = state.state.time.current;
-
- // Create new explosion every second
- if (t > objects.nextExplosion) {
- objects.nextExplosion = t + 0.5 + Math.random();
-
- const explosion = {
- x: Math.random() * app.screen.width,
- y: Math.random() * app.screen.height * 0.7,
- particles: [],
- color: Math.random() * 0xffffff,
- born: t
- };
-
- // Create particles
- for (let i = 0; i < 50; i++) {
- const angle = (i / 50) * Math.PI * 2;
- const speed = 2 + Math.random() * 4;
- const particle = new PIXI.Graphics();
- particle.circle(0, 0, 3);
- particle.fill(explosion.color);
- particle.x = explosion.x;
- particle.y = explosion.y;
- particle.vx = Math.cos(angle) * speed;
- particle.vy = Math.sin(angle) * speed;
-
- app.stage.addChild(particle);
- explosion.particles.push(particle);
- }
-
- objects.explosions.push(explosion);
- }
-
- // Update explosions
- objects.explosions = objects.explosions.filter(explosion => {
- const age = t - explosion.born;
-
- if (age > 3) {
- explosion.particles.forEach(p => p.destroy());
- return false;
- }
-
- explosion.particles.forEach(p => {
- p.vx *= 0.98;
- p.vy += 0.1; // Gravity
- p.x += p.vx;
- p.y += p.vy;
- p.alpha = 1 - age / 3;
- });
-
- return true;
- });
- },
-
- cleanup(app, objects) {
- objects.explosions.forEach(explosion => {
- explosion.particles.forEach(p => p.destroy());
- });
- }
-};
-
-// ============================================================================
-// DEMO 9: MATRIX RAIN
-// ============================================================================
-
-export const matrixRain = {
- name: "Matrix Rain",
- description: "Falling digital rain effect",
-
- setup(app, state) {
- const fontSize = 16;
- const columns = Math.floor(app.screen.width / fontSize);
- const drops = [];
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#$%^&*";
-
- for (let i = 0; i < columns; i++) {
- const text = new PIXI.Text('', {
- fontFamily: 'monospace',
- fontSize: fontSize,
- fill: 0x00ff00
- });
- text.x = i * fontSize;
- text.y = -Math.random() * app.screen.height;
-
- app.stage.addChild(text);
- drops.push({
- text,
- speed: 1 + Math.random() * 3,
- chars: chars
- });
- }
-
- return { drops };
- },
-
- update(app, state, objects) {
- objects.drops.forEach(drop => {
- drop.y = (drop.y || drop.text.y) + drop.speed;
- drop.text.y = drop.y;
-
- // Random character
- if (Math.random() > 0.95) {
- drop.text.text = drop.chars[Math.floor(Math.random() * drop.chars.length)];
- }
-
- // Reset to top
- if (drop.y > app.screen.height) {
- drop.y = -20;
- drop.text.alpha = 1;
- }
-
- // Fade trail
- drop.text.alpha = Math.max(0.1, drop.text.alpha - 0.01);
- });
- },
-
- cleanup(app, objects) {
- objects.drops.forEach(d => d.text.destroy());
- }
-};
-
-// ============================================================================
-// DEMO 10: SOLAR SYSTEM
-// ============================================================================
-
-export const solarSystem = {
- name: "Solar System",
- description: "Orbiting planets around a star",
-
- setup(app, state) {
- const cx = app.screen.width / 2;
- const cy = app.screen.height / 2;
-
- // Sun
- const sun = new PIXI.Graphics();
- sun.circle(0, 0, 30);
- sun.fill(0xffd700);
- sun.x = cx;
- sun.y = cy;
- app.stage.addChild(sun);
-
- // Planets
- const planets = [
- { radius: 60, size: 6, speed: 2.0, color: 0x8b7355 },
- { radius: 100, size: 10, speed: 1.5, color: 0xff6347 },
- { radius: 150, size: 12, speed: 1.0, color: 0x4169e1 },
- { radius: 200, size: 8, speed: 0.7, color: 0xff4500 },
- { radius: 260, size: 18, speed: 0.4, color: 0xdaa520 },
- ];
-
- const planetObjects = planets.map(config => {
- const planet = new PIXI.Graphics();
- planet.circle(0, 0, config.size);
- planet.fill(config.color);
- planet.config = config;
- app.stage.addChild(planet);
- return planet;
- });
-
- return { sun, planets: planetObjects, cx, cy };
- },
-
- update(app, state, objects) {
- const t = state.state.time.current;
-
- objects.planets.forEach((planet, i) => {
- const angle = t * planet.config.speed;
- planet.x = objects.cx + Math.cos(angle) * planet.config.radius;
- planet.y = objects.cy + Math.sin(angle) * planet.config.radius;
- });
- },
-
- cleanup(app, objects) {
- objects.sun.destroy();
- objects.planets.forEach(p => p.destroy());
- }
-};
-
-// ============================================================================
-// UTILITIES
-// ============================================================================
-
-function hslToHex(h, s, l) {
- s /= 100;
- l /= 100;
- const c = (1 - Math.abs(2 * l - 1)) * s;
- const x = c * (1 - Math.abs((h / 60) % 2 - 1));
- const m = l - c/2;
- let r = 0, g = 0, b = 0;
-
- if (0 <= h && h < 60) {
- r = c; g = x; b = 0;
- } else if (60 <= h && h < 120) {
- r = x; g = c; b = 0;
- } else if (120 <= h && h < 180) {
- r = 0; g = c; b = x;
- } else if (180 <= h && h < 240) {
- r = 0; g = x; b = c;
- } else if (240 <= h && h < 300) {
- r = x; g = 0; b = c;
- } else if (300 <= h && h < 360) {
- r = c; g = 0; b = x;
- }
-
- r = Math.round((r + m) * 255);
- g = Math.round((g + m) * 255);
- b = Math.round((b + m) * 255);
-
- return (r << 16) | (g << 8) | b;
-}
-
-function noise(x, y, z) {
- return Math.sin(x + Math.cos(y)) * Math.cos(y + Math.sin(z)) * Math.sin(z + Math.cos(x));
-}
-
-// ============================================================================
-// EXPORT ALL DEMOS
-// ============================================================================
-
-export const allDemos = [
- bouncingParticles,
- spirograph,
- starfield,
- waveInterference,
- circlePacking,
- flowField,
- dnaHelix,
- fireworks,
- matrixRain,
- solarSystem
-];