4.html5 笔记2 canvas

"Hello World, Hello Blog"

Posted by wudimingwo on December 15, 2018

HTML5 Canvas; echarts; image.png CodePen image.png image.png image.png image.png

可以对同一个形状进行多次描绘. ``` // 画布 var myCanvas = document.getElementById(“myCanvas”); // 创建画笔, 上下文 var ctx = myCanvas.getContext(“2d”);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  // 一条路径 
    // 落笔
    ctx.moveTo(100,100);
    // 画直线
    ctx.lineTo(100,200);
    // 线宽
    ctx.lineWidth = 20;// 对已经画了的 线条进行装饰
    // 线颜色
    ctx.strokeStyle = 'red';//// 对已经画了的 线条进行装饰
    //描边
    ctx.stroke();
    ctx.lineTo(200,200);// 可以一直接着画直线
    ctx.lineTo(200,300);// 可以一直接着画直线
    // 线宽 // 线颜色 // 描边.
    ctx.lineWidth = 10;
    ctx.strokeStyle = "blueviolet";
    ctx.stroke();
    // 记住此时,我们不只是对新的线条进行了修饰,还对最上面的边也进行了修饰.
    ctx.lineWidth = 3;
    ctx.strokeStyle = "#009E86";
    ctx.stroke();
    // 也就是,我们可以对已经画了的线条,形状, 可以进行多次修饰.
    // 即使另起一行, 也是会进行对此修饰. ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-5d34404c4e849f7b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

如何换一层? beginpath();

1
2
3
4
5
6
7
8
9
...
        ctx.beginPath();
        ctx.moveTo(300,100);
        ctx.lineTo(300,0);
        ctx.lineWidth = 15;
        ctx.strokeStyle = "#00458A";
        ctx.stroke();
        // 此时不会对beginPath() 前面的形状产生影响, 就好像另起一层

image.png

closePath() 闭合线路,回到movoTo 落笔处.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        ctx.moveTo(100,100);
        // 画直线
        ctx.lineTo(100,200);
        // 线宽
        ctx.lineWidth = 20;// 对已经画了的 线条进行装饰
        // 线颜色
        ctx.strokeStyle = 'red';//// 对已经画了的 线条进行装饰
        //描边
        ctx.stroke();
        ctx.lineTo(200,200);// 可以一直接着画直线
        ctx.lineTo(200,300);// 可以一直接着画直线
        // 线宽 // 线颜色 // 描边.
        ctx.lineWidth = 10;
        ctx.strokeStyle = "blueviolet";
        ctx.stroke();
        // 记住此时,我们不只是对新的线条进行了修饰,还对最上面的边也进行了修饰.
        ctx.lineWidth = 3;
        ctx.strokeStyle = "#009E86";
        ctx.closePath();
        ctx.stroke();

image.png image.png image.png 同样效果

1
2
3
        ctx.rect(0,0,100,100);
        ctx.strokeStyle = "#f00";
        ctx.stroke();
1
2
        ctx.strokeStyle = "#000000";
        ctx.strokeRect(0,0,100,100);

同样效果

1
2
3
        ctx.rect(0,0,100,100);
        ctx.fillStyle = "red";
        ctx.fill();
1
2
        ctx.fillStyle = "red";
        ctx.fillRect(0,0,100,100);

所以能看出来,只是为了让你更方便, 没必要觉得更复杂. 唯一的橡皮擦 image.png 矩形落地小demo ``` ctx.fillRect(100,100,100,100); var y = 100; var timer = setInterval(function () { ctx.clearRect(0,0,500,500); ctx.fillRect(100,y,100,100); if (y >= 400) { clearInterval(timer); } y += 10; },50);

1
2
3
4
5
6
7
![image.png](https://upload-images.jianshu.io/upload_images/13637909-102b6eb0c05d234c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/13637909-aedcae02b0c3cc77.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
# [javascript三角函数的使用](https://www.cnblogs.com/shibaxiong/p/4673035.html)

[html5 作业 canvas 雪花飘落](https://www.jianshu.com/p/763523d81fb3)
![image.png](https://upload-images.jianshu.io/upload_images/13637909-a34375c9f6805901.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/13637909-f6c86ccc416260eb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
1
2
3
4
    ctx.arc(250,250,50,0,2*Math.PI,0);
    ctx.strokeStyle = "white"
    ctx.lineWidth = 5;
    ctx.stroke(); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-101e10b3e5728a09.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
1
2
3
4
5
6
        ctx.moveTo(250,250);
        ctx.arc(250,250,50,0,-Math.PI/4,1);
        ctx.strokeStyle = "white"
        ctx.lineWidth = 5;
        ctx.closePath();
        ctx.stroke();

image.png

1
2
3
4
5
6
7
        
        ctx.moveTo(250,250);
        ctx.arc(250,250,50,0,-Math.PI/4,0);
        ctx.strokeStyle = "white"
        ctx.lineWidth = 5;
        ctx.closePath();
        ctx.stroke();

image.png image.png

1
2
3
        ctx.moveTo(100,100);
        ctx.arcTo(100,200,200,200,10);
        ctx.stroke();

image.png 注意, 画弧结束后的笔不是,弧度的第二个坐标, 而是半径和第二条线的切线处.

1
2
3
4
        ctx.moveTo(100,100);
        ctx.arcTo(100,200,200,200,10);
        ctx.closePath();
        ctx.stroke();

image.png

画一个有圆角的矩形. ``` ctx.moveTo(100,110); ctx.arcTo(100,200,200,200,10); ctx.arcTo(200,200,200,100,10); ctx.arcTo(200,100,100,100,10); ctx.arcTo(100,100,100,200,10);

1
2
3
4
5
    ctx.stroke(); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-f89f7cd72ebdce79.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 如何画曲线?  ![image.png](https://upload-images.jianshu.io/upload_images/13637909-b436d58386183b26.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 具体数学上怎么实现的暂时不用理会,不用理解. 我们只需要知道, 可以设置控制点的方式,绘制曲线. 先确定起点,和终点,起始点不是由 quadraticCurveTo 来决定, 而是看上一次落笔在哪里. 然后调整中间点,就可以控制曲线了 ```
    ctx.moveTo(100,100);
    ctx.quadraticCurveTo(200,200,300,100);
    ctx.stroke(); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-012333cc99195ee0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ```
    ctx.quadraticCurveTo(200,400,300,100); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-3e7139b9ffe0b27d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 三次也类似.

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.translate(200,200);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        // 必须重新落笔, 上一个坐标系中的 终点,不是这个坐标系中的默认起点.
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.stroke();
        // 可以看到 坐标系的变换, 并不能替代 beginpath的作用
        // 后面的样式,依然会影响前面的线条.

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.translate(200,200);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        // closePath 只会影响这个坐标系的线条,不会影响上一个坐标系
        ctx.stroke();
        

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.translate(200,200);
        ctx.scale(0.5,0.5);
        // scale 和 translate 一样也是对坐标系的伸缩
        // 注意 scale 和 translate 顺序是对效果有影响的.
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        ctx.stroke();

image.png

调换scale,translate 顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        
        ctx.scale(0.5,0.5);
        // 注意 scale,translate,rotate 的顺序 对坐标系是有影响的.
        ctx.translate(200,200);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        ctx.stroke();
        

image.png

rotate(Math.PI) 也是对坐标系的操作 ``` ctx.moveTo(100,100); ctx.lineTo(100,200); ctx.lineTo(200,200); ctx.lineWidth = 10; ctx.stroke();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    ctx.translate(200,200);
    ctx.scale(0.5,0.5);
    ctx.rotate(Math.PI/4);
    // 与css3不同, css3可以通过transform-origin 来调整旋转轴坐标,默认为center
    // 而这里的默认转轴为 坐标系原点,想要进行精确旋转,
    // 就要在设置图形的时候, 设定好与 远点的关系.
    ctx.lineWidth = 5;
    ctx.strokeStyle = "red";
    ctx.moveTo(0,0)
    ctx.lineTo(100,100);
    ctx.lineTo(100,200);
    ctx.closePath();
    ctx.stroke(); ``` > ctx.save()  ``` 首先 ctx.save() 不能代替 beginpath() 换言之, 不管你设置几个ctx.save() 只要没设置 ctx.beginpath() 那么后面的样式会依旧影响前面所有坐标系的样式.

    ctx.moveTo(100,100);
    ctx.lineTo(100,200);
    ctx.lineTo(200,200);
    ctx.lineWidth = 10;
    ctx.stroke();
    
    ctx.translate(200,200);
    ctx.scale(0.5,0.5);
    ctx.rotate(Math.PI/4);
    ctx.lineWidth = 5;
    ctx.strokeStyle = "red";
    ctx.moveTo(0,0)
    ctx.lineTo(100,100);
    ctx.lineTo(100,200);
    ctx.closePath();
    ctx.stroke();
    ctx.save();
    
    ctx.lineWidth = 2;
    ctx.strokeStyle = "yellow";
    ctx.stroke(); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-5630e59fbe0f2a3e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > ctx.save() 可以理解为 坐标系的 时间戳, 或者画布层? 用ctx.restore() 配合进行在不同坐标系之间的切换. (而beginpath() 则没有相应的切换到前面状态的方式.)

注意 save 和 restore

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
        ctx.moveTo(100,100);
        ctx.lineTo(100,200);
        ctx.lineTo(200,200);
        ctx.lineWidth = 10;
        ctx.stroke();
        ctx.save();//第一状态坐标系
        
        ctx.translate(200,200);
        ctx.save();// 第二状态坐标系
        
        ctx.scale(0.5,0.5);
        ctx.save();// 第三状态坐标系
        
        ctx.rotate(Math.PI/4);
        ctx.lineWidth = 5;
        ctx.strokeStyle = "red";
        ctx.moveTo(0,0)
        ctx.lineTo(100,100);
        ctx.lineTo(100,200);
        ctx.closePath();
        ctx.stroke();
        
        ctx.restore();// 回到第三状态坐标系, 也就是现在
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();

image.png 再来一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
        ctx.restore();// 回到第三状态坐标系, 也就是现在
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        
        
        ctx.restore();// 回到第二状态坐标系,
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        

image.png 再来一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
...
        ctx.restore();// 回到第三状态坐标系, 也就是现在
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        
        
        ctx.restore();// 回到第二状态坐标系,
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        
        
        
        ctx.restore();// 回到第一状态坐标系,
        ctx.beginPath();
        ctx.moveTo(0,0);
        ctx.lineTo(100,300);
        ctx.lineWidth = 5;
        ctx.strokeStyle = 'blue';
        ctx.stroke();
        

image.png 每次restore() 都会寻找上一个save() 对应的 坐标系. restore 的方向只能是往后切换, 无法往前切换.

image.png

1
2
3
4
5
6
7
8
9
10
11
        var img = new Image();
        img.src = "img/2test.jpg";
        img.onload = function () {
          console.log(123);
          var bg = ctx.createPattern(img,"no-repeat");
          ctx.strokeStyle = bg;
          ctx.moveTo(0,0);
          ctx.lineTo(0,400);
          ctx.lineWidth = 800;
          ctx.stroke();
        }

image.png

var bg = ctx.createPattern(img,”no-repeat”); 创建的是一个”颜色”,可以用于fillstyle,strokestyle,两个参数一个都不能少. ``` var myCanvas = document.getElementById(“myCanvas”); var myCanvas2 = document.getElementById(“myCanvas2”); var ctx = myCanvas.getContext(“2d”); var ctx2 = myCanvas2.getContext(“2d”);

1
2
3
4
5
6
7
8
9
10
11
12
13
      // 用于充当 "颜色的" canvas
      ctx2.moveTo(50,50);
      ctx2.arc(50,50,40,0,1.8 * Math.PI,0);
      ctx2.lineWidth = 5;
      ctx2.fillStyle = "deeppink";
      ctx2.strokeStyle = "purple";
      ctx2.stroke();
      ctx2.fill();
      
      // 把颜色 拿过来.
      var bg = ctx.createPattern(myCanvas2,"repeat");
      ctx.fillStyle = bg;
      ctx.fillRect(0,0,500,500);
1
2
3
4
5
6
7
![image.png](https://upload-images.jianshu.io/upload_images/13637909-17e086169b8b33bf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


![image.png](https://upload-images.jianshu.io/upload_images/13637909-f1f06c786262fbdc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
> 跟createPattern 一样, 最后也是成为一个颜色.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    var myCanvas = document.getElementById("myCanvas");
    var ctx = myCanvas.getContext("2d");
    
    var bg = ctx.createLinearGradient(100,100,100,300);
    // 中间 可以有多个渐变 颜色
    bg.addColorStop(0,"black");
    bg.addColorStop(0.5,"pink");
    bg.addColorStop(1,"purple"); //        ctx.fillStyle = bg; //        ctx.fillRect(0,0,500,500);
      
      ctx.strokeStyle = bg;
      ctx.lineWidth = 500;
      ctx.moveTo(0,0);
      ctx.lineTo(0,500);
      ctx.stroke();
1
![image.png](https://upload-images.jianshu.io/upload_images/13637909-e59cf7f1c5199205.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    var myCanvas = document.getElementById("myCanvas");
    var ctx = myCanvas.getContext("2d");
    
    var bg = ctx.createRadialGradient(250,250,50,250,250,200);
    // 中间 可以有多个渐变 颜色
    bg.addColorStop(0,"black");
    bg.addColorStop(0.5,"pink");
    bg.addColorStop(1,"purple"); //        ctx.fillStyle = bg; //        ctx.fillRect(0,0,500,500);
      
      ctx.strokeStyle = bg;
      ctx.lineWidth = 500;
      ctx.moveTo(0,0);
      ctx.lineTo(0,500);
      ctx.stroke(); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-4f71f46cd292f8b5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

image.png

1
2
3
4
5
6
7
        var bg = ctx.createRadialGradient(250,250,100,250,250,150);
        // 中间 可以有多个渐变 颜色
        bg.addColorStop(0,"white");
        bg.addColorStop(0.5,"black");
        bg.addColorStop(1,"white");
          ctx.fillStyle = bg;
          ctx.fillRect(0,0,500,500);

image.png

1
2
3
4
5
6
        var bg = ctx.createLinearGradient(0,0,0,100);
        // 中间 可以有多个渐变 颜色
        bg.addColorStop(0,"black");
        bg.addColorStop(1,"white");
          ctx.fillStyle = bg;
          ctx.fillRect(0,0,500,500);

image.png

image.png

1
2
3
4
5
6
7
8
9
10
11
        ctx.shadowColor = "red";
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 20;
        ctx.shadowOffsetY = 20;
        ctx.fillRect(100,100,100,100);
        
        
        ctx.beginPath();// 结束落笔
        ctx.translate(10,10);// 更换坐标系
        ctx.arc(400,400,50,0,2 * Math.PI,1);
        ctx.stroke();

image.png

发现,beginPath(), translate 都无法影响, 换言之, 所有 生成的图形都会生成 阴影. 除非, ``` ctx.shadowColor = “red”; ctx.shadowBlur = 10; ctx.shadowOffsetX = 20; ctx.shadowOffsetY = 20; ctx.fillRect(100,100,100,100);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    ctx.shadowBlur = 0;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;        
    ctx.arc(400,400,50,0,2 * Math.PI,1);
    ctx.stroke(); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-b8a3116345436307.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 问题: 如果我希望为一个元素, 增加多个阴影怎么办? 找到一个不是很好的方法 ```
    ctx.shadowColor = "red";
    ctx.shadowBlur = 10;
    ctx.shadowOffsetX = 20;
    ctx.shadowOffsetY = 20;
    ctx.fillRect(100,100,100,100);

    再画一次.
    ctx.shadowColor = "red";
    ctx.shadowBlur = 10;
    ctx.shadowOffsetX = -20;
    ctx.shadowOffsetY = -20;
    ctx.fillRect(100,100,100,100); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-1efaa7334bbc6cf1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

image.png

文字居中

1
2
                ctx.textAlign = "center";
                ctx.verticalAlign = "middle";

image.png image.png

image.png

1
2
3
4
5
6
7
8
        ctx.beginPath();
        ctx.arc(250,250,100,0, 2 * Math.PI,1);
        ctx.stroke();
        ctx.closePath();
        ctx.clip();
        
        ctx.fillStyle = "red";
        ctx.fillRect(200,200,300,300);

image.png

问题 : 怎么才能摆脱clip() 效果? 用 save() + restore() ``` ctx.beginPath(); ctx.arc(250,250,100,0, 2 * Math.PI,1); ctx.stroke(); ctx.closePath(); ctx.save(); ctx.clip();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    ctx.fillStyle = "red";
    ctx.fillRect(200,200,300,300);
    
    ctx.restore();
    ctx.fillStyle = "blue";
    ctx.fillRect(100,100,100,100); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-185b045d7f7b7d11.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 问题 必须加上 closepath, 完成封闭区间嘛? 不必, ```
    ctx.beginPath();
    ctx.arc(250,250,100,0, Math.PI,1);
    ctx.lineTo(250,300);
    ctx.stroke();
    ctx.save();
    ctx.clip();
    
    ctx.fillStyle = "red";
    ctx.fillRect(200,200,300,300);
    
    ctx.restore();
    ctx.fillStyle = "blue";
    ctx.fillRect(100,100,100,100); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-fbfe8af8316221d5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![image.png](https://upload-images.jianshu.io/upload_images/13637909-6381f6cb5ef74024.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![image.png](https://upload-images.jianshu.io/upload_images/13637909-4a4de5fba57131db.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 解决 新旧像素(形状重合,重叠时的情况) ![image.png](https://upload-images.jianshu.io/upload_images/13637909-37fe75fb444a730f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![image.png](https://upload-images.jianshu.io/upload_images/13637909-3ae09b07c49793fd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 只会影响, 该语句后面的所有像素. ```
    
    ctx.beginPath();
    ctx.arc(250,250,100,0, 2*Math.PI,1);
    ctx.fillStyle = "red";
    ctx.globalAlpha = '0.5';
    ctx.fill();
    ctx.fillStyle = "blue";
    ctx.fillRect(250,250,150,150); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-c38e43b07bf4a90a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ```
    ctx.beginPath();
    ctx.arc(250,250,100,0, 2*Math.PI,1);
    ctx.fillStyle = "red";
    ctx.fill();
    ctx.globalAlpha = '0.5';
    ctx.fillStyle = "blue";
    ctx.fillRect(250,250,150,150); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-ad6e9d21ed5de012.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![image.png](https://upload-images.jianshu.io/upload_images/13637909-7c7e57c74f596955.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 三个参数时,图片会按自身大小显示. ```
    var img = new Image();
    img.src = "img/2test.jpg";
    img.onload = function () {
    	ctx.drawImage(img,0,0);
    } ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-a84e6dd599b23457.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

五个参数时,限制范围, 图片会按比例缩小(或放大?).

1
        	ctx.drawImage(img,0,0,250,250);

image.png 九个参数时, 前四个数字,是截取图片, 后四个参数是 决定位置和大小.

1
        	ctx.drawImage(img,100,100,300,300,0,0,250,250);

image.png image.png ``` var myCanvas = document.getElementById(“myCanvas”); var ctx = myCanvas.getContext(“2d”);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    var img = new Image();
    img.src = "img/2test.jpg";
    img.onload = function () {
      ctx.fillRect(0,0,500,500);
    	ctx.drawImage(img,100,100,300,300,150,150,250,250);
    	
    	var canvasUrl = myCanvas.toDataURL();
    	
    	var oImg = new Image();
    	oImg.src = canvasUrl;
    	oImg.onload = function () {
    		document.body.appendChild(oImg);
    	}
    } ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-84e80129becebeb6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 问题 toDataUrl() 方法 , img有没有该方法?  只有canvas 才有. ![image.png](https://upload-images.jianshu.io/upload_images/13637909-7e5f6b97bd43d207.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > 图片高斯模糊处理的方法. 获取一张图片 利用ctx.dragImage() 方式放进一个画布里. 利用ctx.getImageData(x,y,dx,dy) 得到像素对象. 对像素对象中的数据进行处理, 利用ctx.putImageData(imgData,x,y),重新放进画布 可以利用 canvas.toDataUrl 转换成图片. ```
      ctx.fillRect(0,0,500,500);
    	ctx.drawImage(img,100,100,300,300,150,150,250,250);
    	console.log(ctx.getImageData(0,0,500,500)); ``` ![image.png](https://upload-images.jianshu.io/upload_images/13637909-ddfcdb43d74e2709.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![image.png](https://upload-images.jianshu.io/upload_images/13637909-752d37fcd684c0eb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![image.png](https://upload-images.jianshu.io/upload_images/13637909-d5a078ee2b20f43e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ```
    var myCanvas = document.getElementById("myCanvas");
    var ctx = myCanvas.getContext("2d");
    
    ctx.fillRect(0,0,500,500);
    
    function changeGray () {
      var imageData = ctx.getImageData(0,0,500,500);
      imageData.data.forEach(function (item,index,self) {
      	if (((index+1)%4) != 0) {
      		self[index] = 100;
      	}
      });
      ctx.putImageData(imageData,0,0);
    	
    } ```