2014-09-24 87 views
1

我需要跟蹤相對於我的應用中的<canvas>元素的鼠標位置。目前,我有一個mousemove事件監聽器附加到<canvas>,它在發生火災時更新我的​​鼠標位置,使用offsetX/offsetY(/layerY),當offsetX/Y不可用時。使用offsetX/YlayerX/Y可以給我鼠標座標,相對於我的<canvas>,這正是我想要的。當我的應用程序發揮它的魔力時,各種CSS 3d轉換將應用於<canvas>,即使<canvas>進行了非常大的轉換,offsetX/Y仍然在<canvas>的局部變換座標空間內給出了精確的座標。在沒有鼠標移動事件的情況下跟蹤相對鼠標位置

這有點令人困惑,所以我會嘗試說明一個例子。如果我的<canvas>的寬度和高度均爲100px,並且位於相對於瀏覽器視口的(0,0)處,並且單擊(50,50)(在視口座標系中),對應於(50,50)in我的<canvas>和50是通過offsetXoffsetY(正確)返回的值。如果我然後將transform: translate3d(20px,20px,0px)應用於我的<canvas>並單擊(50,50)(在視口座標系中),由於我的畫布已向下移動20px和20px,實際上相當於(30,30)相對於<canvas>, 30是通過offsetXoffsetY(正確)返回的值。

我面臨的問題是當用戶沒有物理移動鼠標時要做什麼,但<canvas>正在轉換。我只更新了mousemove事件上的鼠標位置,所以如果沒有mousemove,我該怎麼辦?

例如。我的鼠標位於(50,50),並且沒有轉換應用於<canvas>。我的this.mouseXthis.mouseY都等於50;當我將鼠標移動到(50,50)時,他們被保存在最後的mousemove事件中。根本沒有移動鼠標,我將上面的轉換(transform: translate3d(20px,20px,0px))應用於我的<canvas>。現在,我需要this.mouseXthis.mouseY每個等於30,因爲這是我的鼠標相對於當前轉換<canvas>的新位置。但this.mouseXthis.mouseY仍然等於50.因爲我從來沒有移動過鼠標,所以沒有發生mousemove事件,而且這些被保存的座標也不會被更新。

我該如何面對呢?我想創建一個新的jQuery事件,根據我的舊/舊鼠標位置手動分配一些屬性(pageXpageY?),然後觸發該事件,但我不認爲這會導致瀏覽器重新計算offsetXoffsetY屬性。我也一直在考慮採用已知的舊/舊鼠標位置並將其乘以我的轉換矩陣,但由於我的鼠標座標位於2d空間中,所以這會變得非常複雜,但我應用於<canvas>的轉換是所有3d轉換。

我想真的,我想要做的就是將我已知的2d頁面位置和光線投射到3d空間中,並找出我在點擊轉換的<canvas>,所有的javascript(jQuery都可用)。

這可能嗎?這甚至有意義嗎?

+0

如果您想在不移動鼠標的情況下獲得「新的」鼠標座標 - 那麼我認爲您必須從最後一個mousemove事件中獲取「舊」座標,並將這些轉換應用於這些值自己來計算正確的「新」座標應該是什麼。 – CBroe 2014-09-24 08:40:19

+0

@CBroe我真的希望避免這種情況,但你可能是對的... – 2014-09-24 18:17:36

回答

0

即使您不移動鼠標,它看起來像要刷新您的鼠標位置值。你應該嘗試這樣的:

var event = ''; 
var counter = 1; 

$(function(e){ 
    event = e; 
    window.setInterval(refresh, 10); 
}); 

$(document).mousemove(function(e){ 
    event = e; 
    refresh; 
}); 

function refresh(){ 
    counter++; 
    $('#mousepos').val("event.pageX: " + event.pageX + ", event.pageY: " + event.pageY + ", counter: " + counter) 
} 

該計數器只是爲刷新的可視化。你可以設置你想要的時間間隔(10 = 10ms = 0.01s)。只需將你的.mousemove()事件中的所有內容移動到這個refresh()函數並正確調用它,即使你不移動鼠標位置也應該更新你的鼠標。

看這個搗鼓一個生活中的例子:http://jsfiddle.net/82cmxw8L/1

編輯:

因爲我的小提琴沒有爲提問者的工作,我更新它:http://jsfiddle.net/82cmxw8L/8/

新的是,鼠標位置現在每0.1秒設置一次,無論如何,而不是隻有當鼠標移動時才更新。

+0

感謝您的建議,但不幸的是,它看起來像這不會爲我的目的。我編輯了一下你的jsfiddle來測試它。我添加了一個框,當您將鼠標懸停在右側時將其向右滑動,並將事件附加到該框而不是文檔,並且當您將鼠標懸停在框上並滑動時,可以看到offsetX和offsetY值(鼠標位置相對於div而不是頁面)在您實際移動鼠標之前不會被更新。 – 2014-09-24 18:14:03

+0

我更新了我的答案。它現在應該可以按照您的預期工作。 – WcPc 2014-09-25 18:22:26

1

作品在所有瀏覽器

var mouseX=0; 
var mouseY=0; 
var canvas = document.querySelector('#canvas'); 
var rect = canvas.getBoundingClientRect(); 
document.onmousemove = function(e) { 
     mouseX=e.clientX-rect.left; 
     mouseY=e.clientY-rect.top; 
}; 
function updateCoords() { 
     mouseX=e.clientX-mouseX; 
     mouseY=e.clientY-mouseY; 
     setTimeout(updatecoords,10); 
} 

現在,我們可以調用一次updateCoords()功能反覆檢查爲新的位置。

updateCoords(); 

您可以添加代碼updateCoords()功能內,將每10毫秒

執行

理念:mouseXmouseY變量得到更新上mousemove事件,並且也得到更新,當有任何改變畫布的位置。