Skip to content Skip to sidebar Skip to footer

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"