2012-09-09 41 views
5

Có rất nhiều câu trả lời, ở đây trên stackoverflow, về cách lấy toạ độ của một sự kiện trên Canvas Element, liên quan đến Canvas. Tôi sử dụng giải pháp sau (getEventPosition) và nó hoạt động tốt, ngoại trừ từ khi tôi thêm một biên giới để bạt tôi:Tìm tọa độ của sự kiện HTML5 Canvas (nhấp), với đường viền

/**** 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}; 
}; 

Kể từ khi mã này thuộc về thư viện của tôi và có thể mất bất cứ điều gì yếu tố canvas một người sử dụng cung cấp cho nó, khi một người dùng cung cấp cho thư viện một canvas có viền, mọi thứ sẽ bị phá vỡ. Có giải pháp lấy biên giới trong tài khoản không?

Trả lời

3

Dưới đây là những gì tôi đã được sử dụng để thử nghiệm mới nhất của tôi.

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 
    }; 
} 

Nó hoạt động với bất kỳ đường viền và đệm và cũng hoạt động trên các trang Shim trong một đối tượng mà offsets HTML (như thanh stumbleupon). Nó cũng hoạt động nếu trình duyệt được phóng to.

Dường như cũng hoạt động tốt trên các thiết bị cảm ứng.

0

Hãy thử điều này:

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 bao gồm biên giới, nhưng offsetLeftoffsetTop thì không.

Nếu bạn không muốn bao gồm các yếu tố khác, có lẽ sau đây sẽ làm việc:

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

Điều này không chỉ không giải quyết được vấn đề, mà nó còn thêm chiều cao của hai phần tử h1 lên trên cùng của canvas với tọa độ y nó trả về: ( – janesconference

+0

@janesconference Tôi đã sửa câu trả lời của mình, thử nó. bạn có thể cung cấp một jsfiddle với tất cả mã của bạn để kiểm tra nó – Oriol

+1

giải pháp đã chỉnh sửa bao gồm cả các phần tử khác. – janesconference

Các vấn đề liên quan