]> gitweb.cassieko.com Git - neon-realms.git/commitdiff
Gravity Balls: Added reset button and multi-touch
authorCassie <cassie@cassieko.com>
Tue, 25 Feb 2025 19:11:21 +0000 (14:11 -0500)
committerCassie <cassie@cassieko.com>
Tue, 25 Feb 2025 19:11:21 +0000 (14:11 -0500)
html/1-Balls/balls.html

index cae3dd427f69741022b42d21b9a6974713610466..82a403b2767eb9e106640b2bd269fd8ca21901a8 100644 (file)
       position: fixed; top: 10px; left: 10px;
       color: white; font-family: Arial; pointer-events: none;
     }
+
+    #resetBtn {
+      position: fixed;
+      top: 20px;
+      left: 20px;
+      padding: 12px 24px;
+      background: rgba(255, 255, 255, 0.1);
+      border: 2px solid rgba(255, 255, 255, 0.3);
+      color: white;
+      font-family: Arial;
+      font-size: 16px;
+      border-radius: 30px;
+      cursor: pointer;
+      backdrop-filter: blur(5px);
+      transition: all 0.3s ease;
+      box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
+      z-index: 1000;
+    }
+
+    #resetBtn:hover {
+      background: rgba(255, 0, 100, 0.3);
+      border-color: rgba(255, 0, 100, 0.7);
+      transform: scale(1.05);
+    }
+
+    #resetBtn:active {
+      transform: scale(0.95);
+      background: rgba(255, 0, 100, 0.3);
+      border-color: rgba(255, 255, 255, 0.3);
+    }
+
+    @media (hover: none) {
+      #resetBtn:hover {
+        background: rgba(255, 255, 255, 0.1);
+        border-color: rgba(255, 255, 255, 0.3);
+        transform: none;
+      }
+    }
   </style>
 </head>
 <body>
   <canvas id="canvas"></canvas>
   <div id="status"></div>
+  <button id="resetBtn">Reset</button>
   <script src="matter.min.js"></script>
   <script>
-    // Configuration variables with detailed comments
     const CONFIG = {
-      // Particle properties:
       PARTICLE_RADIUS: 5,
       PARTICLE_VARIATION: 4,
       PARTICLE_RESTITUTION: 0.6,
       PARTICLE_FRICTION: 0.00,
       PARTICLE_FRICTION_AIR: 0.000,
       GRAVITY_SCALE: 0.005,
-
-      // Shake behavior:
       SHAKE_FORCE: 0.2,
       SHAKE_THRESHOLD: 12,
-
-      // Walls:
       WALL_THICKNESS: 40,
       WALL_RESTITUTION: 0.8,
-
-      // Spawn behavior:
       SPAWN_FORCE: 0,
       PARTICLES_PER_SPAWN: 3,
-
-      // World gravity:
       WORLD_GRAVITY: 1.0
     };
 
     const canvas = document.getElementById('canvas');
     const statusDiv = document.getElementById('status');
+    const resetBtn = document.getElementById('resetBtn');
     let engine, runner, render;
     let walls = [];
     let isInitialized = false;
 
-    // Track continuous input for spawning particles.
-    let isPointerDown = false;
-    let pointerX = null;
-    let pointerY = null;
+    // Track multiple touches and mouse input
+    let activeTouches = new Map(); // Stores active touch points
+    let isMouseDown = false; // Tracks mouse state
 
-    // Helper function to generate a random neon color.
     function randomNeonColor() {
       return `hsl(${Math.floor(Math.random() * 360)}, 100%, 50%)`;
     }
       resize();
       createWalls();
 
-      // Set up pointer events for continuous particle spawning.
-      canvas.addEventListener('mousedown', onPointerDown, false);
-      canvas.addEventListener('mousemove', onPointerMove, false);
-      canvas.addEventListener('mouseup', onPointerUp, false);
+      // Mouse events
+      canvas.addEventListener('mousedown', onMouseDown, false);
+      canvas.addEventListener('mousemove', onMouseMove, false);
+      canvas.addEventListener('mouseup', onMouseUp, false);
 
+      // Touch events
       canvas.addEventListener('touchstart', onTouchStart, { passive: false });
       canvas.addEventListener('touchmove', onTouchMove, { passive: false });
       canvas.addEventListener('touchend', onTouchEnd, { passive: false });
       spawnLoop();
     }
 
-    // Schedule the simulated touch after the full window load event.
-    window.addEventListener('load', () => {
-      setTimeout(simulateTouch, 25);
-    });
-
-    function simulateTouch() {
-      const simulatedX = canvas.width / 2;
-      const simulatedY = canvas.height * 0.25;
-      let touchObj;
-      try {
-        touchObj = new Touch({
-          identifier: Date.now(),
-          target: canvas,
-          clientX: simulatedX,
-          clientY: simulatedY,
-          pageX: simulatedX,
-          pageY: simulatedY,
-          screenX: simulatedX,
-          screenY: simulatedY
-        });
-      } catch (e) {
-        touchObj = { clientX: simulatedX, clientY: simulatedY };
-      }
+    // Mouse event handlers
+    function onMouseDown(event) {
+      isMouseDown = true;
+      activeTouches.set('mouse', {
+        x: event.clientX,
+        y: event.clientY
+      });
+    }
 
-      let touchStartEvent;
-      try {
-        touchStartEvent = new TouchEvent('touchstart', {
-          cancelable: true,
-          bubbles: true,
-          touches: [touchObj],
-          targetTouches: [touchObj],
-          changedTouches: [touchObj]
+    function onMouseMove(event) {
+      if (isMouseDown) {
+        activeTouches.set('mouse', {
+          x: event.clientX,
+          y: event.clientY
         });
-      } catch (e) {
-        touchStartEvent = new Event('touchstart', { bubbles: true, cancelable: true });
-        touchStartEvent.touches = [touchObj];
-        touchStartEvent.targetTouches = [touchObj];
-        touchStartEvent.changedTouches = [touchObj];
       }
-      canvas.dispatchEvent(touchStartEvent);
-
-      // End the simulated touch after a short delay.
-      setTimeout(() => {
-        let touchEndEvent;
-        try {
-          touchEndEvent = new TouchEvent('touchend', {
-            cancelable: true,
-            bubbles: true,
-            touches: [],
-            targetTouches: [],
-            changedTouches: [touchObj]
-          });
-        } catch (e) {
-          touchEndEvent = new Event('touchend', { bubbles: true, cancelable: true });
-          touchEndEvent.touches = [];
-          touchEndEvent.targetTouches = [];
-          touchEndEvent.changedTouches = [touchObj];
-        }
-        canvas.dispatchEvent(touchEndEvent);
-      }, 100);
     }
 
-    function spawnLoop() {
-      if (isPointerDown && pointerX !== null && pointerY !== null) {
-        for (let i = 0; i < CONFIG.PARTICLES_PER_SPAWN; i++) {
-          createParticle(pointerX, pointerY);
-        }
-      }
-      requestAnimationFrame(spawnLoop);
-    }
-
-    function onPointerDown(event) {
-      isPointerDown = true;
-      pointerX = event.clientX;
-      pointerY = event.clientY;
-    }
-    function onPointerMove(event) {
-      if (isPointerDown) {
-        pointerX = event.clientX;
-        pointerY = event.clientY;
-      }
-    }
-    function onPointerUp() {
-      isPointerDown = false;
-      pointerX = null;
-      pointerY = null;
+    function onMouseUp() {
+      isMouseDown = false;
+      activeTouches.delete('mouse');
     }
 
+    // Touch event handlers
     function onTouchStart(event) {
       event.preventDefault();
-      isPointerDown = true;
-      const touch = event.touches[0];
-      pointerX = touch.clientX;
-      pointerY = touch.clientY;
+      Array.from(event.changedTouches).forEach(touch => {
+        activeTouches.set(touch.identifier, {
+          x: touch.clientX,
+          y: touch.clientY
+        });
+      });
     }
+
     function onTouchMove(event) {
       event.preventDefault();
-      if (isPointerDown && event.touches.length > 0) {
-        const touch = event.touches[0];
-        pointerX = touch.clientX;
-        pointerY = touch.clientY;
-      }
+      Array.from(event.changedTouches).forEach(touch => {
+        if (activeTouches.has(touch.identifier)) {
+          activeTouches.set(touch.identifier, {
+            x: touch.clientX,
+            y: touch.clientY
+          });
+        }
+      });
     }
+
     function onTouchEnd(event) {
       event.preventDefault();
-      if (event.touches.length === 0) {
-        isPointerDown = false;
-        pointerX = null;
-        pointerY = null;
-      }
+      Array.from(event.changedTouches).forEach(touch => {
+        activeTouches.delete(touch.identifier);
+      });
+    }
+
+    // Spawn particles for all active touch points
+    function spawnLoop() {
+      activeTouches.forEach(touch => {
+        for (let i = 0; i < CONFIG.PARTICLES_PER_SPAWN; i++) {
+          createParticle(touch.x, touch.y);
+        }
+      });
+      requestAnimationFrame(spawnLoop);
     }
 
     function createParticle(x, y) {
       createWalls();
     }
 
-    let lastShake = Date.now();
+    function removeAllBalls() {
+      Matter.Composite.allBodies(engine.world).forEach(body => {
+        if (!body.isStatic) {
+          Matter.Composite.remove(engine.world, body);
+        }
+      });
+    }
 
+    // Handle device motion for gravity effects
     function handleMotion(e) {
       const acc = e.accelerationIncludingGravity;
       if (!acc) return;
       }
     }
 
+    // Request permission for device motion sensors
     function requestSensorPermissions() {
       if (typeof DeviceMotionEvent !== "undefined" && typeof DeviceMotionEvent.requestPermission === "function") {
         DeviceMotionEvent.requestPermission().then(state => {
       }
     }
 
+    // Reset button event handlers
+    resetBtn.addEventListener('mousedown', () => {
+      resetBtn.style.background = 'rgba(255, 0, 100, 0.3)';
+      resetBtn.style.borderColor = 'rgba(255, 0, 100, 0.7)';
+    });
+    resetBtn.addEventListener('mouseup', () => {
+      resetBtn.style.background = 'rgba(255, 255, 255, 0.1)';
+      resetBtn.style.borderColor = 'rgba(255, 255, 255, 0.3)';
+    });
+    resetBtn.addEventListener('mouseleave', () => {
+      resetBtn.style.background = 'rgba(255, 255, 255, 0.1)';
+      resetBtn.style.borderColor = 'rgba(255, 255, 255, 0.3)';
+    });
+
+    resetBtn.addEventListener('touchstart', () => {
+      resetBtn.style.background = 'rgba(255, 0, 100, 0.3)';
+      resetBtn.style.borderColor = 'rgba(255, 0, 100, 0.7)';
+      removeAllBalls();
+    });
+    resetBtn.addEventListener('touchend', () => {
+      resetBtn.style.background = 'rgba(255, 255, 255, 0.1)';
+      resetBtn.style.borderColor = 'rgba(255, 255, 255, 0.3)';
+    });
+
     init();
   </script>
 </body>
 </html>
-