JavaScript 之 canvas(五)-- 橢圓、橡皮

原文地址: https://www.jeremyjone.com/490/, 轉載請註明。


橢圓

通過前面的文章,我們已經可以繪製大部分圖形以及文字。但是,在canvas中,橢圓是一個複雜的存在,本身我們上學時學習橢圓本身也是一個複雜的結構。我看了很多畫橢圓的方案,大部分分爲兩類:

  • 第一類是 使用arc()畫一個圓形,然後將其縮放變形,完成一個橢圓。
  • 第二類是 使用貝塞爾曲線,即使用多條貝塞爾曲線混合拼接爲一個橢圓。

經過我的實際測試,採用我認爲比較簡單並且顯示效果比較好的方式,使用貝塞爾曲線的方式繪製橢圓。

剛纔說過,貝塞爾的方式是使用多條曲線拼接,一個橢圓可以是兩條曲線、三條曲線,或四條甚至更多曲線拼接。我這裏使用兩條就夠了,而且很大程度減少我們的計算量。

關於貝塞爾曲線

貝塞爾曲線(Bézier curve),又稱貝茲曲線或貝濟埃曲線,是應用於二維圖形應用程序的數學曲線。

canvas中,使用bezierCurveTo()方法來繪製貝塞爾曲線,該方法通過使用表示三次貝塞爾曲線的指定控制點,向當前路徑添加一個點。

  • 提示:三次貝塞爾曲線需要三個點。前兩個點是用於三次貝塞爾計算中的控制點,第三個點是曲線的結束點。曲線的開始點是當前路徑中最後一個點。如果路徑不存在,那麼請使用 beginPath() 和 moveTo() 方法來定義開始點。

file

** 以上摘自HTML5 canvas bezierCurveTo()方法說明

通過貝塞爾曲線繪製橢圓

通過上圖,我們可以清楚看到繪製一條貝塞爾曲線的基本要素。

所以,我們的橢圓應該大致如下(純鼠標繪製,別吐~ ~ ~):

file

從圖中可以看到,橢圓可以被分成兩條貝塞爾曲線,我們只需要找到對應的點即可。計算過程忽略,直接看代碼(代碼已經經過位置計算的優化,看上去更像使用鼠標點擊的起始點到結束點的橢圓):

let k = ((x2 - x1) / 0.55);
let w = (x2 - x1) / 2;
let h = (y2 - y1) / 2;

// bezier double ellipse algorithm
context.moveTo(x1, y1 + h);
context.bezierCurveTo(x1, y1 + h * 3, x1 + w * 11 / 5, y1 + h * 3, x1 + w * 11 / 5, y1 + h);
context.bezierCurveTo(x1 + w * 11 / 5, y1 - h, x1, y1 - h, x1, y1 + h);
context.stroke();

效果:

這樣就繪製出了一個比較完美的橢圓。

橡皮擦

在canvas中,有三個繪製圖形函數,分別是fillRect()strokeRect()clearRect(),分別是填充圖形,空心矩形,和清除矩形,前面兩個函數我們已經使用過。最後的函數通常:

clearRect(0, 0, canvas.width, canvas.height)

可以完成清屏的功能。

我們如果想要達到橡皮擦的功能,該如何操作呢?

其實原理是一樣的,只不過,我們需要先固定住我們需要修改的圖片。

context.arc(x1, y1, 10, 0, 2 * Math.PI);  // 畫一個圓形,位置即鼠標當前位置,大小就是橡皮擦的半徑大小,當然,也可以不適用圓形,任意形狀的橡皮擦都可以。
context.clip();  // 這句很重要,它可以將上面一句定義的形狀,從當前畫布中剪切出來單獨操作,如果沒有這一句,那麼一會操作的仍然是整幅畫布。
context.clearRect(0, 0, canvas.width, canvas.height);  // 這句很簡單,和剛纔的清空示例是一樣的。
self.X1 = self.X2;
self.Y1 = self.Y2;

所以,它的整體邏輯分三步:

定義橡皮擦的大小和形狀,通常我們定義爲圓形。
固定畫板,將橡皮擦的內容單獨剪切出來。
清空剪切出來的內容,就完成了橡皮功能。

是不是很簡單,當然,需要注意的是,隨後不要忘記和隨心畫一樣,實時修改傳入的座標,達到連續擦出的效果。

這樣,簡單的橡皮功能也完成了。


完整的內容已經更新在了我的github - canvasPaint中,您也可以通過我的示例來測試一下功能。

前期目錄:

JavaScript 之 canvas(一)-- 認識canvas
JavaScript 之 canvas(二)-- 繪製基本圖形
JavaScript 之 canvas(三)-- 使用鼠標實時繪製圖形
JavaScript 之 canvas(四)-- 繪製文字

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章