neingeist
/
cosmos
Archived
1
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

206 lines
5.6 KiB
JavaScript

/*global Quintus:false */
Quintus.Touch = function(Q) {
if(Q._isUndefined(Quintus.Sprites)) {
throw "Quintus.Touch requires Quintus.Sprites Module";
}
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:1, h:1, cx: 0, cy: 0 };
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)) {
if(Q.touch.offsetX === void 0) {
Q.touch.offsetX = 0;
Q.touch.offsetY = 0;
var el = Q.el;
do {
Q.touch.offsetX += el.offsetLeft;
Q.touch.offsetY += el.offsetTop;
} while(el = el.offsetParent);
}
canvasPosX = touch.pageX - Q.touch.offsetX;
canvasPosY = touch.pageY - Q.touch.offsetY;
}
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;
this.touchPos.p.y = this.touchPos.p.py;
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.search(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 || Q.SPRITE_UI;
touchStage = stage || [2,1,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;
};
};