Multi-touch For HTML5 Canvas
I am creating a musical instrument with HTML5 canvas and I have problem integrating multi-touch functionality into my code. I want to make it so that users will be able to play mor
Solution 1:
To support some kind of muli-touch feature, you have to handle the touch events touchstart touchmove touchend touchcancel
(and pointer events if you want to support IE). The touch events have a changedTouches
property. Read added or removed touches from this property and store that information.
function touchStart(evt) {
var changedTouches = evt.changedTouches;
for (var i = 0; i < changedTouches.length; i++) {
// remember new touches and its key
var key = changedTouches[i].target;
touches.push({ id : changedTouches[i].identifier, key: key });
}
updateKeys();
}
function touchEnd(evt) {
var changedTouches = evt.changedTouches;
for (var i = 0; i < changedTouches.length; i++) {
// Remove this touch
var index = getTouchIndex(changedTouches[i].identifier);
if (index >= 0) {
touches.splice(index, 1);
}
}
updateKeys();
}
The tricky event is touchmove
, since the event target is still the target of the corresponding touchstart
event. In your case, you have to calculate the next piano key, when a finger moves from one key to another.
function touchMove(evt) {
var changedTouches = evt.changedTouches;
for (var i = 0; i < changedTouches.length; i++) {
var touch = changedTouches[i];
var index = getTouchIndex(touch.identifier);
if (index >= 0) {
// Update stored key to the new key
var key = document.elementFromPoint(touch.pageX, touch.pageY);
if (isKey(key))
touches[index].key = key;
}
}
updateKeys();
}
The piano example:
var keys = [].slice.call(document.querySelectorAll('.key'), 0);
var keyboard = document.getElementById('keyboard');
var touches = [];
keyboard.addEventListener("touchstart", touchStart, false);
keyboard.addEventListener("touchmove", touchMove, false);
keyboard.addEventListener("touchend", touchEnd, false);
function isKey(key) {
return keys.indexOf(key) >= 0;
}
function updateKeys() {
keys.forEach(function(key) {
key.classList.remove("down");
});
touches.forEach(function(touch) {
if (isKey(touch.key))
touch.key.classList.add("down");
});
}
function touchStart(evt) {
evt.preventDefault();
var changedTouches = evt.changedTouches;
for (var i = 0; i < changedTouches.length; i++) {
var key = changedTouches[i].target;
touches.push({ id : changedTouches[i].identifier, key: key });
}
updateKeys();
}
function touchEnd(evt) {
evt.preventDefault();
var changedTouches = evt.changedTouches;
for (var i = 0; i < changedTouches.length; i++) {
var index = getTouchIndex(changedTouches[i].identifier);
if (index >= 0) {
touches.splice(index, 1);
}
}
updateKeys();
}
function touchMove(evt) {
evt.preventDefault();
var changedTouches = evt.changedTouches;
for (var i = 0; i < changedTouches.length; i++) {
var touch = changedTouches[i];
var index = getTouchIndex(touch.identifier);
if (index >= 0) {
var key = document.elementFromPoint(touch.pageX, touch.pageY);
if (isKey(key))
touches[index].key = key;
}
}
updateKeys();
}
function getTouchIndex(id) {
for (var i = 0; i < touches.length; i++) {
if (touches[i].id === id) {
return i;
}
}
return -1;
}
#keyboard {
background:#333;
padding:10px;
}
.key {
height:150px;
width:35px;
display:inline-block;
background: #aee;
}
.key.down {
background: #aae;
}
<div id="keyboard">
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
<div class="key"></div>
</div>
Post a Comment for "Multi-touch For HTML5 Canvas"