2017-07-14 229 views
0

我正在尋找一種方法來在畫布上「生活」繪製矩形或圓圈。Javascript畫布繪製矩形或圓圈

我發現用fillRect()來繪製矩形,但沒有生活的各種方式。我的意思是,能夠在一點上將mouseDown()移動到畫布中的另一個點上,畫布定義畫布的大小,就像例如在Microsoft Paint,OneNote等中一樣。

任何人都可以幫助我,並告訴我如何開始?我可能會想對如何做到這一點的方式,沒有看到矩形(或圓形)的尺寸變化,是這樣的:

$("canvas").mousedown(function(event){ 
    var ctx = this.getContext("2d"); 
    ctx.clearRect(0,0,$(this).width(),$(this).height()); 
    var initialX = event.clientX - this.getBoundingClientRect().left; 
    var initialY = event.clientY - this.getBoundingClientRect().top; 

    $(this).mousemove(function(evt) { 
     ctx.strokeRect(initialX, initialY, evt.clientX - event.clientX, evt.clientY - event.clientY); 
    }); 
}); 

但我想現場觀看,所以矩形的大小如何變化的時候,用戶移動鼠標。

+0

使用'window.requestAnimationFrame()'經常刷新畫布 – frozen

+0

@ randnum-1和?你的意思是每隔50ms重繪一次畫布或像'setInterval()'中的那樣,直到'mouseUp'? – nameless

+0

我假設你想要像這樣的東西https://jsfiddle.net/jk607fqn/3/在畫布上單擊以繪製紅色方塊 – slackOverflow

回答

1

https://jsfiddle.net/zb66mxra/2/

要做到這一點活,你需要保持你的畫布一個固定的圖像。這很容易通過保持一個對象數組被JavaScript重複地重複來完成。

let drawArr = []; 

一個例子對象包含x和y座標開始繪製,寬度和高度:

{ x: 100, 
    y: 100, 
    w: 10, 
    h: 10 } 

當你的鼠標在畫布上移動時,你只希望它改變的數組,如果鼠標關閉。這意味着你需要設置一個標誌,看看這種情況下是真或假:

let mousedown = false; 
    canvas.addEventListener('mousedown', function(e) { 
    mousedown = true; 
    ... 
    }); 
    canvas.addEventListener('mouseup', function(e) { 
    mousedown = false; 
    }); 

當你按下鼠標時要添加的項目提請陣列:

canvas.addEventListener('mousedown', function(e) { 
    mousedown = true; 
    drawArr.push({ 
    x: e.pageX, 
    y: e.pageY, 
    w: 0, 
    h: 0 
    }); 
}); 

高度和寬度最初設置爲0.我們現在想要做的事情是,如果可以想象的話,是在將鼠標拖動到畫布上並且鼠標關閉時創建矩形的高度和寬度。我們希望隨時對此進行調整,以便在重新渲染屏幕時將其視爲正在繪製。

操縱高度和寬度很容易,因爲只要您只能一次繪製一個,它總是最近添加到繪製數組的對象。

canvas.addEventListener('mousemove', function(e) { 
    if (mousedown) { 
    let i = drawArr.length -1; 

    let { 
     x, 
     y 
    } = drawArr[i]; 
    drawArr[i].w = e.pageX - x; 
    drawArr[i].h = e.pageY - y; 
    } 
}); 

最後我們使用requestAnimationFrame在draw數組中不斷繪製任何對象。

requestAnimationFrame(draw); 

然後遞歸內繪製函數:

function draw() { 
... 
requestAnimationFrame(draw); 
} 

然後,我們只需要清除原先的屏幕呈現和遍歷平局陣列我們通過調用它時,頁面加載做到這一點並再次將所有內容繪製到屏幕上。

function draw() { 
    ctx.clearRect(0, 0, window.innerWidth, window.innerHeight); 
    for (let obj of drawArr) { 
    let { 
     x, 
     y, 
     w, 
     h 
    } = obj; 
     ctx.strokeRect(x, y, w, h); 
    } 
    requestAnimationFrame(draw); 
    } 

瞧。

+0

感謝您的回答,看起來不錯,而且正是我想要的,我會盡快嘗試可能的,一個問題:難以用這樣的代碼畫一個圓圈嗎?那麼這將是一個大變化嗎?如此相同的原則,只需一個圓圈 – nameless

+0

@nameless它會非常相似。您需要使用arc context方法,接着使用stroke()而不是strokeRect。您還需要在繪製對象中存儲半徑,並在拖動畫布時更新它。 – zfrisch

+0

https://medium.com/wdstack/quick-blurb-2d-canvas-app-setup-5e6f13e12884我寫的這篇文章可能會幫助您更好地理解2d畫布的基本方法和體系結構。此外,如果這是您要查找的內容,請點擊旁邊的綠色複選框接受此答案。 – zfrisch