User Tools

Site Tools


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

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki