circles-following-touches.html [plain text]
<html>
<head>
<title>Debugging Multiple Touches and Events</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script type="text/javascript" charset="utf-8">
function init () {
document.body.addEventListener('touchstart', this, true);
window.addEventListener('touchmove', this, true);
window.addEventListener('touchend', this, true);
window.addEventListener('touchcancel', this, true);
}
function handleEvent (event) {
event.preventDefault();
event.stopPropagation();
updateTouchEventsCount(event);
updateBubbles(event);
}
function updateTouchEventsCount (event) {
if (event.type == 'touchmove') {
return;
}
var output = document.getElementById('number-of-' + event.type);
output.innerText = parseInt(output.innerText, 10) + event.changedTouches.length;
}
function addEventToSequenceLog (event) {
if (event.type == 'touchmove') {
return;
}
var msg = document.createElement('p');
msg.innerText = event.type;
var sequence = document.getElementById('sequence');
if (sequence.firstElementChild) {
sequence.insertBefore(msg, sequence.firstElementChild);
}
else {
sequence.appendChild(msg);
}
if (sequence.childElementCount > 25) {
sequence.removeChild(sequence.lastElementChild);
}
}
function updateBubbles (event) {
switch (event.type) {
case 'touchstart' :
this.touchesStarted(event);
break;
case 'touchmove' :
this.touchesMoved(event);
break;
case 'touchend' :
this.touchesEnded(event);
break;
case 'touchcancel' :
this.touchesCancelled(event);
break;
}
}
function randomColor () {
var components = new Array(3);
for (var i = 0; i < components.length; i++) {
components[i] = Math.round(Math.random() * 255);
}
return 'rgba(' + components.join(',') + ', 0.5)';
}
function touchesStarted (event) {
var touch, bubble;
for (var i = 0; i < event.changedTouches.length; i++) {
touch = event.changedTouches[i];
bubble = document.getElementById('bubbles').appendChild(document.createElement('div'));
bubble.className = 'bubble';
bubble.id = 'bubble-' + touch.identifier;
bubble.appendChild(document.createElement('span')).innerText = touch.identifier;
bubble.appendChild(document.createElement('div')).style.backgroundColor = randomColor();
bubble.style.webkitTransform = 'translate3d(' + touch.clientX + 'px, ' + touch.clientY + 'px, 0)';
}
}
function touchesMoved (event) {
var touch, bubble;
for (var i = 0; i < event.changedTouches.length; i++) {
touch = event.changedTouches[i];
bubble = document.getElementById('bubble-' + touch.identifier);
if (bubble) {
bubble.style.webkitTransform = 'translate3d(' + touch.clientX + 'px, ' + touch.clientY + 'px, 0)';
}
}
}
function touchesEnded (event) {
var touch, bubble;
for (var i = 0; i < event.changedTouches.length; i++) {
bubble = document.getElementById('bubble-' + event.changedTouches[i].identifier);
if (bubble) {
document.getElementById('bubbles').removeChild(bubble);
}
}
}
function touchesCancelled (event) {
console.log(event.changedTouches.length)
var touch, bubble;
for (var i = 0; i < event.changedTouches.length; i++) {
bubble = document.getElementById('bubble-' + event.changedTouches[i].identifier);
if (bubble) {
document.getElementById('bubbles').removeChild(bubble);
}
}
}
function listBubbles () {
}
window.addEventListener('DOMContentLoaded', init, false);
</script>
<style type="text/css" media="screen">
body {
font-family: 'Helvetica';
}
body > * {
-webkit-transform: translateZ(0);
}
.bubble {
position: absolute;
top: 0;
left: 0;
z-index: 0;
-webkit-transform: translateZ(0);
}
.bubble > span {
display: block;
position: absolute;
top: -20px;
left: 60px;
font-weight: bold;
font-size: 24px;
}
.bubble > div {
display: block;
position: absolute;
left: -50px;
top: -50px;
border-radius: 50px;
width: 100px;
height: 100px;
}
#log {
position: absolute;
top: 0;
left: 0;
background-color: rgba(0,0,0,0.25);
width: 160px;
height: 100%;
z-index: 1;
padding: 10px;
-webkit-box-sizing: border-box;
}
#sequence > p {
margin: 0;
}
#number-of-touchstart:before {
content: 'touchstart: ';
}
#number-of-touchend:before {
content: 'touchend: ';
}
#number-of-touchcancel:before {
content: 'touchcancel: ';
}
</style>
</head>
<body>
<div id="bubbles"></div>
<div id="log">
<div>Changed Touches</div>
<div id="number-of-touchstart">0</div>
<div id="number-of-touchend">0</div>
<div id="number-of-touchcancel">0</div>
<hr>
<div id="sequence"></div>
</div>
</body>
</html>