HTML5高阶实例之canvas绘制圆弧

最新更新时间: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 对象

参考资料

感谢阅读,欢迎评论^-^

打赏我吧^-^

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