最新更新時間:2019年07月14日14:18:12
《猛戳-查看我的博客地圖-總有你意想不到的驚喜》
本文內容:canvas 繪製圓弧
繪製任意角度的純色圓弧
模板骨架
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas demo</title>
<script type="text/javascript">
function draw(){
var canvas = document.getElementById('myCanvas');//返回DOM對象
if (canvas.getContext){
var ctx = canvas.getContext('2d');//返回canvas 的上下文
}
}
</script>
</head>
<body onload="draw();">
<canvas id="myCanvas" width="300" height="300"></canvas>
</body>
<scritp></script>
</html>
初始化並繪製30°圓弧
function initCanvas(){
let canvas = document.getElementById("myCanvas")
this.ctx = canvas.getContext("2d");
let width = 140,height = 140;
canvas.width = width;//等同於寫在組件 width={canvaswidth}
canvas.height = height;//等同於寫在組件 height={canvasheight}
//移動端毛邊優化和模糊優化-借鑑於echarts
if (window.devicePixelRatio) {
canvas.style.width = width + "px";
canvas.style.height = height + "px";
canvas.height = height * window.devicePixelRatio;
canvas.width = width * window.devicePixelRatio;
this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}
//創建背景圓
this.ctx.lineWidth = 12;//線寬
this.ctx.lineCap = 'round';//圓弧頂端弧面
this.ctx.beginPath();//開始一個新的路徑 x*(36/180)*Math.PI
this.ctx.arc(70, 70, 60, -Math.PI/2, Math.PI/6 - Math.PI/2, false);//繪製30°圓弧context.arc(圓心的x座標,圓心的y座標,半徑,起始角度,終止角度,false順時針/true逆時針)
this.ctx.strokeStyle = 'rgba(252,255,152, 1)';
this.ctx.stroke();//對當前路徑進行描邊
}
幾點說明:
- lineCap 線段末端的屬性,butt-線段末端以方形結束,round-線段末端以圓形結束,square-線段末端以方形結束,但是增加了一個寬度和線段相同,高度是線段厚度一半的矩形區域。
- arc 繪製圓弧路徑的方法,起始角度
-Math.PI/2
爲十二點鐘(零點)方向
繪製任意角度的漸變色圓弧
初始化並繪製270°圓弧
function initCanvas(){
let canvas = document.getElementById("myCanvas")
this.ctx = canvas.getContext("2d");
let width = 140,height = 140;
canvas.width = width;//等同於寫在組件 width={canvaswidth}
canvas.height = height;//等同於寫在組件 height={canvasheight}
//移動端毛邊優化和模糊優化-借鑑於echarts
if (window.devicePixelRatio) {
canvas.style.width = width + "px";
canvas.style.height = height + "px";
canvas.height = height * window.devicePixelRatio;
canvas.width = width * window.devicePixelRatio;
this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}
//創建背景圓
this.ctx.lineWidth = 12;//線寬
this.ctx.lineCap = 'butt';
let g = this.ctx.createLinearGradient(30*Math.sqrt(2), 0, 0, 30*Math.sqrt(2));
g.addColorStop(0, 'rgba(252,255,152, 1)');
g.addColorStop(1, 'rgba(252,0,0, 1)');
this.ctx.strokeStyle = g;
this.ctx.beginPath();//開始一個新的路徑 x*(36/180)*Math.PI
this.ctx.arc(70, 70, 60, -Math.PI/2, Math.PI*3/2 - Math.PI/2, false);
this.ctx.stroke();//對當前路徑進行描邊
}
半徑爲60°的圓弧,漸變色x軸和y軸的起點和終點的值如下表:
座標點名稱 | 30° | 90° | 180° | 270° | 360° |
---|---|---|---|---|---|
漸變色x起點 | - | - | 30*Math.sqrt(2) | 30*Math.sqrt(2) | - |
漸變色y起點 | - | - | 0 | 0 | - |
漸變色x終點 | - | - | 0 | 0 | - |
漸變色y終點 | - | - | 30*Math.sqrt(2)*2 | 30*Math.sqrt(2) | - |
圓弧路徑起始座標 | - | - | –Math.PI/2 | -Math.PI/2 | - |
圓弧路徑終點座標 | - | - | Math.PI - Math.PI/2 | Math.PI*3/2 - Math.PI/2 | - |
繪製360°雙色圓弧
function initCanvas(){
let canvas = document.getElementById("myCanvas")
this.ctx = canvas.getContext("2d");
let width = 140,height = 140;
canvas.width = width;//等同於寫在組件 width={canvaswidth}
canvas.height = height;//等同於寫在組件 height={canvasheight}
//移動端毛邊優化和模糊優化-借鑑於echarts
if (window.devicePixelRatio) {
canvas.style.width = width + "px";
canvas.style.height = height + "px";
canvas.height = height * window.devicePixelRatio;
canvas.width = width * window.devicePixelRatio;
this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}
//創建背景圓
this.ctx.lineWidth = 12;//線寬
this.ctx.lineCap = 'butt';
this.ctx.strokeStyle = 'rgba(252,255,152, 1)';
this.ctx.beginPath();
this.ctx.arc(70, 70, 60, -Math.PI/2, Math.PI - Math.PI/2, false);
this.ctx.stroke();
this.ctx.strokeStyle = 'rgba(255,105,180, 1)';
this.ctx.beginPath();
this.ctx.arc(70, 70, 60, Math.PI/2, Math.PI*2 - Math.PI/2, false);
this.ctx.stroke();
}
繪製360°三色圓弧
function initCanvas(){
let canvas = document.getElementById("myCanvas")
this.ctx = canvas.getContext("2d");
let width = 140,height = 140;
canvas.width = width;//等同於寫在組件 width={canvaswidth}
canvas.height = height;//等同於寫在組件 height={canvasheight}
//移動端毛邊優化和模糊優化-借鑑於echarts
if (window.devicePixelRatio) {
canvas.style.width = width + "px";
canvas.style.height = height + "px";
canvas.height = height * window.devicePixelRatio;
canvas.width = width * window.devicePixelRatio;
this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}
//創建背景圓
this.ctx.lineWidth = 12;//線寬
this.ctx.lineCap = 'butt';
this.ctx.strokeStyle = 'rgba(252,255,152, 1)';
this.ctx.beginPath();
this.ctx.arc(70, 70, 60, -Math.PI/2, Math.PI*2/3 - Math.PI/2, false);
this.ctx.stroke();
this.ctx.strokeStyle = 'rgba(255,105,180, 1)';
this.ctx.beginPath();
this.ctx.arc(70, 70, 60, -Math.PI/2 + Math.PI*2/3, Math.PI*4/3 - Math.PI/2, false);
this.ctx.stroke();
this.ctx.strokeStyle = 'rgba(0,255,0, 1)';
this.ctx.beginPath();
this.ctx.arc(70, 70, 60, Math.PI*4/3 - Math.PI/2, Math.PI*2 - Math.PI/2, false);
this.ctx.stroke();
}
以動畫形式繪製圓弧
function initCanvas(){
let canvas = document.getElementById("myCanvas")
this.ctx = canvas.getContext("2d");
let width = 140,height = 140;
canvas.width = width;//等同於寫在組件 width={canvaswidth}
canvas.height = height;//等同於寫在組件 height={canvasheight}
//移動端毛邊優化和模糊優化-借鑑於echarts
if (window.devicePixelRatio) {
canvas.style.width = width + "px";
canvas.style.height = height + "px";
canvas.height = height * window.devicePixelRatio;
canvas.width = width * window.devicePixelRatio;
this.ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}
//創建背景圓
this.ctx.lineWidth = 12;//線寬
this.ctx.lineCap = 'round';//圓弧頂端弧面
startAnimate();
}
function startAnimate(){
let _this = this;
let totalScore = 90;//以滿分爲100分表示圓弧爲360°
let count = 0;
this.scoreCountTimer = setInterval(function(){
count += 1;
if(count >= totalScore){
count = totalScore
}
//清空canvas內上一次的繪製圖案
_this.ctx.clearRect(0, 0, 140, 140);//左上角爲 00座標 x y w h
//繪製新圓弧
_this.ctx.beginPath();//開始一個新的路徑 x*(36/180)*Math.PI
_this.ctx.arc(70, 70, 60, -Math.PI/2, (count*Math.PI*2/100) - Math.PI/2, false);///用於繪製圓弧context.arc(x座標,y座標,半徑,起始角度,終止角度,false順時針/true逆時針)
_this.ctx.strokeStyle = 'rgba(252,255,152, 1)';
_this.ctx.stroke();//對當前路徑進行描邊
//分數動態渲染,canvas重繪不需要執行setState方法
_this.setState({score: count})
if(count >= totalScore){
clearInterval(_this.scoreCountTimer)
}
},15)
}
canvas api詳解
HTMLCanvasElement.getContext() 方法返回canvas 的上下文,CanvasRenderingContext2D 具有的屬性和方法如下:
- 屬性:canvas、currentTransform、direction、fillStyle、filter、font、globalAlpha、globalCompositeOperation、imageSmoothingEnabled、imageSmoothingQuality、lineCap、lineDashOffset、lineJoin、lineWidth、miterLimitshadowBlur、shadowColor、shadowOffsetX、shadowOffsetY、strokeStyle、textAlign、textBaseline
- 方法:addHitRegion()、arc()、arcTo()、beginPath()、bezierCurveTo()、clearHitRegions()、clearRect()、clip()、closePath()、createImageData()、createLinearGradient()、createPattern()、createRadialGradient()、drawFocusIfNeeded()、drawImage()、drawWidgetAsOnScreen()、drawWindow()、ellipse()、fill()、fillRect()、fillText()、getImageData()、getLineDash()、isPointInPath()、isPointInStroke()、lineTo()、measureText()、moveTo()、putImageData()、quadraticCurveTo()、rect()、removeHitRegion()、resetTransform()、restore()、rotate()、save()、scale()、scrollPathIntoView()、setLineDash()、setTransform()、stroke()、strokeRect()、strokeText()、transform()、translate()
var canvas = document.getElementById('tutorial');
var ctx = canvas.getContext('2d');
常用的:
- ctx.clearRect();//設置指定矩形區域內所有像素變成透明,並擦除之前繪製的所有內容
- ctx.fillRect();//繪製填充矩形
- ctx.strokeRect();//使用當前的繪畫樣式
- ctx.lineCap;//線末端的類型
- ctx.fillStyle;//圖形內部的顏色和樣式。 默認 #000 (黑色).
- ctx.strokeStyle;//圖形邊線的顏色和樣式。 默認 #000 (黑色).
- ctx.beginPath();//清空子路徑列表開始一個新的路徑
- ctx.arc();//繪製一段圓弧路徑
- ctx.stroke();//使用當前的樣式描邊子路徑
- ctx.drawImage();//繪製指定的圖片
- ctx.getImageData();//返回一個 ImageData 對象
參考資料
- HTML5 Canvas中 繪製圓弧
- 關於如何解決canvas的畫圓弧時的鋸齒感以及如何讓canvas的圖更清晰?(分享帖)
- Html5 Canvas開發之清除一個特定區域內的Canvas、寬高技巧、使Canvas填充整個瀏覽器窗口
- CanvasRenderingContext2D.lineCap - Web API 接口參考 | MDN
- CanvasRenderingContext2D - Web API 接口參考 | MDN
- HTMLCanvasElement - Web API 接口參考 | MDN
- Canvas - Web API 接口參考 | MDN
感謝閱讀,歡迎評論^-^