Meta Description" name="description" />

Share this result

Previews are deleted daily. Get a permanent share link sent to your inbox:
Script
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> <title>Universal Neon Cat's Cradle</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/hands/hands.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@mediapipe/camera_utils/camera_utils.js"></script> <style> html, body { margin: 0; padding: 0; overflow: hidden; background: #020816; touch-action: none; } canvas { display: block; } #video { position: fixed; top: 0; left: 0; opacity: 0; pointer-events: none; } #status { position: fixed; top: 20px; left: 20px; color: rgba(255,255,255,0.7); font-family: Arial; letter-spacing: 2px; font-size: 12px; z-index: 10; } </style> </head> <body> <div id="status">Initializing Camera...</div> <video id="video" autoplay playsinline muted></video> <script> let video; let hands; let camera; let handData = []; let ready = false; const fingertips = [4,8,12,16,20]; function setup() { createCanvas(windowWidth, windowHeight); pixelDensity(1); video = document.getElementById("video"); startEverything(); } async function startEverything() { try { const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "user", width: { ideal: 1280 }, height: { ideal: 720 } }, audio: false }); video.srcObject = stream; await video.play(); setupHands(); document.getElementById("status").innerText = "Camera Ready"; } catch(err) { console.error(err); document.getElementById("status").innerText = "Camera Permission Failed"; } } function setupHands() { hands = new Hands({ locateFile: file => `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${file}` }); hands.setOptions({ maxNumHands: 2, modelComplexity: 1, minDetectionConfidence: 0.65, minTrackingConfidence: 0.65 }); hands.onResults(results => { handData = []; if (results.multiHandLandmarks) { for (let i = 0; i < results.multiHandLandmarks.length; i++) { handData.push({ landmarks: results.multiHandLandmarks[i], label: results.multiHandedness[i].label }); } } ready = true; }); camera = new Camera(video, { onFrame: async () => { await hands.send({ image: video }); }, width: 1280, height: 720 }); camera.start(); } function draw() { background(2,8,22); drawVideo(); drawCRT(); if (!ready) return; drawLandmarks(); drawStrings(); } function drawVideo() { push(); translate(width,0); scale(-1,1); tint(255,70); image(video,0,0,width,height); pop(); fill(0,10,30,110); rect(0,0,width,height); } function drawLandmarks() { for (let hand of handData) { for (let i = 0; i < hand.landmarks.length; i++) { let lm = hand.landmarks[i]; let x = width - lm.x * width; let y = lm.y * height; let c = getColor(i); drawingContext.shadowBlur = 25; drawingContext.shadowColor = c; noStroke(); fill(c); circle(x,y,10); fill(255); circle(x,y,3); } } drawingContext.shadowBlur = 0; } function drawStrings() { if (handData.length < 2) return; let left = null; let right = null; for (let h of handData) { if (h.label === "Left") left = h; if (h.label === "Right") right = h; } if (!left || !right) return; for (let i = 0; i < fingertips.length; i++) { let a = left.landmarks[fingertips[i]]; let b = right.landmarks[fingertips[i]]; let x1 = width - a.x * width; let y1 = a.y * height; let x2 = width - b.x * width; let y2 = b.y * height; let d = dist(x1,y1,x2,y2); let thick = map(d,50,700,8,1,true); neonCurve(x1,y1,x2,y2,thick,d); } } function neonCurve(x1,y1,x2,y2,t,distance) { const ctx = drawingContext; let gradient = ctx.createLinearGradient(x1,y1,x2,y2); gradient.addColorStop(0,"#00ffff"); gradient.addColorStop(0.5,"#ff00ff"); gradient.addColorStop(1,"#ffff00"); ctx.strokeStyle = gradient; ctx.lineWidth = t; ctx.shadowBlur = 30; ctx.shadowColor = "#00ffff"; noFill(); let mx = (x1+x2)/2; let my = (y1+y2)/2; let wave = sin(frameCount*0.08 + distance*0.01)*20; beginShape(); curveVertex(x1,y1); curveVertex(x1,y1); curveVertex(mx,my+wave); curveVertex(x2,y2); curveVertex(x2,y2); endShape(); ctx.shadowBlur = 0; } function drawCRT() { stroke(255,8); for (let y=0;y<height;y+=4) { line(0,y,width,y); } } function getColor(i) { if (i % 3 === 0) return "#00ffff"; if (i % 3 === 1) return "#ff00ff"; return "#ffff00"; } function windowResized() { resizeCanvas(windowWidth,windowHeight); } </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

4

Requests

3

Domains

215KB

Transfer Size

1063KB

Content Size

621.0ms

Dom Content Loaded

636.0ms

First Paint

622.0ms

Load Time
Domain Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...
Timings (ms)
Loading...
Total Time
Loading...
Content Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...