2012-09-09 50 views
5

關於如何獲取Canvas元素上相對於Canvas本身的事件座標,在這裏有很多答案,在stackoverflow上。我使用下述溶液(getEventPosition),並從工作得很好,除了我添加邊框到我的畫布:查找具有邊框的HTML5 Canvas(點擊)事件的座標

/**** This solution gives me an offset equal to the border size 
**** when the canvas has a border. Example: 
**** <canvas style='border: 10px solid black; background: #333;' id='gauge_canvas' width='500' height='500'></canvas> 
****/ 

// Get DOM element position on page 
this.getPosition = function(obj) { 
    var x = 0, y = 0; 
    if (obj.offsetParent) { 
     do { 
      x += obj.offsetLeft; 
      y += obj.offsetTop; 
      obj = obj.offsetParent; 
     } while (obj); 
    } 
    return {'x': x, 'y': y}; 
}; 

// Get mouse event position in DOM element (don't know how to use scale yet). 
this.getEventPosition = function(e, obj, aux_e, scale) { 

    var evt, docX, docY, pos; 

    evt = (e ? e : window.event); 
    if (evt.pageX || evt.pageY) { 
     docX = evt.pageX; 
     docY = evt.pageY; 
    } else if (evt.clientX || evt.clientY) { 
     docX = evt.clientX + document.body.scrollLeft + 
      document.documentElement.scrollLeft; 
     docY = evt.clientY + document.body.scrollTop + 
      document.documentElement.scrollTop; 
    } 
    // This works on hammer.js 
    else if (typeof aux_e !== 'undefined') { 
     docX = aux_e.touches[0].x; 
     docY = aux_e.touches[0].y; 
    } 
    pos = this.getPosition(obj); 
    if (typeof scale === 'undefined') { 
     scale = 1; 
    } 
    return {'x': (docX - pos.x)/scale, 'y': (docY - pos.y)/scale}; 
}; 

由於該代碼屬於我的圖書館,可以採取任何canvas元素的用戶當用戶給圖書館一個邊框畫布時,事情就會分崩離析。有沒有解決邊界問題的解決方案?

回答

3

這是我一直在使用什麼我的最新實驗。

http://jsfiddle.net/simonsarris/te8GQ/5/

var stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(can, undefined)['paddingLeft'], 10) || 0; 
var stylePaddingTop = parseInt(document.defaultView.getComputedStyle(can, undefined)['paddingTop'], 10) || 0; 
var styleBorderLeft = parseInt(document.defaultView.getComputedStyle(can, undefined)['borderLeftWidth'], 10) || 0; 
var styleBorderTop = parseInt(document.defaultView.getComputedStyle(can, undefined)['borderTopWidth'], 10) || 0; 
var html = document.body.parentNode; 
var htmlTop = html.offsetTop; 
var htmlLeft = html.offsetLeft; 

function getMouse(e) { 
    var element = can, 
     offsetX = 0, 
     offsetY = 0, 
     mx, my; 

    // Compute the total offset 
    if (element.offsetParent !== undefined) { 
     do { 
      offsetX += element.offsetLeft; 
      offsetY += element.offsetTop; 
     } while ((element = element.offsetParent)); 
    } 

    // Add padding and border style widths to offset 
    // Also add the <html> offsets in case there's a position:fixed bar 
    offsetX += stylePaddingLeft + styleBorderLeft + htmlLeft; 
    offsetY += stylePaddingTop + styleBorderTop + htmlTop; 

    mx = e.pageX - offsetX; 
    my = e.pageY - offsetY; 

    // We return a simple javascript object (a hash) with x and y defined 
    return { 
     x: mx, 
     y: my 
    }; 
} 

它適用於任何邊界和填充,也適用於在該抵消了HTML(像StumbleUpon公司吧)的對象墊片頁。它也適用於瀏覽器放大的情況。

它似乎也適用於觸摸設備。

0

試試這個:

this.getPosition = function(obj) { 
    var x = 0, y = 0; 
    if (obj.offsetParent) { 
     do { 
      x += obj.clientLeft; 
      y += obj.clientTop; 
      obj = obj.offsetParent; 
     } while (obj); 
    } 
    return {'x': x, 'y': y}; 
}; 

clientLeftclientTop包括邊界,但offsetLeftoffsetTop沒有。

如果您不希望包括其他的元素,也許下面的工作:

this.getPosition = function(obj) { 
    return{'x': obj.clientLeft, 
      'y': obj.clientTop}; 
}; 
+1

這不僅不能解決問題,而且它會將畫布頂部的兩個h1元素的高度添加到它返回的y座標:( – janesconference

+0

@janesconference我編輯了我的答案,試試吧。您可以提供一個jsfiddle來測試它。 – Oriol

+1

編輯後的解決方案包含其他元素。 – janesconference