canvas基本认识及简单图形绘制

819 阅读3分钟

这是我参与更文挑战的第1天,活动详情查看: 更文挑战

概念:

广义:h5新增canvas 2d 绘图功能 在html中:

  • canvas 是html 标签
  • canvas可以理解为一张画布
  • 我们需要用js 在canvas 里绘制图形 
<!--canvas 默认宽:300px 高:150px-->
<cavnas id="canvas" width="700" height="700"></canvas>

<script>
		const canvas = document.querySelector('#canvas');
  	 // 获取画笔
  	const ctx = canvas.selector('2d')
</script>

如何设置canvas的尺寸及尺寸限制

设置canvas dom 元素的 width height 属性。 canvas 的尺寸不能过大 ,尽量控制在4000 以内。 canvas 具体极限值因浏览器、平台不同而不同。  注意:不要使用css 设置canvas 尺寸。 在css中设置画布的大小会引起画布的拉伸、锯边等怪异行为。 image.png

canvas 上下文对象

image.png

如何获取canvas上下文对象

获取上下文对象的方法:canvas.getContext(‘2d’) 

<canvas id="canvas" width="700" height="700">不兼容</canvas>
<script>
    /*获取canvas画布*/
    const canvas=document.getElementById('canvas');

    /*获取画笔*/
    const ctx=canvas.getContext('2d');

    /*红色的填充矩形*/
    ctx.fillStyle='red';
    ctx.fillRect(20,20,300,200);
</script>

获取了上下文对象后,如何用它画画?

使用画笔在canvas 上画画,要考虑三个方面:

  • 颜色
  • 形状
  • 绘图方法 

兼容性

  • canvas 兼容ie9 及其以上 

image.png

canvas绘图的步骤

  • 建立canvas 画布。
  • 通过canvas 画布获取上下文对象,也就是画笔。
  • 设置画笔颜色。
  • 设置图形形状。
  • 绘制图形。 

canvas 画布的坐标系和栅格? 

  • canvas 的坐标系是二维直角坐标系,由x轴和y轴组成。
  • canvas 坐标系中横向的轴为x轴,越往右越大;竖向的轴为y 轴,越往下越大。
  • canvas 坐标系是以像素的宽高为基底的 栅格就是右图的4 个格子,每一个格子就是一个像素,像素具有rgba 数据。 像素的数量等于canvas 画布的宽度乘以高度。

image.png

矩形的绘制方法

填充矩形方法:fillRect(x,y,w,h)
<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
		// 将画布的宽高设为浏览器的宽高
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    //画笔
    const  ctx=canvas.getContext('2d');

    /*填充色*/
    ctx.fillStyle='red';

    /*填充矩形方法:fillRect(x,y,w,h)*/
    ctx.fillRect(50,50,400,200);
</script>

image.png

描边矩形方法:strokeRect(x,y,w,h)
<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
		// 将画布的宽高设为浏览器的宽高
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    // 画笔
    const  ctx=canvas.getContext('2d');

		// 描边色, 默认黑色
    // ctx.strokeStyle='maroon';

    // 描边矩形方法:strokeRect(x,y,w,h)
    ctx.strokeRect(50,50,400,200);
</script>

image.png

清理矩形方法:clearRect(x,y,w,h) 
<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    //画笔
    const  ctx=canvas.getContext('2d');

    /*描边宽度*/
    ctx.lineWidth=20;

    /*填充色*/
    ctx.fillStyle='red';
    /*描边色*/
    // ctx.strokeStyle='maroon';

    // /*填充矩形方法:fillRect(x,y,w,h)*/
    ctx.fillRect(50,50,400,200);

    // /*描边矩形方法:strokeRect(x,y,w,h)*/
    ctx.strokeRect(50,50,400,200);

    // /*清理矩形方法:clearRect(x,y,w,h)*/
    ctx.clearRect(50,50,400,200);

</script>

image.png

绘制路径的步骤
  • 开始建立路径:beginPath()
  • 向路径集合中添加子路径:    
    • [  moveTo(x,y); 形状; closePath() 可选,  
    • moveTo(x,y); 形状; closePath() 可选,  
    • moveTo(x,y); 形状; closePath() 可选,    ]
  • 显示路径:填充fill() ,描边stroke() 
子路径的形状
  • 直线:lineTo(x,y);
<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    //画笔
    const  ctx=canvas.getContext('2d');

    ctx.lineWidth=10;

    /*直线:lineTo(x,y); */
    ctx.beginPath();
    ctx.moveTo(50,100);
    ctx.lineTo(400,100);
    ctx.lineTo(400,300);
    ctx.closePath();
    ctx.stroke();
</script>

image.png

  • 圆弧:arc(x,y,半径,开始弧度,结束弧度,方向)

圆弧 arc(x,y,半径,开始弧度,结束弧度,方向)  image.png

<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    //画笔
    const  ctx=canvas.getContext('2d');

    ctx.lineWidth=10;

    /*
    * 360° = Math.PI*2
    * 1°=Math.PI*2/360
    * */

    /*arc(x,y,半径,开始弧度,结束弧度,方向)*/
    ctx.beginPath();
    ctx.arc(
        300,300,
        50,
        0,Math.PI*3/2
    )
	
		// 第二个圆的起点
    ctx.moveTo(370,500);
    ctx.arc(
        300,500,
        70,
        0,Math.PI*2
    )
    ctx.stroke();
</script>

image.png

  • 切线圆弧:arcTo(x1,y1,x2,y2,半径)

image.png

<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    //画笔
    const  ctx=canvas.getContext('2d');

    ctx.lineWidth=10;

    /*切线圆弧:arcTo(x1,y1,x2,y2,半径)*/
    ctx.beginPath();
    ctx.moveTo(50,100);
    ctx.lineTo(400,100);
    ctx.lineTo(400,300);
    ctx.stroke();

    ctx.beginPath();
    ctx.strokeStyle = 'red'
    ctx.moveTo(50,100);
    ctx.arcTo(400,100,400,300,100);
    ctx.stroke();
</script>

image.png

  • 二次贝塞尔曲线:quadraticCurverTo(cpx1,cpy1,x,y)

image.png

<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    //画笔
    const  ctx=canvas.getContext('2d');

    ctx.lineWidth=10;

    /*二次贝塞尔曲线:quadraCurverTo(cpx1,cpy1,x,y)*/
    ctx.beginPath();
    ctx.moveTo(50,100);
    ctx.quadraticCurveTo(200,60,400,300);
    ctx.stroke();
</script>

image.png

  • 三次贝塞尔曲线:bezierCurverTo(cpx1,cpy1,cpx2,cpy2,x,y)

image.png

<canvas id="canvas"></canvas>
<script>
    const canvas=document.getElementById('canvas');
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    //画笔
    const  ctx=canvas.getContext('2d');

    ctx.lineWidth=10;
		ctx.beginPath();
    ctx.moveTo(50,100);
		
		// 三次贝塞尔曲线:bezierCurverTo(cpx1,cpy1,cpx2,cpy2,x,y)
    ctx.bezierCurveTo(
        400,0,
        400,400,
        700,300);
    ctx.stroke();
</script>

image.png

  • 矩形:rect(x,y,w,h) 
<script>
    const canvas=document.getElementById('canvas');
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;

    //画笔
    const  ctx=canvas.getContext('2d');

    ctx.lineWidth=10;    
		// 矩形:rect(x,y,w,h)
		ctx.beginPath();
    ctx.rect(50,50,100,100);
    ctx.rect(50,200,100,100);
    ctx.stroke();
</script>

image.png

绘制原理

image.png

路径和子路径的概念

路径:

  • 路径是子路径的集合。
  • 一个上下文对象同时只有一个路径,想要绘制新的路径,就要把当前路径置空。
  • beginPath() 方法当前路径置空,也就是将路径恢复到默认状态,让之后绘制的路径不受以前路径的影响。

子路径: 

  • 子路径是一条只有一个起点的、连续不断开的线。
  • moveTo(x,y)  是设置路径起点的方法,也是创建一条新的子路径的方法。
  • 路径里的第一条子路径可以无需设置起点,它的起点默认是子路径中的第一个点。

注:rect(x,y,w,h) 绘制路径时,会具备moveTo() 功能。  

image.png