关于Canvas的基本知识

1,088 阅读4分钟

什么是canvas

canvas 是 HTML5 新定义的标签,通过使用脚本(通常是 JavaScript)绘制图形。
<canvas> 标签只是图形容器,相当于一个画布,canvas 元素本身是没有绘图能力的。所有的绘制工作必须在 JavaScript 内部完成,相当于使用画笔在画布上画画。

默认情况下,<canvas> 没有边框和内容。默认是一个 300*150 的画布,所以我们创建了 <canvas> 之后要对其设置宽高。

我们可以通过html属性‘width’,‘height’来设置canvas的宽高,不可以通过 css 属性来设置宽高。因为通过 css 属性设置的宽高会使 canvas 内的图像按照 300*150 时的比例放大或缩小

getContext()

context是一个封装了很多绘图功能的对象,我们在页面中创建一个canvas标签之后,首先要获取getContext()获取canvas的环境

getContext("2d")对象是内建的html5对象,拥有多种绘制与添加图像的方法。

canvas元素绘制图像

canvas创建图形有两种方式

context.fill()

fill()方法填充当前的图像。

context.stroke()

stroke()方法会实际地绘制出通过moveTo()lineTo()方法定义的路径。在进行图形绘制前,要设置好绘图的形式

绘制矩形

 fillRect(x,y,width,height) // 实心矩形
 strokeRect(x,y,width,height) // 空心矩形
  • x,y : 起点的(x,y)坐标
  • width,height: 矩形的宽和高
<canvas id="canvas"></canvas>
//script代码
   var canvas = document.getElementById('canvas');
   var context = canvas.getContext('2d');
   context.fillRect(0, 0, 100, 100);
   context.strokeRect(120, 0, 100, 100);

显示如下:

image.png

canvas绘制矩形有填充颜色,默认是黑色

context.fillStyle = 'yellow'
context.strokeStyle = 'blue';
context.fillRect(0, 0, 100, 100);
context.strokeRect(120, 0, 100, 100);

效果如下:

image.png

清除矩形区域

clearRect(x,y,width,height)
  • x,y : 清除矩形起点的(x,y)坐标
  • width,height: 清除矩形的宽和高
context.clearRect( 50,50,120,120);

image.png

实心圆

context.arc(x,y,radius,starAngle,endAnagle,anticlockwise)

  • x,y : 圆心的x,y坐标
  • radius: 半径
  • starAngle: 开始角度
  • endAnagle: 结束角度
  • anticlockwise: 是否逆时针 true|false
context.beginPath();
context.arc(300,350,100,0,Math.PI*2,true);
// 不关闭路径会一直保留下去
context.closePath();
context.fillStyle = 'rgba(0,255,0,0.25)';
context.fill();

image.png

圆弧

如果不填充颜色,实心圆就是圆弧

context.beginPath();
context.arc(300, 350, 100, 0, Math.PI , true);
//不关闭路径路径会一直保留下去
context.closePath();
context.strokeStyle = 'red';
context.stroke();


context.beginPath();
context.arc(300, 350, 100, 0, Math.PI , true);
// context.closePath();
context.strokeStyle = 'red';
context.stroke();

image.png

image.png

  • 系统默认在绘制第一个路径的开始点位beginPath
  • 如果画完前面的路径没有重新指定beginPath,那么画其他路径的时候就会将前面最近指定的beginPath后的全部路径重新绘制
  • 每次调佣fill()的时候会自动把当次绘制的路径的开始点和结束点相连,接着填充封闭的部分

绘制线段

  • moveTo(x,y): 把路径移动到画布中的指定点,不创建线条
  • lineTo(x,y): 添加一个新点,然后在画布中创建从该点到最后指定的线条
  • 每次画线都从moveTo的点到lineTo的点
 context.strokeStyle = 'yellow';
 context.moveTo(50, 50);
 context.lineTo(100, 100);
 context.stroke();

image.png

如果没有moveTo,那么可以写成

context.strokeStyle = 'yellow';
context.lineTo(50, 50);
context.lineTo(100, 100);
context.stroke();

每次lineTo后如果没有moveTo,那么下次lineTo的开始点为前一次lineTo的结束点

context.strokeStyle = 'yellow';
context.lineTo(50, 50);
context.lineTo(100, 100);
context.lineTo(200,100);
context.stroke();

image.png

线性渐变

var line=context.createLinearGradient(xStart,yStart,xEnd,y);
line.addColorStop(offset,color)

  • xstart: 渐变开始点x坐标
  • ystart: 渐变开始点y坐标
  • xEnd: 渐变结束点x坐标
  • yEnd: 渐变结束点y坐标
  • offset: 设定的颜色离渐变结束点的偏移量(0~1)
  • color:绘制时要使用的颜色
var g1 = context.createLinearGradient(0, 0, 0, 300);
g1.addColorStop(0, 'yellow'); 
g1.addColorStop(1, 'blue');
context.fillStyle = g1;context.fillRect(0, 0, 400, 300);

image.png

径向渐变

var rg=context.createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd)
rg.addColorStop(offset,color)

  • xStart:发散开始圆心x坐标
  • yStart:发散开始圆心y坐标
  • radiusStart:发散开始圆的半径
  • xEnd:发散结束圆心的x坐标
  • yEnd:发散结束圆心的y坐标
  • radiusEnd:发散结束圆的半径
  • offset:设定的颜色离渐变结束点的偏移量(0~1)
  • color:绘制时要使用的颜色
// 同心圆径向渐变
var g1 = context.createRadialGradient(200, 150, 0, 200, 150, 200); 
g1.addColorStop(0.1, '#F09819'); 
g1.addColorStop(1, '#EDDE5D'); 
context.fillStyle = g1; 
context.beginPath(); 
context.arc(200, 150, 100, 0, Math.PI * 2, true); 
context.closePath(); 
context.fill();

image.png

圆形变形

缩放

scale(x,y)

  • x: x坐标轴按x比例缩放
  • y: y坐标轴按y比例缩放

旋转

rotate(angle)

  • angle: 坐标轴旋转x角度

平移

translate(x,y)

  • x: 坐标原点向x轴方向平移x
  • y: 坐标原点向y轴方向平移y

画一个月亮试试看

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
    <canvas id="canvas" width="800" height="800" style="display:block;border:1px solid #aaa;margin:50px auto;">
        如果浏览器不能正常显示,请更换支持canvas的浏览器
    </canvas>
    <script type="text/javascript">
        window.onload=function(){
            var canvas = document.getElementById('canvas');
            var context = canvas.getContext('2d');  // 返回一个用于在画布上绘图的环境
            fillMoon(context , 2 ,400 ,400 ,300 ,0);
        }
        
        //d是控制点的横坐标值
        function fillMoon( cxt , d , x , y , R , rot ,/*optional*/fillColor){
            cxt.save();
            cxt.translate( x , y ); //重新映射画布上的 (x,y) 位置
            cxt.rotate( rot * Math.PI / 180);
            cxt.scale( R , R );
            pathMoon( cxt , d);
            cxt.fillStyle = fillColor||"#fb5";
            cxt.fill();
            cxt.restore();
        }
        function pathMoon( cxt , d ){
            cxt.beginPath();
            cxt.arc( 0 , 0 , 1 ,0.5*Math.PI ,1.5*Math.PI ,true);   // 创建弧线/曲线
            cxt.moveTo( 0 , -1 );
            cxt.quadraticCurveTo(1.2 ,0 ,0 ,1);   // 创建二次贝塞尔曲线
            cxt.closePath();
        }
    </script>
</body>
</html>

image.png