David Nesbitt
David Nesbitt

Reputation: 61

mousedown event not firing on tablet / mobile, HTML5 Canvas

I am having an issue with canvas not registering mousedown events on tablet, I have been trying for a while but nothing is working, even changing the mousedown to touchstart in the code, implementing hammer.js, jquery mobile, any help would be appreciated, everything works on desktop, just not an anything that requires touch gestures

var gestures = function(config){

var conf = {
    debug: true,
    draw: true,
    drawColor: "##f8f07e",
    drawWidth: 5,
    autoTrack: true,
    allowRotation: true,
    inverseShape: true,
    points: 33
};

var d;
var ctx;
var tracking = false;
var ob = this;

this.gestures = [];
this.points = [];

this.construct = function(){
    d = doc_size();
    //copying configuration
    for(var opt in config){
        conf[opt] = config[opt];
    }

    if(document.getElementById("gestures_canvas"))
    {
        ctx = document.getElementById("gestures_canvas").getContext("2d");
    }
    else if(conf.draw)
    {
        //create canvas for drawing

        var canvas = document.createElement("canvas");
        canvas.setAttribute("width", d.width + "px");
        canvas.setAttribute("height", d.height + "px");
        canvas.style.position = "fixed";
        canvas.style.top = "0px";
        canvas.style.left = "0px";
        canvas.id = "gestures_canvas";
        ctx = canvas.getContext("2d");
        document.body.appendChild(canvas);
    }
    if(conf.autoTrack || conf.draw)
    {
        add_event(document.body, "mousedown", this.Down);
        add_event(document.body, "mouseup", this.Up);




        tracking = true;
    }

    this.reset();
};




this.pauseTracking = function(){
    tracking = false;
};

this.resumeTracking = function(){
    tracking = true;
};

this.addGesture = function(name, points, callback){
    if(conf.inverseShape){
        var inverse = [];
        for(var i = points.length-1; i >= 0; i--)
        {
            inverse.push(points[i]);
        }
        var gesture = {};
        gesture.name = name;
        gesture.callback = callback;
        var map = resample(inverse, inverse.length, conf);

        gesture.map = vectorize(map, conf.allowRotation);
        this.gestures.push(gesture);

    }

    var gesture = {};
    gesture.name = name;
    gesture.callback = callback;
    var map = resample(points, points.length, conf);
    gesture.map = vectorize(map, conf.allowRotation);
    this.gestures.push(gesture);
};

this.resolve = function(points){

    if(points.length > 1)
    {
        this.reset();
        var map = resample(points, points.length, conf);

        var ivect = vectorize(map, conf.allowRotation);

        var maxScore = 0;
        var match = "none";
        for(var i = 0; i < this.gestures.length; i++)
        {
            var dist = optCosDist(this.gestures[i].map, ivect);
            var score = 1/dist;

            if(score > maxScore)
            {
                maxScore = score;
                match = this.gestures[i];
            }
        }
        if(match.callback)
        {
            match.callback(match.name);
        }
    }
};

this.reset = function(){
    this.points = [];
};

this.clear = function(){
    ctx.clearRect(0, 0, d.width, d.height);
};

//gesture auto tracking
//mouse down
this.Down = function(event){
    ob.reset();
    if(conf.draw)
    {
        ctx.clearRect(0, 0, d.width, d.height);
        ctx.lineWidth = conf.drawWidth;
        ctx.strokeStyle = conf.drawColor;
        ctx.lastX = event.clientX;
        ctx.lastY = event.clientY;
    }
    if(conf.autoTrack && tracking)
    {
        var point = {};
        point.x = event.clientX;
        point.y = event.clientY;
        ob.points.push(point);
    }
    add_event(document.body, "mousedown", ob.Move);
};

//mouse move
this.Move = function(event){
    if(conf.draw)
    {
        ctx.beginPath();
        ctx.moveTo(ctx.lastX, ctx.lastY);
        ctx.lineTo(event.clientX, event.clientY);
        ctx.stroke();
        ctx.lastX = event.clientX;
        ctx.lastY = event.clientY;
    }
    if(conf.autoTrack && tracking)
    {
        var point = {};
        point.x = event.clientX;
        point.y = event.clientY;
        ob.points.push(point);
    }
};
//mouse up
this.Up = function(event){
    if(conf.autoTrack && tracking)
    {
        ob.resolve(ob.points);
    }
    remove_event(document.body, "mousemove", ob.Move);
};


//some helping internal functions

var optCosDist = function(gestureV, inputV){
    var a = 0;
    var b = 0;

    for(i = 0; i < gestureV.length; i += 2)
    {
        a = a + gestureV[i]*inputV[i] + gestureV[i+1]*inputV[i+1];
        b = b + gestureV[i]*inputV[i+1] - gestureV[i+1]*inputV[i];
    }
    var angle = Math.atan2(b,a);

    return Math.acos(a*Math.cos(angle) + b*Math.sin(angle));
};

//distance [PROTRACTOR]
var Distance = function(u, v){
    var x = (u.x - v.x);
    var y = (u.y - v.y);
    return Math.sqrt((x*x)+(y*y));
};

var pathLength = function(points, n){
    var distance = 0;
    for(i = 1; i < n; i++)
    {
        distance = distance + Distance(points[i-1], points[i]);
    }
    return distance;
};

var resample = function(points, n){
    var subLength = pathLength(points, n)/(conf.points-1);
    var distance = 0;
    var newpoints = [];
    var elem ={};
    elem.x = points[0].x;
    elem.y = points[0].y;
    newpoints.push(elem);

    var i = 1;
    while (i < points.length && newpoints.length < (conf.points-1))
    {
        var subdist = Distance(points[i-1], points[i]);
        if((distance + subdist) >= subLength)
        {
            var elem2 = {};
            elem2.x = points[i-1].x + ((subLength - distance)/subdist)*(points[i].x - points[i-1].x);
            elem2.y = points[i-1].y + ((subLength - distance)/subdist)*(points[i].y - points[i-1].y);
            //add point
            newpoints.push(elem2);
            points.splice(i,0,elem2);
            distance = 0;
        }
        else
        {
            distance = distance + subdist;
        }
        i = i + 1;
    }
    var elem3 = {};
    //adding last point
    elem3.x = points[points.length-1].x;
    elem3.y = points[points.length-1].y;
    newpoints.push(elem3);

    return newpoints;
};

var centroid = function(points){
    var center = {};
    center.x = 0;
    center.y = 0;

    for(i = 0; i < points.length; i++)
    {
        center.x = center.x + points[i].x;
        center.y = center.y + points[i].y;
    }
    center.x = center.x/(points.length-1);
    center.y = center.y/(points.length-1);
    return center;
};

var translate = function(points,center){
    for(var i = 0; i < points.length; i++)
    {
        points[i].x = points[i].x - center.x;
        points[i].y = points[i].y - center.y;
    }
    return points;
};

var vectorize = function(points, sensit){
    var vector = [];

    var center = centroid(points);
    var points = translate(points, center);

    var lenkis = Math.atan2(points[1].x, points[1].y);
    var delta = lenkis;
    if(sensit)
    {
        var base = (Math.PI/4)*Math.floor((lenkis+(Math.PI/8))*(4/Math.PI));
        delta = base-lenkis;
    }
    var summa = 0;
    for(var i = 0; i < points.length; i++)
    {
        var newx = points[i].x*Math.cos(delta) - points[i].y*Math.sin(delta);
        var newy = points[i].x*Math.sin(delta) + points[i].y*Math.cos(delta);
        vector.push(newx);
        vector.push(newy);
        summa = summa + newx*newx + newy*newy;
    }

    var magnitude = Math.sqrt(summa);
    for(var i = 0; i < vector.length; i++)
    {
        vector[i] = vector[i]/magnitude;
    }
    return vector;
};

//get document dimensions
var doc_size = function(){
    var docsize = new Object();
    docsize.width = 0;
    docsize.height = 0;
    docsize.width = Math.max(
        Math.max(document.body.scrollWidth, document.documentElement.scrollWidth),
        Math.max(document.body.offsetWidth, document.documentElement.offsetWidth),
        Math.max(document.body.clientWidth, document.documentElement.clientWidth)
    );
    docsize.height = Math.max(
        Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
        Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
        Math.max(document.body.clientHeight, document.documentElement.clientHeight)
    );
    return docsize;
};

//add event
var add_event = function(element, type, listener){
    if(element.addEventListener)
    {
        element.addEventListener(type, listener, false);
    }
    else
    {
        element.attachEvent('on' +  type, listener);
    }
};

//remove event
var remove_event = function(element, type, listener){
    if(element.removeEventListener)
        element.removeEventListener(type, listener, false);
    else
        element.detachEvent('on' +  type, listener);
};

this.construct();

}

Upvotes: 5

Views: 9764

Answers (2)

David Nesbitt
David Nesbitt

Reputation: 61

I managed to get this to work, stuck some code in the head to detect mobile and use the gesture script, and then the desktop uses the mouse script, a bit of a jerry rig of code but it works, if anyone can help make it nice please get in contact

if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) 
|| /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))){ isMobile = true;}

----------end of head code---------------

 if(isMobile==true){
var gestures = function(config){
var conf = {
    debug: true,
    draw: true,
    drawColor: "#000000",
    drawWidth: 5,
    autoTrack: true,
    allowRotation: true,
    inverseShape: true,
    points: 33
};

var d;
var ctx;
var tracking = false;
var ob = this;

this.gestures = [];
this.points = [];

this.construct = function(){
    d = doc_size();
    //copying configuration
    for(var opt in config){
        conf[opt] = config[opt];
    }

    if(document.getElementById("gestures_canvas"))
    {
        ctx = document.getElementById("gestures_canvas").getContext("2d");
    }
    else if(conf.draw)
    {
        //create canvas for drawing
        var canvas = document.createElement("canvas");
        canvas.setAttribute("width", d.width + "px");
        canvas.setAttribute("height", d.height + "px");
        canvas.style.position = "absolute";
        canvas.style.top = "0px";
        canvas.style.left = "0px";
        canvas.id = "gestures_canvas";
        ctx = canvas.getContext("2d");
        document.body.appendChild(canvas);
    }
    if(conf.autoTrack || conf.draw)
    {
        add_event(document.body, "touchstart", this.Down);
        add_event(document.body, "touchend", this.Up);
        tracking = true;
    }

    this.reset();
};

this.pauseTracking = function(){
    tracking = false;
};

this.resumeTracking = function(){
    tracking = true;
};

this.addGesture = function(name, points, callback){
    if(conf.inverseShape){
        var inverse = [];
        for(var i = points.length-1; i >= 0; i--)
        {
            inverse.push(points[i]);
        }
        var gesture = {};
        gesture.name = name;
        gesture.callback = callback;
        var map = resample(inverse, inverse.length, conf);

        gesture.map = vectorize(map, conf.allowRotation);
        this.gestures.push(gesture);

    }

    var gesture = {};
    gesture.name = name;
    gesture.callback = callback;
    var map = resample(points, points.length, conf);
    gesture.map = vectorize(map, conf.allowRotation);
    this.gestures.push(gesture);
};

this.resolve = function(points){

    if(points.length > 1)
    {
        this.reset();
        var map = resample(points, points.length, conf);

        var ivect = vectorize(map, conf.allowRotation);

        var maxScore = 0;
        var match = "none";
        for(var i = 0; i < this.gestures.length; i++)
        {
            var dist = optCosDist(this.gestures[i].map, ivect);
            var score = 1/dist;

            if(score > maxScore)
            {
                maxScore = score;
                match = this.gestures[i];
            }
        }
        if(match.callback)
        {
            match.callback(match.name);
        }
    }
};

this.reset = function(){
    this.points = [];
};

this.clear = function(){
    ctx.clearRect(0, 0, d.width, d.height);
};

//gesture auto tracking
//mouse down
this.Down = function(event){
    ob.reset();
    if(conf.draw)
    {
        ctx.clearRect(0, 0, d.width, d.height);
        ctx.lineWidth = conf.drawWidth;
        ctx.strokeStyle = conf.drawColor;
        ctx.lastX = (event.targetTouches[0] ? event.targetTouches[0].pageX :        event.changedTouches[event.changedTouches.length-1].pageX)
;ctx.lastY = (event.targetTouches[0] ? event.targetTouches[0].pageY :     event.changedTouches[event.changedTouches.length-1].pageY)
;
    }
    if(conf.autoTrack && tracking)
    {
        var point = {};
        point.x = (event.targetTouches[0] ? event.targetTouches[0].pageX : event.changedTouches[event.changedTouches.length-1].pageX)
;
        point.y = (event.targetTouches[0] ? event.targetTouches[0].pageY : event.changedTouches[event.changedTouches.length-1].pageY)
;
        ob.points.push(point);
    }
    add_event(document.body, "touchmove", ob.Move);
};

//mouse move
this.Move = function(event){
    if(conf.draw)
    {
        ctx.beginPath();
        ctx.moveTo(ctx.lastX, ctx.lastY);
        ctx.lineTo((event.targetTouches[0] ? event.targetTouches[0].pageX :     event.changedTouches[event.changedTouches.length-1].pageX)
, (event.targetTouches[0] ? event.targetTouches[0].pageY : event.changedTouches[event.changedTouches.length-1].pageY)
);
            ctx.stroke();
        ctx.lastX = (event.targetTouches[0] ? event.targetTouches[0].pageX : event.changedTouches[event.changedTouches.length-1].pageX)
;
        ctx.lastY = (event.targetTouches[0] ? event.targetTouches[0].pageY : event.changedTouches[event.changedTouches.length-1].pageY)
;
    }
    if(conf.autoTrack && tracking)
    {
        var point = {};
        point.x = (event.targetTouches[0] ? event.targetTouches[0].pageX : event.changedTouches[event.changedTouches.length-1].pageX)
;
        point.y = (event.targetTouches[0] ? event.targetTouches[0].pageY : event.changedTouches[event.changedTouches.length-1].pageY)
  ;
        ob.points.push(point);
    }
};
//mouse up
this.Up = function(event){
    if(conf.autoTrack && tracking)
    {
        ob.resolve(ob.points);
    }
    remove_event(document.body, "touchmove", ob.Move);
};


//some helping internal functions

var optCosDist = function(gestureV, inputV){
    var a = 0;
    var b = 0;

    for(i = 0; i < gestureV.length; i += 2)
    {
        a = a + gestureV[i]*inputV[i] + gestureV[i+1]*inputV[i+1];
        b = b + gestureV[i]*inputV[i+1] - gestureV[i+1]*inputV[i];
    }
    var angle = Math.atan2(b,a);

    return Math.acos(a*Math.cos(angle) + b*Math.sin(angle));
};

//distance [PROTRACTOR]
var Distance = function(u, v){
    var x = (u.x - v.x);
    var y = (u.y - v.y);
    return Math.sqrt((x*x)+(y*y));
};

var pathLength = function(points, n){
    var distance = 0;
    for(i = 1; i < n; i++)
    {
        distance = distance + Distance(points[i-1], points[i]);
    }
    return distance;
};

var resample = function(points, n){
    var subLength = pathLength(points, n)/(conf.points-1);
    var distance = 0;
    var newpoints = [];
    var elem ={};
    elem.x = points[0].x;
    elem.y = points[0].y;
    newpoints.push(elem);

    var i = 1;
    while (i < points.length && newpoints.length < (conf.points-1))
    {
        var subdist = Distance(points[i-1], points[i]);
        if((distance + subdist) >= subLength)
        {
            var elem2 = {};
            elem2.x = points[i-1].x + ((subLength - distance)/subdist)*(points[i].x - points[i-1].x);
            elem2.y = points[i-1].y + ((subLength - distance)/subdist)*(points[i].y - points[i-1].y);
            //add point
            newpoints.push(elem2);
            points.splice(i,0,elem2);
            distance = 0;
        }
        else
        {
            distance = distance + subdist;
        }
        i = i + 1;
    }
    var elem3 = {};
    //adding last point
    elem3.x = points[points.length-1].x;
    elem3.y = points[points.length-1].y;
    newpoints.push(elem3);

    return newpoints;
};

var centroid = function(points){
    var center = {};
    center.x = 0;
    center.y = 0;

    for(i = 0; i < points.length; i++)
    {
        center.x = center.x + points[i].x;
        center.y = center.y + points[i].y;
    }
    center.x = center.x/(points.length-1);
    center.y = center.y/(points.length-1);
    return center;
};

var translate = function(points,center){
    for(var i = 0; i < points.length; i++)
    {
        points[i].x = points[i].x - center.x;
        points[i].y = points[i].y - center.y;
    }
    return points;
};

var vectorize = function(points, sensit){
    var vector = [];

    var center = centroid(points);
    var points = translate(points, center);

    var lenkis = Math.atan2(points[1].x, points[1].y);
    var delta = lenkis;
    if(sensit)
    {
        var base = (Math.PI/4)*Math.floor((lenkis+(Math.PI/8))*(4/Math.PI));
        delta = base-lenkis;
    }
    var summa = 0;
    for(var i = 0; i < points.length; i++)
    {
        var newx = points[i].x*Math.cos(delta) - points[i].y*Math.sin(delta);
        var newy = points[i].x*Math.sin(delta) + points[i].y*Math.cos(delta);
        vector.push(newx);
        vector.push(newy);
        summa = summa + newx*newx + newy*newy;
    }

    var magnitude = Math.sqrt(summa);
    for(var i = 0; i < vector.length; i++)
    {
        vector[i] = vector[i]/magnitude;
    }
    return vector;
};

//get document dimensions
var doc_size = function(){
    var docsize = new Object();
    docsize.width = 0;
    docsize.height = 0;
    docsize.width = Math.max(
        Math.max(document.body.scrollWidth, document.documentElement.scrollWidth),
        Math.max(document.body.offsetWidth, document.documentElement.offsetWidth),
        Math.max(document.body.clientWidth, document.documentElement.clientWidth)
    );
    docsize.height = Math.max(
        Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
        Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
        Math.max(document.body.clientHeight, document.documentElement.clientHeight)
    );
    return docsize;
};

//add event
var add_event = function(element, type, listener){
    if(element.addEventListener)
    {
        element.addEventListener(type, listener, false);
    }
    else
    {
        element.attachEvent('on' +  type, listener);
    }
};

//remove event
var remove_event = function(element, type, listener){
    if(element.removeEventListener)
        element.removeEventListener(type, listener, false);
    else
        element.detachEvent('on' +  type, listener);
};

this.construct();
}
} else { 
var gestures = function(config){

var conf = {
    debug: true,
    draw: true,
    drawColor: "#000000",
    drawWidth: 5,
    autoTrack: true,
    allowRotation: true,
    inverseShape: true,
    points: 33
};

var d;
var ctx;
var tracking = false;
var ob = this;

this.gestures = [];
this.points = [];

this.construct = function(){
    d = doc_size();
    //copying configuration
    for(var opt in config){
        conf[opt] = config[opt];
    }

    if(document.getElementById("gestures_canvas"))
    {
        ctx = document.getElementById("gestures_canvas").getContext("2d");
    }
    else if(conf.draw)
    {
        //create canvas for drawing
        var canvas = document.createElement("canvas");
        canvas.setAttribute("width", d.width + "px");
        canvas.setAttribute("height", d.height + "px");
        canvas.style.position = "absolute";
        canvas.style.top = "0px";
        canvas.style.left = "0px";
        canvas.id = "gestures_canvas";
        ctx = canvas.getContext("2d");
        document.body.appendChild(canvas);
    }
    if(conf.autoTrack || conf.draw)
    {
        add_event(document.body, "mousedown", this.Down);
        add_event(document.body, "mouseup", this.Up);
        tracking = true;
    }

    this.reset();
};

this.pauseTracking = function(){
    tracking = false;
};

this.resumeTracking = function(){
    tracking = true;
};

this.addGesture = function(name, points, callback){
    if(conf.inverseShape){
        var inverse = [];
        for(var i = points.length-1; i >= 0; i--)
        {
            inverse.push(points[i]);
        }
        var gesture = {};
        gesture.name = name;
        gesture.callback = callback;
        var map = resample(inverse, inverse.length, conf);

        gesture.map = vectorize(map, conf.allowRotation);
        this.gestures.push(gesture);

    }

    var gesture = {};
    gesture.name = name;
    gesture.callback = callback;
    var map = resample(points, points.length, conf);
    gesture.map = vectorize(map, conf.allowRotation);
    this.gestures.push(gesture);
};

this.resolve = function(points){

    if(points.length > 1)
    {
        this.reset();
        var map = resample(points, points.length, conf);

        var ivect = vectorize(map, conf.allowRotation);

        var maxScore = 0;
        var match = "none";
        for(var i = 0; i < this.gestures.length; i++)
        {
            var dist = optCosDist(this.gestures[i].map, ivect);
            var score = 1/dist;

            if(score > maxScore)
            {
                maxScore = score;
                match = this.gestures[i];
            }
        }
        if(match.callback)
        {
            match.callback(match.name);
        }
    }
};

this.reset = function(){
    this.points = [];
};

this.clear = function(){
    ctx.clearRect(0, 0, d.width, d.height);
};

//gesture auto tracking
//mouse down
this.Down = function(event){
    ob.reset();
    if(conf.draw)
    {
        ctx.clearRect(0, 0, d.width, d.height);
        ctx.lineWidth = conf.drawWidth;
        ctx.strokeStyle = conf.drawColor;
        ctx.lastX = event.clientX;
        ctx.lastY = event.clientY;
    }
    if(conf.autoTrack && tracking)
    {
        var point = {};
        point.x = event.clientX;
        point.y = event.clientY;
        ob.points.push(point);
    }
    add_event(document.body, "mousemove", ob.Move);
};

//mouse move
this.Move = function(event){
    if(conf.draw)
    {
        ctx.beginPath();
        ctx.moveTo(ctx.lastX, ctx.lastY);
        ctx.lineTo(event.clientX, event.clientY);
        ctx.stroke();
        ctx.lastX = event.clientX;
        ctx.lastY = event.clientY;
    }
    if(conf.autoTrack && tracking)
    {
        var point = {};
        point.x = event.clientX;
        point.y = event.clientY;
        ob.points.push(point);
    }
};
//mouse up
this.Up = function(event){
    if(conf.autoTrack && tracking)
    {
        ob.resolve(ob.points);
    }
    remove_event(document.body, "mousemove", ob.Move);
};


//some helping internal functions

var optCosDist = function(gestureV, inputV){
    var a = 0;
    var b = 0;

    for(i = 0; i < gestureV.length; i += 2)
    {
        a = a + gestureV[i]*inputV[i] + gestureV[i+1]*inputV[i+1];
        b = b + gestureV[i]*inputV[i+1] - gestureV[i+1]*inputV[i];
    }
    var angle = Math.atan2(b,a);

    return Math.acos(a*Math.cos(angle) + b*Math.sin(angle));
};

//distance [PROTRACTOR]
var Distance = function(u, v){
    var x = (u.x - v.x);
    var y = (u.y - v.y);
    return Math.sqrt((x*x)+(y*y));
};

var pathLength = function(points, n){
    var distance = 0;
    for(i = 1; i < n; i++)
    {
        distance = distance + Distance(points[i-1], points[i]);
    }
    return distance;
};

var resample = function(points, n){
    var subLength = pathLength(points, n)/(conf.points-1);
    var distance = 0;
    var newpoints = [];
    var elem ={};
    elem.x = points[0].x;
    elem.y = points[0].y;
    newpoints.push(elem);

    var i = 1;
    while (i < points.length && newpoints.length < (conf.points-1))
    {
        var subdist = Distance(points[i-1], points[i]);
        if((distance + subdist) >= subLength)
        {
            var elem2 = {};
            elem2.x = points[i-1].x + ((subLength - distance)/subdist)*(points[i].x - points[i-1].x);
            elem2.y = points[i-1].y + ((subLength - distance)/subdist)*(points[i].y - points[i-1].y);
            //add point
            newpoints.push(elem2);
            points.splice(i,0,elem2);
            distance = 0;
        }
        else
        {
            distance = distance + subdist;
        }
        i = i + 1;
    }
    var elem3 = {};
    //adding last point
    elem3.x = points[points.length-1].x;
    elem3.y = points[points.length-1].y;
    newpoints.push(elem3);

    return newpoints;
};

var centroid = function(points){
    var center = {};
    center.x = 0;
    center.y = 0;

    for(i = 0; i < points.length; i++)
    {
        center.x = center.x + points[i].x;
        center.y = center.y + points[i].y;
    }
    center.x = center.x/(points.length-1);
    center.y = center.y/(points.length-1);
    return center;
};

var translate = function(points,center){
    for(var i = 0; i < points.length; i++)
    {
        points[i].x = points[i].x - center.x;
        points[i].y = points[i].y - center.y;
    }
    return points;
};

var vectorize = function(points, sensit){
    var vector = [];

    var center = centroid(points);
    var points = translate(points, center);

    var lenkis = Math.atan2(points[1].x, points[1].y);
    var delta = lenkis;
    if(sensit)
    {
        var base = (Math.PI/4)*Math.floor((lenkis+(Math.PI/8))*(4/Math.PI));
        delta = base-lenkis;
    }
    var summa = 0;
    for(var i = 0; i < points.length; i++)
    {
        var newx = points[i].x*Math.cos(delta) - points[i].y*Math.sin(delta);
        var newy = points[i].x*Math.sin(delta) + points[i].y*Math.cos(delta);
        vector.push(newx);
        vector.push(newy);
        summa = summa + newx*newx + newy*newy;
    }

    var magnitude = Math.sqrt(summa);
    for(var i = 0; i < vector.length; i++)
    {
        vector[i] = vector[i]/magnitude;
    }
    return vector;
};

//get document dimensions
var doc_size = function(){
    var docsize = new Object();
    docsize.width = 0;
    docsize.height = 0;
    docsize.width = Math.max(
        Math.max(document.body.scrollWidth, document.documentElement.scrollWidth),
        Math.max(document.body.offsetWidth, document.documentElement.offsetWidth),
        Math.max(document.body.clientWidth, document.documentElement.clientWidth)
    );
    docsize.height = Math.max(
        Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
        Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
        Math.max(document.body.clientHeight, document.documentElement.clientHeight)
    );
    return docsize;
};

//add event
var add_event = function(element, type, listener){
    if(element.addEventListener)
    {
        element.addEventListener(type, listener, false);
    }
    else
    {
        element.attachEvent('on' +  type, listener);
    }
};

//remove event
var remove_event = function(element, type, listener){
    if(element.removeEventListener)
        element.removeEventListener(type, listener, false);
    else
        element.detachEvent('on' +  type, listener);
};

this.construct();
}
}

Upvotes: 1

Aaron Gillion
Aaron Gillion

Reputation: 2265

I've had to do this recently, so you can follow in my footsteps here.

To get your game working on mobile devices, you'll have to follow 2 steps:

  • A) Change all mousedown, mousemove, and mouseup events to touchstart, touchmove, and touchend (straight-up replace them in Notepad via Find & Replace).
  • B) Replace every instance of event.clientX and event.clientY with the following:

clientX ↓

(event.targetTouches[0] ? event.targetTouches[0].pageX : event.changedTouches[event.changedTouches.length-1].pageX)

And clientY ↓

(event.targetTouches[0] ? event.targetTouches[0].pageY : event.changedTouches[event.changedTouches.length-1].pageY)

And again, just use Find & Replace.

The above commands are long/complicated, because ontouchend doesn't contain a targetTouches object, and the above examples can be dropped in for all contexts (touchstart, touchmove, and touchend) via Find & Replace and will work on all Android versions.

One last thing, you may also have to put in event.preventDefault() at the very end of each touchstart/touchmove event handler to prevent the mobile browser from thinking the page is scrolling.

Hope this helps!

Upvotes: 9

Related Questions