folkarc:touch
Tablet-based touch input
Use this and navigate your tablet to /tablet
# Tablet Touch Handler 9000 - Revamped live at folk0 on Jun 11 2024 Wish the web server handles route "/tablet" with handler { html { <html> <body > <span id="status">Status</span> <img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDBtbSIgaGVpZ2h0PSIxMDBtbSIgdmlld0JveD0iMCAwIDEwMCAxMDAiPgo8cGF0aCBzdHlsZT0iZmlsbDojZmZmZmZmOyBzdHJva2U6bm9uZTsiIGQ9Ik0wIDBMMCAxMEwyMCAxMEwyMCAwTDAgMHoiPjwvcGF0aD4KPHBhdGggc3R5bGU9ImZpbGw6IzAwMDAwMDsgc3Ryb2tlOm5vbmU7IiBkPSJNMjAgMEwyMCAxMEwwIDEwTDAgMjBMMTAgMjBMMTAgNDBMMCA0MEwwIDYwTDEwIDYwTDEwIDcwTDAgNzBMMCAxMDBMNTAgMTAwTDUwIDkwTDYwIDkwTDYwIDEwMEw3MCAxMDBMNzAgOTBMOTAgOTBMOTAgMTAwTDEwMCAxMDBMMTAwIDYwTDkwIDYwTDkwIDQwTDEwMCA0MEwxMDAgMzBMOTAgMzBMOTAgMjBMMTAwIDIwTDEwMCAwTDkwIDBMOTAgMTBMODAgMTBMODAgMEwyMCAweiI+PC9wYXRoPgo8cGF0aCBzdHlsZT0iZmlsbDojZmZmZmZmOyBzdHJva2U6bm9uZTsiIGQ9Ik04MCAwTDgwIDEwTDkwIDEwTDkwIDBMODAgME0wIDIwTDAgNDBMMTAgNDBMMTAgMjBMMCAyME0yMCAyMEwyMCA4MEw4MCA4MEw4MCAyMEwyMCAyME05MCAyMEw5MCAzMEwxMDAgMzBMMTAwIDIwTDkwIDIweiI+PC9wYXRoPgo8cGF0aCBzdHlsZT0iZmlsbDojMDAwMDAwOyBzdHJva2U6bm9uZTsiIGQ9Ik00MCAzMEw0MCA0MEwzMCA0MEwzMCA1MEw1MCA1MEw1MCAzMEw0MCAzME02MCA0MEw2MCA1MEw3MCA1MEw3MCA0MEw2MCA0MHoiPjwvcGF0aD4KPHBhdGggc3R5bGU9ImZpbGw6I2ZmZmZmZjsgc3Ryb2tlOm5vbmU7IiBkPSJNOTAgNDBMOTAgNjBMMTAwIDYwTDEwMCA0MEw5MCA0ME0wIDYwTDAgNzBMMTAgNzBMMTAgNjBMMCA2MHoiPjwvcGF0aD4KPHBhdGggc3R5bGU9ImZpbGw6IzAwMDAwMDsgc3Ryb2tlOm5vbmU7IiBkPSJNNjAgNjBMNjAgNzBMNzAgNzBMNzAgNjBMNjAgNjB6Ij48L3BhdGg+CjxwYXRoIHN0eWxlPSJmaWxsOiNmZmZmZmY7IHN0cm9rZTpub25lOyIgZD0iTTUwIDkwTDUwIDEwMEw2MCAxMDBMNjAgOTBMNTAgOTBNNzAgOTBMNzAgMTAwTDkwIDEwMEw5MCA5MEw3MCA5MHoiPjwvcGF0aD4KPC9zdmc+" style="position: absolute;top: 0;right: 0; width: 30%; pointer-events:none" /> <button onClick="openFullscreen()">Fullscreen</button> <canvas id="body" style="width: 100%; height: 100%; border-style: solid;"></canvas> </body> <script> let el = document.getElementById("body"); let width = el.getBoundingClientRect().width; let height = el.getBoundingClientRect().height; const program = "tablet-touch-handler-" + ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)); function touch(event) { event.preventDefault(); for (let i = 0; i < event.targetTouches.length; i++) { send(`Commit {Claim ${program} has touch number ${i} with x ${event.targetTouches[i].screenX / width} and y ${event.targetTouches[i].screenY / height} }`); } } /* Get the documentElement (<html>) to display the page in fullscreen */ let elem = document.documentElement; /* View in fullscreen */ function openFullscreen() { if (elem.requestFullscreen) { elem.requestFullscreen(); } else if (elem.webkitRequestFullscreen) { /* Safari */ elem.webkitRequestFullscreen(); } else if (elem.msRequestFullscreen) { /* IE11 */ elem.msRequestFullscreen(); } } el.addEventListener("touchstart", touch, false); el.addEventListener("touchmove", touch, false); function stop_touch(event) { send(`Commit { Claim ${program} has no touch }`); } el.addEventListener("touchend", stop_touch, false); let ws; let send; function wsConnect() { ws = new WebSocket(window.location.origin.replace("http", "ws") + "/ws"); send = function(s) { ws.send(s); } ws.onopen = () => { document.getElementById('status').innerHTML = "<span style=background-color:seagreen;color:white;>Connnected</span>"; }; ws.onclose = window.onbeforeunload = () => { document.getElementById('status').innerHTML = "<span style=background-color:red;color:white;>Disconnnected</span>"; send(`Commit { Claim ${program} has no touch }`); setTimeout(() => { wsConnect(); }, 1000); }; ws.onerror = (err) => { document.getElementById('status').innerText = "Error"; console.error('Socket encountered error: ', err.message, 'Closing socket'); ws.close(); } ws.onmessage = (msg) => { if (msg.data.startsWith("Error:")) { const errorEl = document.getElementById("error"); if (msg.data === "Error:") { errorEl.style.backgroundColor = ""; errorEl.innerText = ""; } else { errorEl.style.backgroundColor = "#f55"; errorEl.innerText = msg.data; } } } }; wsConnect(); </script> </html> } } When tag 48712 has corners /corners/ { # Setting aside this tag space (48600 to 48713) for calibration. set tagCorners [lmap p $corners {::cameraToProjector $p}] set vecBottom [sub [lindex $tagCorners 1] [lindex $tagCorners 0]] set vecRight [sub [lindex $tagCorners 2] [lindex $tagCorners 1]] set offsets {{-4.7 -2.6} {1 -2.6} {1 0.8} {-4.7 0.8}} set scales [matmul $offsets [list $vecBottom $vecRight]] set corners [add $tagCorners $scales] set edges [list] for {set i 0} {$i < [llength $corners]} {incr i} { if {$i > 0} { lappend edges [list [expr {$i - 1}] $i] } } lappend edges [list [expr {[llength $corners] - 1}] 0] set angle [expr {atan2(-[lindex $vecBottom 1], [lindex $vecBottom 0])}] set region [region create $corners $edges $angle] Claim 48712 has region $region Claim tag 48712 is a tag Claim 48712 is a tablet }
Draw a little circle using touch!
When /thing/ claims /thing2/ has touch number /i/ with x /x/ and y /y/ { set posX [expr {int($Display::WIDTH * $x) % $Display::WIDTH}] set posY [expr {int($Display::HEIGHT * $y) % $Display::HEIGHT}] Wish to draw a circle with x $posX y $posY radius 20 thickness 6 color white }
Tablet pointer!
set MARGIN 0.2 set LENGTH 0.5 When /thing/ claims /thing2/ has touch number /i/ with x /x/ and y /y/ & 48712 has region /r/ { if {$x < $MARGIN && $y > $MARGIN && $y < [expr {1 - $MARGIN}] } { # left Wish 48712 points left with length $LENGTH } elseif {$x > [expr {1 - $MARGIN}] && $y > $MARGIN && $y < [expr {1 - $MARGIN}] } { # right Wish 48712 points right with length $LENGTH } elseif {$y > [expr {1 - $MARGIN}] } { # down Wish 48712 points down with length $LENGTH } elseif {$y < $MARGIN } { # up Wish 48712 points up with length $LENGTH } }
If you have Supercollider set up, play this little theremin!
# Supercollider touch demo When /thing/ claims /thing2/ has touch number /i/ with x /x/ and y /y/ { set freq [expr {int($Display::WIDTH * $x) % $Display::WIDTH} / 2.] Wish Supercollider sound $thing2-touch-noise attr freq is $freq Wish $this is labelled "$freq Hz" Wish Supercollider plays sound $thing2-touch-noise { arg freq = 0; var envgen; envgen = EnvGen.kr(Env.adsr(sustainLevel: 0.2)); Pan2.ar(SinOsc.ar(freq) * 0.5 * envgen, 1.0); } }
folkarc/touch.txt · Last modified: 2024/09/15 19:11 by discord