canvas

Canvas 学习

栅格

首先我们要先了解下栅格,因为canvas的坐标和数学的坐标不同,改下我们惯性的坐标,这样才可以设计出正确的图案。
在我们开始画图之前,我们需要了解一下画布栅格(canvas grid)以及坐标空间。如图1-1所示,canvas元素默认被网格所覆盖。通常来说网格中的一个单元相当于canvas元素中的一像素。栅格的起点为左上角(坐标为(0,0))。所有元素的位置都相对于原点定位。所以图中蓝色方形左上角的坐标为距离左边(X轴)x像素,距离上边(Y轴)y像素(坐标为(x,y))。
canvas的画布栅格和传统数学的Y轴的方向相反,如果没有提前了解,到时我们画出的图案就是垂直翻转的。
1-1.

绘制矩形

< canvas >只支持两种形式的图形绘制:矩形和路径(由一系列点连成的线段)。所有其他类型的图形都是通过一条或者多条路径组合而成的。不过,我们拥有众多路径生成的方法让复杂图形的绘制成为了可能。
canvas提供了三种方法绘制矩形:
fillRect(x, y, width, height)
绘制一个填充的矩形
strokeRect(x, y, width, height)
绘制一个矩形的边框
clearRect(x, y, width, height)
清除指定矩形区域,让清除部分完全透明。
上面提供的方法之中每一个都包含了相同的参数。x与y指定了在canvas画布上所绘制的矩形的左上角(相对于原点)的坐标。width和height设置矩形的尺寸。

<html>
<head>
<title>Canvas</title>
<script>
  //效果图如 图2-4 所示
  function draw(){
    var canvas=document.getElementById("canvas");
	var ctx=canvas.getContext("2d");
	ctx.fillRect(25, 25, 100, 100);  //填充的矩形 代码效果 图2-1 所示
    ctx.clearRect(45, 45, 60, 60);   //1-2句代码效果图2-2所示
    ctx.strokeRect(50, 50, 50, 50);  //代码效果 图2-3 所示
	}
</script>
</head>
<body onload="draw()">
 <canvas id="canvas" width="300px" height="300px" style="border:1px soild #000">
  </canvas>
</body>
</html>

2-12-22-32-4

绘制路径

beginPath()
新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
closePath()
闭合路径之后图形绘制命令又重新指向到上下文中。
stroke()
通过线条来绘制图形轮廓。
fill()
通过填充路径的内容区域生成实心的图形。
生成路径的第一步叫做beginPath()。本质上,路径是由很多子路径构成,这些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。而每次这个方法调用之后,列表清空重置,然后我们就可以重新绘制新的图形。
注意:当前路径为空,即调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo(),无论实际上是什么。出于这个原因,你几乎总是要在设置路径之后专门指定你的起始位置。

第二步就是调用函数指定绘制路径,本文稍后我们就能看到了。

第三,就是闭合路径closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。
注意:当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。

绘制一个三角形

<html>
<head>
<title>Canvas</title>
<script>
function draw(){
  var canvas=document.getElementById("canvas");
  var ctx=canvas.getContext("2d");
  ctx.beginPath();
  ctx.moveTo(75,50);
  ctx.lineTo(100,75);
  ctx.lineTo(100,25);
  ctx.fill();
  }  
</script>
</head>
<body onload="draw()">
<canvas id="canvas" width="300px" height="300px" style="border:1px soild #000">
</canvas>
</body>
</html>

效果如下图所示
在这里插入图片描述

移动笔触

个非常有用的函数,而这个函数实际上并不能画出任何东西,也是上面所描述的路径列表的一部分,这个函数就是moveTo()。或者你可以想象一下在纸上作业,一支钢笔或者铅笔的笔尖从一个点到另一个点的移动过程。

moveTo(x, y)
将笔触移动到指定的坐标x以及y上。

当canvas初始化或者beginPath()调用后,你通常会使用moveTo()函数设置起点。我们也能够使用moveTo()绘制一些不连续的路径。

线

绘制直线,需要用到的方法lineTo()。

lineTo(x, y)
绘制一条从当前位置到指定x以及y位置的直线。

该方法有两个参数:x以及y ,代表坐标系中直线结束的点。开始点和之前的绘制路径有关,之前路径的结束点就是接下来的开始点,等等。。。开始点也可以通过moveTo()函数改变。

<html>
<head>
<title>Canvas</title>
<script>
  function draw(){
    var canvas=document.getElementById("canvas");
	var ctx=canvas.getContext("2d");
	//填充三角形
	ctx.beginPath();
	ctx.moveTo(25,25);
	ctx.lineTo(105,25);
	ctx.lineTo(25,105);
	ctx.fill();
	//描边三角形
	ctx.beginPath();
	ctx.moveTo(125,125); 
	ctx.lineTo(125,45);
	ctx.lineTo(45,125);
	ctx.closePath();//上面说明过 fill()方法会自动闭合路径,但是我们这里是用stroke()方法。
    ctx.stroke();
 
	}  
</script>
</head>

<body onload="draw()">
 <canvas id="canvas" width="300px" height="300px" style="border:1px solid #000">
  </canvas>
</body>
</html> 

在这里插入图片描述

圆弧

绘制圆弧或者圆,我们使用arc()方法。当然可以使用arcTo(),不过这个的实现并不是那么的可靠,所以我们这里不作介绍。

arc(x, y, radius, startAngle, endAngle, anticlockwise)
画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。
arcTo(x1, y1, x2, y2, radius)
根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点。

这里详细介绍一下arc方法,该方法有六个参数:x,y为绘制圆弧所在圆上的圆心坐标。radius为半径。startAngle以及endAngle参数用弧度定义了开始以及结束的弧度。这些都是以x轴为基准。参数anticlockwise为一个布尔值。为true时,是逆时针方向,否则顺时针方向。

注意:arc()函数中表示角的单位是弧度,不是角度。角度与弧度的js表达式:
弧度=(Math.PI/180)*角度。

<html>
<head>
<title>Canvas</title>
<script>
  function draw(){
    var canvas=document.getElementById("canvas");
	var ctx=canvas.getContext("2d");
	ctx.beginPath();
	ctx.arc(75,75,50,0,Math.PI*2,true); // 绘制
    ctx.moveTo(110,75);
    ctx.arc(75,75,35,0, Math.PI,false); // 口(顺时针)
    ctx.moveTo(65,65);
    ctx.arc(60,65,5,0, Math.PI*2,true);  // 左眼
    ctx.moveTo(95,65);
    ctx.arc(90,65,5,0, Math.PI*2,true);  // 右眼
    ctx.stroke();
	ctx.closePath();
	}  
</script>
</head>

<body onload="draw()">
 <canvas id="canvas" width="300px" height="300px" style="border:1px solid #000">
  </canvas>
</body>
</html>

在这里插入图片描述
下面的例子比上面的要复杂一下,下面绘制了12个不同的角度以及填充的圆弧。

下面两个for循环,生成圆弧的行列(x,y)坐标。每一段圆弧的开始都调用beginPath()。代码中,每个圆弧的参数都是可变的,实际编程中,我们并不需要这样做。

x,y坐标是可变的。半径(radius)和开始角度(startAngle)都是固定的。结束角度(endAngle)在第一列开始时是180度(半圆)然后每列增加90度。最后一列形成一个完整的圆。

clockwise语句作用于第一、三行是顺时针的圆弧,anticlockwise作用于二、四行为逆时针圆弧。if语句让一、二行描边圆弧,下面两行填充路径。

图

二次贝塞曲线

quadraticCurveTo(cp1x, cp1y, x, y)
绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。
如图所示 P1为控制点 ,P0 为起始点,P2为结束点
在这里插入图片描述

<html>
<head>
<title>Canvas</title>
<script>
  function draw(){
    var canvas=document.getElementById("canvas");
	var ctx=canvas.getContext("2d");	
    ctx.beginPath();
	ctx.moveTo(75,25);
	ctx.quadraticCurveTo(25,25,25,60);
	ctx.stroke(); 
	}  
</script>
</head>

<body onload="draw()">
 <canvas id="canvas" width="300px" height="300px" style="border:1px solid #000">
  </canvas>
</body>
</html>

在这里插入图片描述
将控制点坐标改为 (75,75)来改变方向
在这里插入图片描述
我们可以通过修改控制点来修改圆弧的方向

以下通过绘制聊天气泡例子来看看 ==quadraticCurveTo(cp1x, cp1y, x, y)==的运用

<html>
<head>
<title>Canvas</title>
<script>
  function draw(){
    var canvas=document.getElementById("canvas");
	var ctx=canvas.getContext("2d");	
     ctx.beginPath();
    ctx.moveTo(75, 25);
    ctx.quadraticCurveTo(25, 25, 25, 62.5);
    ctx.quadraticCurveTo(25, 100, 50, 100);
    ctx.quadraticCurveTo(50, 120, 30, 125);
    ctx.quadraticCurveTo(60, 120, 65, 100);
    ctx.quadraticCurveTo(125, 100, 125, 62.5);
    ctx.quadraticCurveTo(125, 25, 75, 25);
    ctx.stroke();
	}  
</script>
</head>

<body onload="draw()">
 <canvas id="canvas" width="300px" height="300px" style="border:1px solid #000">
  </canvas>
</body>
</html>

效果图如下
在这里插入图片描述

三次贝塞曲线

bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。
如图所示 P1,P2 为控制点 ,P0为起始点,P3为结束点。
在这里插入图片描述
运用三次贝塞曲线来绘制爱心

<html>
<head>
<title>Canvas</title>
<script>
  function draw(){
    var canvas=document.getElementById("canvas");
	var ctx=canvas.getContext("2d");	
    ctx.fillStyle="red"; //设置填充颜色
	ctx.beginPath();
    ctx.moveTo(75, 40);
    ctx.bezierCurveTo(75, 37, 70, 25, 50, 25);
    ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
    ctx.bezierCurveTo(20, 80, 40, 102, 75, 120);
    ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
    ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
    ctx.bezierCurveTo(85, 25, 75, 37, 75, 40);
    ctx.fill();
	}  
</script>
</head>

<body onload="draw()">
 <canvas id="canvas" width="300px" height="300px" style="border:1px solid #000">
  </canvas>
</body>
</html>

效果如下图所示
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值