2012-09-09 15 views
5

キャンバス自体に対するキャンバス要素のイベントの座標を取得する方法については、stackoverflowに関する多くの回答があります。私は、次のソリューションを使用しています(getEventPosition)、それがうまく機能し、私は私のキャンバスに境界線を追加してから除く:ボーダー付きのHTML5キャンバス(クリック)イベントの座標を見つける

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

このコードはマイライブラリに属し、どのようなキャンバス要素ユーザーを取ることができますので、ユーザーがライブラリに枠のついたキャンバスを渡すと、物が壊れます。アカウントに境界線を取るソリューションはありますか?

答えて

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

これは、任意のボーダーとパディングと連携し、また、(StumbleUponのバーのような)HTMLを相殺オブジェクトにシムのページで動作します。ブラウザがズームされている場合にも機能します。

タッチデバイスでもうまくいくようです。

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

これは問題を解決するだけでなく、それが返すy座標にキャンバスの上にある2つのh1要素の高さを追加します:( – janesconference

+0

@janesconference私は自分の答えを編集しました。テストするためにすべてのコードをjsfiddleで提供することができます。 – Oriol

+1

編集されたソリューションには他の要素が含まれています。 – janesconference

関連する問題