topical media & game development
mobile-game-present-lib-quintus-touch.js / js
/*global Quintus:false */
Quintus.Touch = function(Q) {
var hasTouch = !!('ontouchstart' in window);
var touchStage = [0];
var touchType = 0;
Q.Evented.extend("TouchSystem",{
init: function() {
var touchSystem = this;
this.boundTouch = function(e) { touchSystem.touch(e); };
this.boundDrag = function(e) { touchSystem.drag(e); };
this.boundEnd = function(e) { touchSystem.touchEnd(e); };
Q.el.addEventListener('touchstart',this.boundTouch);
Q.el.addEventListener('mousedown',this.boundTouch);
Q.el.addEventListener('touchmove',this.boundDrag);
Q.el.addEventListener('mousemove',this.boundDrag);
Q.el.addEventListener('touchend',this.boundEnd);
Q.el.addEventListener('mouseup',this.boundEnd);
Q.el.addEventListener('touchcancel',this.boundEnd);
this.touchPos = new Q.Evented();
this.touchPos.grid = {};
this.touchPos.p = { w:6, h:6, cx: 3, cy: 3 };
this.activeTouches = {};
this.touchedObjects = {};
},
destroy: function() {
Q.el.removeEventListener('touchstart',this.boundTouch);
Q.el.removeEventListener('mousedown',this.boundTouch);
Q.el.removeEventListener('touchmove',this.boundDrag);
Q.el.removeEventListener('mousemove',this.boundDrag);
Q.el.removeEventListener('touchend',this.boundEnd);
Q.el.removeEventListener('mouseup',this.boundEnd);
Q.el.removeEventListener('touchcancel',this.boundEnd);
},
normalizeTouch: function(touch,stage) {
var canvasPosX = touch.offsetX,
canvasPosY = touch.offsetY;
if(Q._isUndefined(canvasPosX) || Q._isUndefined(canvasPosY)) {
canvasPosX = touch.layerX;
canvasPosY = touch.layerY;
}
if(Q._isUndefined(canvasPosX) || Q._isUndefined(canvasPosY)) {
canvasPosX = touch.clientX - Q.el.offsetLeft - Q.wrapper.offsetLeft;
canvasPosY = touch.clientY - Q.el.offsetTop - Q.wrapper.offsetTop;
}
this.touchPos.p.ox = this.touchPos.p.px = canvasPosX / Q.cssWidth * Q.width;
this.touchPos.p.oy = this.touchPos.p.py = canvasPosY / Q.cssHeight * Q.height;
if(stage.viewport) {
this.touchPos.p.px /= stage.viewport.scale;
this.touchPos.p.py /= stage.viewport.scale;
this.touchPos.p.px += stage.viewport.x;
this.touchPos.p.py += stage.viewport.y;
}
this.touchPos.p.x = this.touchPos.p.px - 3;
this.touchPos.p.y = this.touchPos.p.py - 3;
this.touchPos.obj = null;
return this.touchPos;
},
touch: function(e) {
var touches = e.changedTouches || [ e ];
for(var i=0;i<touches.length;i++) {
for(var stageIdx=0;stageIdx < touchStage.length;stageIdx++) {
var touch = touches[i],
stage = Q.stage(touchStage[stageIdx]);
if(!stage) { continue; }
touch.identifier = touch.identifier || 0;
var pos = this.normalizeTouch(touch,stage);
stage.regrid(pos,true);
var col = stage.collide(pos,touchType), obj;
if(col || stageIdx === touchStage.length - 1) {
obj = col && col.obj;
pos.obj = obj;
this.trigger("touch",pos);
}
if(obj && !this.touchedObjects[obj]) {
this.activeTouches[touch.identifier] = {
x: pos.p.px,
y: pos.p.py,
origX: obj.p.x,
origY: obj.p.y,
sx: pos.p.ox,
sy: pos.p.oy,
identifier: touch.identifier,
obj: obj,
stage: stage
};
this.touchedObjects[obj.p.id] = true;
obj.trigger('touch', this.activeTouches[touch.identifier]);
break;
}
}
}
//e.preventDefault();
},
drag: function(e) {
var touches = e.changedTouches || [ e ];
for(var i=0;i<touches.length;i++) {
var touch = touches[i];
touch.identifier = touch.identifier || 0;
var active = this.activeTouches[touch.identifier],
stage = active && active.stage;
if(active) {
var pos = this.normalizeTouch(touch,stage);
active.x = pos.p.px;
active.y = pos.p.py;
active.dx = pos.p.ox - active.sx;
active.dy = pos.p.oy - active.sy;
active.obj.trigger('drag', active);
}
}
e.preventDefault();
},
touchEnd: function(e) {
var touches = e.changedTouches || [ e ];
for(var i=0;i<touches.length;i++) {
var touch = touches[i];
touch.identifier = touch.identifier || 0;
var active = this.activeTouches[touch.identifier];
if(active) {
active.obj.trigger('touchEnd', active);
delete this.touchedObjects[active.obj.p.id];
this.activeTouches[touch.identifier] = null;
}
}
e.preventDefault();
}
});
Q.touch = function(type,stage) {
Q.untouch();
touchType = type || null;
touchStage = stage || [0];
if(!Q._isArray(touchStage)) {
touchStage = [touchStage];
}
if(!Q._touch) {
Q.touchInput = new Q.TouchSystem();
}
return Q;
};
Q.untouch = function() {
if(Q.touchInput) {
Q.touchInput.destroy();
delete Q['touchInput'];
}
return Q;
};
};
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.