2016-03-30 3 views
1

У меня проблема с холстом, не регистрирующим события mousedown на планшете, я пробовал какое-то время, но ничего не работает, даже меняя мышь на touchstart в коде, реализации hammer.js, JQuery мобильный, любая помощь будет оценена, все работает на рабочем столе, просто не в ничего, что требует жестыСобытие mousedown, не стреляющее по планшету/мобильному телефону, HTML5 Canvas

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(); 

}

ответ

0

Я должен был сделать это в последнее время, так что вы может следовать по моим стопам здесь.

Чтобы получить игру работать на мобильных устройствах, вы должны следовать 2 шага:

  • A) Изменить все mousedown, mousemove и mouseup события в touchstart, touchmove и touchend (прямо замените их в Блокноте с помощью Найти & Заменить).
  • B) Заменить каждый экземпляр event.clientX и event.clientY со следующим:

clientX ↓

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

И clientY ↓

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

И снова, просто используйте Найти & Заменить.

Приведенные выше команды длинные/сложны, так какontouchend не содержит targetTouches объекта, и приведенные выше примеры могут быть сброшены в течение всех контекстов (touchstart, TouchMove, и touchend) через & Найти Замените и будете работать на все версии для Android.

Последнее, что вам нужно также положить в event.preventDefault() в самом конце каждого обработчика событий touchstart/touchmove, чтобы браузер не думал, что страница прокручивается.

Надеюсь, это поможет!

+0

Вслед вы все шаги к Т, по-прежнему не мог заставить его работать, не слишком уверен, куда я иду неправильно, это все еще работает со всеми изменениями на рабочем столе, просто не работая над планшетом/мобильным телефоном. –

+0

Добавьте функцию window.onerror = (a, b, c) {alert (a + b + c); } ', чтобы увидеть, происходят ли какие-либо ошибки на мобильных устройствах –

0

Мне удалось заставить это работать, застрял какой-то код в голове, чтобы обнаружить мобильный телефон и использовать сценарий жестов, а затем рабочий стол использует сценарий мыши, немного jerry-кода кода, но он работает, если кто-либо может помочь сделать это хорошо, пожалуйста, войти в контакт

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(); 
} 
} 
Смежные вопросы