https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes

canvas的基础使用

  • canvas可以填充矩形
  • canvas可以绘制设定好的路径
  • canvas可以绘制文字
  • canvas可以绘制渐变
  • canvas可以绘制图片

    CanvasRenderingContext2D对象的api

  • fillRect(x:number, y:number, width:number, height:number)绘制一个填充的矩形

  • fillStyle属性,设置或获取填充的颜色,结合fillRect使用。
  • strokeStyle属性,设置或获取填充的颜色,结合路径使用。
  • globalAlpha属性,设置透明度,取值范围0~1
  • lineWidth属性,设置线条宽度
  • lineWidth属性,设置线条末端样式,取值范围butt(方块), round(圆) , square(方块,额外计算宽高尺寸的,宽度和线段相同,高度是线段厚度一半)。默认值是 butt。
  • lineJoin属性,设置线条连接处的样式,round(圆), bevel(矩形拐角), miter(延伸, 可以通过miterLimit设置属性值)。默认值是 miter。
  • miterLimit属性,设置限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。number值,斜接面限制比例的的数字。 0、负数、InfinityNaN 都会被忽略,默认值是10.0。
  • lineDashOffset属性,设置虚线样式的起始偏移量。偏移量是float精度的数字。 初始值为 0.0。
  • setLineDash(segments)设置当前虚线样式。值可以是[5, 15, 25]
  • getLineDash()返回一个包含当前虚线样式,长度为非负偶数的数组。
  • clearRect(x:number, y:number, width:number, height:number)清除指定矩形区域,让清除部分完全透明,要比绘制矩形区域大才能清除。
  • beginPath()新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。生成路径的第一步叫做beginPath()。本质上,路径是由很多子路径构成,这些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。而每次这个方法调用之后,列表清空重置,然后我们就可以重新绘制新的图形。
  • moveTo(_x:number_, _y:number_)将笔触移动到指定的坐标x以及y上,如果在画路径时,不移动笔触的话会出现下面的情况。当前路径为空,即调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo(x, y),无论实际上是什么。出于这个原因,你几乎总是要在设置路径之后专门指定你的起始位置。
  1. 不移动笔触image.png ,移动笔触image.png
  • lineTo(_x:number_, _y:number_)画一条线
  • closePath()闭合路径之后图形绘制命令又重新指向到上下文中。闭合路径closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。
  • stroke()通过线条来绘制图形轮廓。
  • strokeRect(x:number, y:number, width:number, height:number)绘制一个矩形的边框
  • fill()通过填充路径的内容区域生成实心的图形。当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。
  • arc(x:number, y:number, radius:number, startAngle:number, endAngle:number, anticlockwise: boolean)画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle(圆弧的起始点)开始到endAngle(圆弧的结束点)结束,按照anticlockwise给定的方向(默认为顺时针)来生成。ctx.arc(75, 75, 50, 0, 2 * Math.PI);

弧度=(Math.PI/180)*角度。

  • arcTo(x1, y1, x2, y2, radius)根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>菜鸟教程(runoob.com)</title>
  6. </head>
  7. <body>
  8. <canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
  9. 您的浏览器不支持 HTML5 canvas 标签。
  10. </canvas>
  11. <script>
  12. // 找到canvas标签
  13. var c=document.getElementById("myCanvas");
  14. // 通过canvas元素,创建Context对象
  15. var ctx=c.getContext("2d");
  16. // 设置填充颜色
  17. // ctx.fillStyle="#FF0000";
  18. // ctx.fillStyle = "rgb(200,0,0)";
  19. ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
  20. // 绘制一个矩形
  21. ctx.fillRect(0,0,150,75);
  22. </script>
  23. </body>
  24. </html>

画圆形

  1. var canvas = document.getElementById('myCanvas');
  2. var ctx = canvas.getContext('2d');
  3. ctx.beginPath();
  4. ctx.arc(75,75,50,0,Math.PI*2,true); // 绘制
  5. // ctx.moveTo(110,75);
  6. ctx.arc(75,75,35,0,Math.PI,false); // 口(顺时针)
  7. // ctx.moveTo(65,65);
  8. ctx.arc(60,65,5,0,Math.PI*2,true); // 左眼
  9. // ctx.moveTo(95,65);
  10. ctx.arc(90,65,5,0,Math.PI*2,true); // 右眼
  11. // 闭合路径
  12. ctx.closePath();
  13. // 绘制路径
  14. ctx.stroke();

不移动笔触image.png ,移动笔触image.png

画三角形

  1. function draw() {
  2. var canvas = document.getElementById('canvas');
  3. if (canvas.getContext) {
  4. var ctx = canvas.getContext('2d');
  5. // 填充三角形
  6. ctx.beginPath();
  7. ctx.moveTo(25,25);
  8. ctx.lineTo(105,25);
  9. ctx.lineTo(25,105);
  10. ctx.fill();
  11. // 描边三角形
  12. ctx.beginPath();
  13. ctx.moveTo(125,125);
  14. ctx.lineTo(125,45);
  15. ctx.lineTo(45,125);
  16. ctx.closePath();
  17. ctx.stroke();
  18. }
  19. }

绘制文字

  1. // 实心文字用填充实现
  2. var c=document.getElementById("myCanvas");
  3. var ctx=c.getContext("2d");
  4. ctx.font="30px Arial";
  5. ctx.fillText("Hello World",10,50);
  6. // 空心文字用路径实现
  7. var c=document.getElementById("myCanvas");
  8. var ctx=c.getContext("2d");
  9. ctx.font="30px Arial";
  10. ctx.strokeText("Hello World",10,50);

canvas创建渐变效果

  • createLinearGradient(x,y,x1,y1) - 创建线条渐变
  • createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变 ```javascript var c=document.getElementById(“myCanvas”); var ctx=c.getContext(“2d”);

// 创建线性渐变 var grd=ctx.createLinearGradient(0,0,200,0); grd.addColorStop(0,”red”); grd.addColorStop(1,”white”);

// 填充渐变 ctx.fillStyle=grd; ctx.fillRect(10,10,150,80);

// ########## var c=document.getElementById(“myCanvas”); var ctx=c.getContext(“2d”);

// 创建颈向/圆渐变 var grd=ctx.createRadialGradient(75,50,5,90,60,100); grd.addColorStop(0,”red”); grd.addColorStop(1,”white”);

// 填充渐变 ctx.fillStyle=grd; ctx.fillRect(10,10,150,80);

  1. <a name="0UiX2"></a>
  2. #### canvas绘制图像
  3. ```javascript
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7. <meta charset="utf-8">
  8. <title>菜鸟教程(runoob.com)</title>
  9. </head>
  10. <body>
  11. <p>Image to use:</p>
  12. <img id="scream" src="img_the_scream.jpg" alt="The Scream" width="220" height="277"><p>Canvas:</p>
  13. <canvas id="myCanvas" width="250" height="300" style="border:1px solid #d3d3d3;">
  14. 您的浏览器不支持 HTML5 canvas 标签。</canvas>
  15. <script>
  16. var c=document.getElementById("myCanvas");
  17. var ctx=c.getContext("2d");
  18. var img=document.getElementById("scream");
  19. img.onload = function() {
  20. ctx.drawImage(img,10,10);
  21. }
  22. </script>
  23. </body>
  24. </html>

Canvas API

HTMLCanvasElement对象

属性

width

height

方法

getContext(ContextId : string);

接收一个string的参数,是一个contextId,允许的值现在只有3个,2d”和”experimental-webgl”.”experimental-webgl”,

  • 调用getContext(“2d”)会返回一个 CanvasRenderingContext2D对象
  • 调用getContext(“experimental-webgl”)会返回一个WebGLRenderingContext对象.

    toDataURL(type: string, encoderOptions: number);

    返回base64的data值;

  • type 默认取值,默认为 PNG 格式。图片的分辨率为96dpi。

  • encoderOptions,在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
  1. var canvas = document.getElementById("canvas");
  2. var dataURL = canvas.toDataURL();
  3. console.log(dataURL);
  4. // "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby
  5. // blAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC"
  6. var fullQuality = canvas.toDataURL("image/jpeg", 1.0);
  7. // data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...9oADAMBAAIRAxEAPwD/AD/6AP/Z"
  8. var mediumQuality = canvas.toDataURL("image/jpeg", 0.5);
  9. var lowQuality = canvas.toDataURL("image/jpeg", 0.1);

toBlob(callback: () => void, type: string, encoderOptions:number);

  • callback 回调函数,可获得一个单独的Bolb对象参数
  • type 默认取值,默认为 PNG 格式。图片的分辨率为96dpi。
  • encoderOptions,在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。

示例,如何把一个canvas元素转换成图片,再把图片地址传给一个canvas 的使用 - 图5元素并显示出来.

  1. var canvas = document.getElementById("canvas");
  2. canvas.toBlob(function(blob) {
  3. var newImg = document.createElement("img"),
  4. url = URL.createObjectURL(blob);
  5. newImg.onload = function() {
  6. // no longer need to read the blob so it's revoked
  7. URL.revokeObjectURL(url);
  8. };
  9. newImg.src = url;
  10. document.body.appendChild(newImg);
  11. });

示例,将canvas转换为ico(仅限Mozilla)

  1. var canvas = document.getElementById("canvas");
  2. var d = canvas.width;
  3. ctx = canvas.getContext("2d");
  4. ctx.beginPath();
  5. ctx.moveTo(d / 2, 0);
  6. ctx.lineTo(d, d);
  7. ctx.lineTo(0, d);
  8. ctx.closePath();
  9. ctx.fillStyle = "yellow";
  10. ctx.fill();
  11. function blobCallback(iconName) {
  12. return function(b) {
  13. var a = document.createElement("a");
  14. a.textContent = "Download";
  15. document.body.appendChild(a);
  16. a.style.display = "block";
  17. a.download = iconName + ".ico";
  18. a.href = window.URL.createObjectURL(b);
  19. }
  20. }
  21. canvas.toBlob(blobCallback('passThisString'), 'image/vnd.microsoft.icon',
  22. '-moz-parse-options:format=bmp;bpp=32');

实例

画椭圆或圆

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <title>椭圆</title>
  6. </head>
  7. <body>
  8. <canvas id="canvas" style="border:1px solid #aaa;display:block;margin:50px auto;">
  9. 当前浏览器不支持Canvas,请更换浏览器后再试
  10. </canvas>
  11. <script>
  12. window.onload = function(){
  13. var canvas = document.getElementById("canvas");
  14. var ctx=canvas.getContext('2d');
  15. if(ctx.ellipse){
  16. // ctx.ellipse(v1, v2, v3, v4, v5, v6, v7)
  17. // v1 = 圆心x坐标点
  18. // v2 = 圆心y坐标点
  19. // v3 = 半径x
  20. // v4 = 半径y
  21. // v5 = startAngle 起始角
  22. // v6 = endAngle
  23. // v7 = anticlockwise 顺时针还是逆时针
  24. ctx.ellipse(canvas.width / 2, canvas.height / 2, 100, 50,0,0,Math.PI*2);
  25. // ctx.fillStyle="#058";
  26. ctx.strokeStyle="#000";
  27. // ctx.fill();
  28. ctx.stroke();
  29. }else{
  30. alert("no ellipse!");
  31. }
  32. }
  33. </script>
  34. </body>
  35. </html>

画圆或椭圆2

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <title>canvas</title>
  6. </head>
  7. <body>
  8. <canvas width="400" height="400" id="canvas">
  9. </canvas>
  10. <script>
  11. const c = document.getElementById("canvas")
  12. var ctx=c.getContext("2d");
  13. EllipseOne(ctx, 100, 100, 100, 50)
  14. // x,y 圆心的坐标
  15. // a,b 是半径
  16. function EllipseOne(context, x, y, a, b) {
  17. var step = (a > b) ? 1 / a : 1 / b;
  18. context.beginPath();
  19. context.moveTo(x + a, y);
  20. for(var i = 0; i < 2 * Math.PI; i += step) {
  21. context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i));
  22. }
  23. context.closePath();
  24. context.fill();
  25. }
  26. </script>
  27. </body>
  28. </html>

生成文字水印

function watermarkDrawText(text) {
  var canvas = document.createElement("canvas");
  try {
    canvas.width = 200;
    canvas.height = 200;
    var ctx = canvas.getContext("2d");
    canvas.style.position = "fixed";
    canvas.style.top = '0px';
    canvas.style.left= '0px';
    // canvas.style.backgroundColor = "#fff"
    document.body.appendChild(canvas);
    ctx.rotate(45*Math.PI/180);
    ctx.fillStyle = '#ccc'
    ctx.font="30px Arial";
    ctx.fillText(text || "",50,10);
    return canvas.toDataURL("image/png");
  } catch (e) {
    console.error(e);
  } finally {
    document.body.removeChild(canvas);
  }
}

测量文字宽度的方法,让文字行内居中

ctx.measureText('hello world!').width
ctx.textAlign = 'center';