2016-04-06 105 views
1

我正在使用座標數組在畫布上繪製一系列點。檢查鼠標光標是否在座標數組範圍內

var points = [[102, 267], [254, 163], [343, 318], [522, 112], [610, 163], [681, 112]]; 

var canvas = document.getElementById('graph'); 
var c = canvas.getContext('2d'); 

function getMousePos(canvas, evt) { 
    var rect = canvas.getBoundingClientRect(); 
    return { 
    x: evt.clientX - rect.left, 
    y: evt.clientY - rect.top 
    }; 
} 

function drawPoints(){ 
    for (i = 0; i < points.length; i++) { 
    c.beginPath(); 
    c.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI, true); 
    c.fillStyle = "black"; 
    c.fill(); 
    } 
} 
drawPoints(); 

我想寫一個函數來識別這些點,並將它們標記爲鼠標懸停在畫布上。

canvas.addEventListener('mousemove', function(evt) { 
    var mousePos = getMousePos(canvas, evt); 
    var currMouseX = mousePos.x; 
    var currMouseY = mousePos.y; 

    for (i = 0; i < points.length; i++){ 
    if ((points[i][0] >= currMouseX-4 && points[i][0] <= currMouseX+4) && (points[i][1] >= currMouseY-4 && points[i][1] <= currMouseY+4)) { 
      console.log('in range of '+points[i]); 
     c.beginPath(); 
     c.arc(points[i][0], points[i][1], 8, 0, 2 * Math.PI, true); 
     c.fillStyle = "red"; 
     c.fill(); 
    } 

    } 
}); 

我遇到的問題是我想在鼠標光標離開點的範圍時刪除標記。

如果我在最後設置了一條簡單的else語句,則循環僅適用於數組中的最後一個點,因爲for循環的其餘部分仍然執行。我需要檢查點是否已經命中,停止for循環,檢查鼠標是否離開了點的範圍,如果是,清除畫布並重新繪製點。

也許一個循環不是處理這個問題的最好方法,也許針/乾草堆aproach會更好地工作,但我不知道如何實現這個時,搜索範圍而不是嵌套數組內的單個值。

FIDDLE

回答

2

你基本上需要一個循環來重新繪製在畫布上所有的時間:

setInterval(drawPoints, 1000/30); // redraw at 30 fps 

然後,你必須清除畫布在drawPoints:

function drawPoints(){ 
    c.clearRect(0, 0, canvas.width, canvas.height); 

    for (i = 0; i < points.length; i++) { 
    c.beginPath(); 
    c.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI, true); 
    c.fillStyle = "black"; 
    c.fill(); 
    } 
} 

哪會導致一個新問題,當您移動鼠標時該點只會變成紅色。這就是你要的points從數組的數組改爲對象的數組:

points = [{x: 123, y: 234, hovered: false}]; 

而且在drawPoints:

function drawPoints(){ 
    c.clearRect(0, 0, canvas.width, canvas.height); 

    for (i = 0; i < points.length; i++) { 
    c.beginPath(); 
    c.arc(points[i].x, points[i].y, 5, 0, 2 * Math.PI, true); 
    c.fillStyle = "black"; 
    if (points[i].hovered) { 
     c.fillStyle = 'red'; 
    } 
    c.fill(); 
    } 
} 

最後你改變你的移動功能來切換hovered標誌。我把那件作品留給你。

+0

聽起來是資源密集的 – timo

+0

這是,請注意,我剛剛更新了我的答案。 –

+0

但它不是計算機上的資源密集型。你有這種循環運行每個HTML/JS遊戲,他們這樣做很好。 –

0

我添加了一個變量,用於存儲點或不點與布爾值。我添加了一個變量來存儲被擊中點的索引。

var checkHit = true; 
var saveIndex = ""; 

然後我寫了另一個if語句來檢查的checkHit變量,如果是假的,我檢查了鼠標光標仍範圍內,它不再在範圍內,我重繪帆布和重置變量。

if(!checkHit){ 
    if ((points[saveIndex][0] >= currMouseX-4 && points[saveIndex][0] <= currMouseX+4) && (points[saveIndex][1] >= currMouseY-4 && points[saveIndex][1] <= currMouseY+4)) { 
     console.log('point stil in range'); 
    } 
    else { 
     c.clearRect(0, 0, canvas.width, canvas.height); 
     drawPoints(); 
     checkHit = true; 
      saveIndex = ""; 
     console.log('Redraw'); 
    } 
    } 

FIDDLE

如果有人知道一個不太資源密集型的方法如針/大海撈針的方式,我很開放的建議/改進。

相關問題