Spaces:
Sleeping
Sleeping
| (async () => { | |
| const meta = await (await fetch("/slide_meta")).json(); | |
| const slides = meta.slides; | |
| let current = 0; | |
| const slideImg = document.getElementById("slide"); | |
| const count = document.getElementById("count"); | |
| function show(i) { | |
| if (slides.length === 0) { | |
| count.innerText = "No slides in /slides folder"; | |
| return; | |
| } | |
| current = Math.max(0, Math.min(slides.length - 1, i)); | |
| slideImg.src = "/slides/" + slides[current]; | |
| count.innerText = `${current + 1} / ${slides.length}`; | |
| } | |
| show(0); | |
| // Webcam + Mediapipe | |
| const video = document.getElementById("webcam"); | |
| const canvas = document.getElementById("overlay"); | |
| const ctx = canvas.getContext("2d"); | |
| let lastX = null, lastTime = null, cooldown = 0; | |
| function onResults(res) { | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| if (res.multiHandLandmarks && res.multiHandLandmarks.length > 0) { | |
| const lm = res.multiHandLandmarks[0]; | |
| window.drawLandmarks(ctx, lm); | |
| const x = lm[0].x; | |
| const now = performance.now(); | |
| if (lastX !== null) { | |
| const dx = x - lastX; | |
| const dt = (now - lastTime) / 1000; | |
| const speed = dx / dt; | |
| if (now > cooldown) { | |
| if (speed > 1.3) { | |
| show(current + 1); // Next slide | |
| cooldown = now + 800; | |
| } | |
| if (speed < -1.3) { | |
| show(current - 1); // Previous slide | |
| cooldown = now + 800; | |
| } | |
| } | |
| } | |
| lastX = x; | |
| lastTime = now; | |
| } | |
| } | |
| const hands = new Hands({ | |
| locateFile: f => `https://cdn.jsdelivr.net/npm/@mediapipe/hands/${f}` | |
| }); | |
| hands.setOptions({ | |
| maxNumHands: 1, | |
| modelComplexity: 0, | |
| minDetectionConfidence: 0.6, | |
| minTrackingConfidence: 0.6 | |
| }); | |
| hands.onResults(onResults); | |
| const camera = new Camera(video, { | |
| onFrame: async () => await hands.send({ image: video }), | |
| width: 320, | |
| height: 240 | |
| }); | |
| camera.start(); | |
| })(); | |