使用canvas繪製圓弧動畫

j_bleach發表於2019-01-12

效果預覽

圖片描述

canvas 繪製基本流程

圖片描述

初始畫布

對於canvas的繪製,首先需要在html內指定一塊畫布,即<canvas></canvas>, 可以看做是在PS中新建一個空白文件,之後所有的操作都將呈現在這個文件之上,與PS的區別是,canvas本身沒有圖層的特性,當需要展示不同維度的檢視時,需要交由html的位置關係來解決。

canvas標籤上,值得一提的就是width和height兩個屬性,這兩個屬性代表著畫布的寬高,與canvas樣式上的寬高有很大區別。在瀏覽器當中,看到的圖形繪製大小,本身是由canvas.style.width/canvas.style.height決定的,他們決定了canvas這個dom元素的大小關係,而canvas.width和canvas.height決定的是canvas內部圖形的大小關係。當這兩個寬高比不同時,就會產生視覺上的形變。即,把canvas.style.height放大為2倍時,顯示效果會被拉伸:
圖片描述

當不設定樣式寬高時,瀏覽器中canvas大小由畫布大小決定(在實際開發中,碰到一個例外,是在使用mapbox時,繪製map的標籤如果只設定canvas畫布大小時,在ios移動端的瀏覽器上顯示異常,PC正常)。

獲取上下文

所謂上下文,代表的就是一個環境,在這個環境當中你可以獲取到相關的方法,變數。程式中有上下文,html的媒體中也有上下文,比如音訊上下文(AudioContext),只有拿到了上下文,才能進行相關的方法操作,canvas也是如此,canvas上的方法都是藉由canvas上下文得到。

<canvas id="leftCanvas"></canvas>
const canvasL = document.getElementById("leftCanvas");
const cxtL = canvasL.getContext("2d");

配置線條

本次圓弧動畫需要用到的上下文屬性有:

  • lineCap 線段端點形狀,本次設定為round
  • lineWidth 線寬
  • strokeStyle 線條填充顏色
  • clearRect 清除畫布裡面的內容
  • beginPath 在畫布上開始一段新的路徑
  • arc 圓弧繪製引數配置
  • stroke 繪製

角度計算

角度計算之前,先介紹一下繪製圓弧的基礎api arc

ctx.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);

這個函式可以接收6個引數,前五個為必填,分別為圓心x座標,圓心y座標,半徑,起始角度,結束角度,方向(預設為false,順時針)。

回到圓弧動畫,當前動畫有兩段,以順時針方向這段為例。

  • x, y:在canvas當中,座標系預設以左上角為原點,如果想讓圓弧動畫以畫布中心點旋轉,可以將圓心點設定為畫布中心點,即畫布長寬的1/2,假設設定的畫布長寬均為100,那麼圓心點的座標即為(50, 50),這個圓就繪製在了畫布中間。
  • radius:為了不與畫布產生切角,半徑設定比畫布一般略小,。
  • startAngle:起始角度為正北方向,而圓以x軸水平方向為0度,因此將起始點逆時針旋轉90°,即:-1 / 2 * Math.PI。
  • endAngle:因為圓弧長度為30°,終點角度在起始角度的基礎上增加 1 / 6 * Math.PI。

順時針方向圓弧初始配置為:

 cxtL.arc(WidthL / 2, HeightL / 2, WidthL / 2 - 5, -1 / 2 * Math.PI, 1 / 6 * Math.PI, false);

開啟動畫

window.requestAnimationFrame()

藉助requestAnimationFrame,來對canvas圓弧進行不斷的重繪,每次重繪canvas之前清空畫布,每輪動畫方向角偏移2°,即2 / 180 * Math.PI,動畫結束的標記為圓弧終點的角度,移動至3 / 2 * Math.PI,當滿足條件時,呼叫window.cancelAnimationFrame(animationId)取消動畫。

螢幕適配

通過進入html後,動態獲取視口,來設定canvas寬高,比如希望畫布大小為視窗的寬度的15%,可以通過

const clientWidth = document.documentElement.clientWidth;
const canvasWidth = Math.floor(clientWidth * 0.15);
const canvasL = document.getElementById("leftCanvas");
canvasL.setAttribute("width", canvasWidth + "px");

這樣就可以使畫布適應不同螢幕大小。

以下為未整理程式碼,較亂,僅供參考。

https://codepen.io/jbleach/pe…

相關文章