Canvas animation (PC-side movement end)

Canvas animation (PC-side movement end)

I. Introduction and demand

 1.1 Introduction

HTML5 canvas tag is a new operation in the canvas HTML5 javascript API, it can achieve complete dynamic 2D and 3D image technology in the web page. <Canvas> between a tag and SVG and VML important difference is that, <canvas> there is a JavaScript-based drawing API, while SVG and VML XML document described using a drawing. SVG drawing generation and editing is easy, but the function is significantly weaker. canvas can do some of the features of the original need to complete Flash animation, games, graphics, image processing, etc.

 1.2 Demand

Achieve special effects animation

Second, to achieve animation

To follow the mouse / finger movement, for example fire

Step 1: Create Canvas tag

1 <canvas id="fire"></canvas>

Step Two: Get the Canvas tag

1  let canvas = document.getElementById('fire');
2 if (canvas.getContext){
3    var ctx = canvas.getContext('2d');
4    // drawing code here
5  } else {
6    alert("不支持Canvas")
7  }

Step Three: Draw a spark

 1 var Spark = function (mouse) {
 2 
 3             this.cx = mouse.x;
 4             this.cy = mouse.y;
 5             this.x = rand(this.cx - 40, this.cx + 40);
 6             this.y = rand(this.cy, this.cy + 5);
 7             this.lx = this.x;
 8             this.ly = this.y;
 9             this.vy = rand(1, 3);
10             this.vx = rand(-4, 4);
11             this.r = rand(0, 1);
12             this.life = rand(4, 5);
13             this.alive = true;
14             this.c = {
15 
16                 h: Math.floor(rand(2, 40)),
17                 s: 100,
18                 l: rand(40, 100),
19                 a: rand(0.8, 0.9)
20 
21             }
22 
23         }
24         Spark.prototype.update = function () {
25 
26             this.lx = this.x;
27             this.ly = this.y;
28 
29             this.y -= this.vy;
30             this.x += this.vx;
31 
32             if (this.x < this.cx)
33                 this.vx += 0.2;
34             else
35                 this.vx -= 0.2;
36 
37             this.vy += 0.08;
38             this.life -= 0.1;
39 
40             if (this.life <= 0) {
41 
42                 this.c.a -= 0.05;
43 
44                 if (this.c.a <= 0)
45                     this.alive = false;
46 
47             }
48 
49         }
50         Spark.prototype.draw = function (ctx) {
51 
52             ctx.beginPath();
53             ctx.moveTo(this.lx, this.ly);
54             ctx.lineTo(this.x, this.y);
55             ctx.strokeStyle = "hsla( " + this.c.h + ", " + this.c.s + "%, " + this.c.l + "%, " + (this.c.a / 2) + ")";
56             ctx.lineWidth = this.r * 2;
57             ctx.lineCap = 'round';
58             ctx.stroke();
59             ctx.closePath();
60 
61             ctx.beginPath();
62             ctx.moveTo(this.lx, this.ly);
63             ctx.lineTo(this.x, this.y);
64             ctx.strokeStyle = "hsla( " + this.c.h + ", " + this.c.s + "%, " + this.c.l + "%, " + this.c.a + ")";
65             ctx.lineWidth = this.r;
66             ctx.stroke();
67             ctx.closePath();
68 
69         }

Step Four: Draw Fire

 1     var Flame = function (mouse) {
 2 
 3             this.cx = mouse.x;
 4             this.cy = mouse.y;
 5             this.x = rand(this.cx - 25, this.cx + 25);
 6             this.y = rand(this.cy - 5, this.cy + 5);
 7             this.vy = rand(1, 3);
 8             this.vx = rand(-1, 1);
 9             this.r = rand(20, 30);
10             this.life = rand(3, 6);
11             this.alive = true;
12             this.c = {
13 
14                 h: Math.floor(rand(2, 40)),
15                 s: 100,
16                 l: rand(80, 100),
17                 a: 0,
18                 ta: rand(0.8, 0.9)
19 
20             }
21 
22 
23         }
24         Flame.prototype.update = function () {
25 
26             this.y -= this.vy;
27             this.vy += 0.05;
28 
29 
30             this.x += this.vx;
31 
32             if (this.x < this.cx)
33                 this.vx += 0.1;
34             else
35                 this.vx -= 0.1;
36 
37 
38 
39 
40             if (this.r > 0)
41                 this.r -= 0.1;
42 
43             if (this.r <= 0)
44                 this.r = 0;
45 
46 
47 
48             this.life -= 0.15;
49 
50             if (this.life <= 0) {
51 
52                 this.c.a -= 0.05;
53 
54                 if (this.c.a <= 0)
55                     this.alive = false;
56 
57             } else if (this.life > 0 && this.c.a < this.c.ta) {
58 
59                 this.c.a += .08;
60 
61             }
62 
63         }
64         Flame.prototype.draw = function (ctx) {
65 
66             ctx.beginPath();
67             ctx.arc(this.x, this.y, this.r * 3, 0, 2 * Math.PI);
68             ctx.fillStyle = "hsla( " + this.c.h + ", " + this.c.s + "%, " + this.c.l + "%, " + (this.c.a / 20) + ")";
69             ctx.fill();
70 
71             ctx.beginPath();
72             ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
73             ctx.fillStyle = "hsla( " + this.c.h + ", " + this.c.s + "%, " + this.c.l + "%, " + this.c.a + ")";
74             ctx.fill();
75 
76         }

Step five: draw fire

  1     var Fire = function () {
  2 
  3             this.canvas = document.getElementById('fire');
  4             this.ctx = this.canvas.getContext('2d');
  5             this.canvas.height = window.innerHeight;// window.innerHeight
  6             this.canvas.width = window.innerWidth;//window.innerWidth
  7 
  8             this.aFires = [];
  9             this.aSpark = [];
 10             this.aSpark2 = [];
 11 
 12 
 13 
 14             this.mouse = {
 15                 x: this.canvas.width * .5,
 16                 y: this.canvas.height * .75,
 17             }
 18 
 19 
 20 
 21             this.init();
 22 
 23         }
 24         Fire.prototype.init = function () {
 25             //跳转语句
 26             if (system.win || system.mac || system.xll) {
 27                 this.canvas.addEventListener('mousemove', this.updateMouse.bind(this), false);//PC端
 28             } else {
 29                 this.canvas.addEventListener('touchmove', this.updateMouse.bind(this), false);//移动端
 30             }
 31 
 32 
 33         }
 34         Fire.prototype.run = function () {
 35 
 36             this.update();
 37             this.draw();
 38 
 39             if (this.bRuning)
 40                 requestAnimationFrame(this.run.bind(this));
 41 
 42         }
 43         Fire.prototype.start = function () {
 44 
 45             this.bRuning = true;
 46             this.run();
 47 
 48         }
 49         Fire.prototype.stop = function () {
 50 
 51             this.bRuning = false;
 52 
 53         }
 54         Fire.prototype.update = function () {
 55 
 56             this.aFires.push(new Flame(this.mouse));
 57             this.aSpark.push(new Spark(this.mouse));
 58             this.aSpark2.push(new Spark(this.mouse));
 59 
 60 
 61 
 62             for (var i = this.aFires.length - 1; i >= 0; i--) {
 63 
 64                 if (this.aFires[i].alive)
 65                     this.aFires[i].update();
 66                 else
 67                     this.aFires.splice(i, 1);
 68 
 69             }
 70 
 71             for (var i = this.aSpark.length - 1; i >= 0; i--) {
 72 
 73                 if (this.aSpark[i].alive)
 74                     this.aSpark[i].update();
 75                 else
 76                     this.aSpark.splice(i, 1);
 77 
 78             }
 79 
 80 
 81             for (var i = this.aSpark2.length - 1; i >= 0; i--) {
 82 
 83                 if (this.aSpark2[i].alive)
 84                     this.aSpark2[i].update();
 85                 else
 86                     this.aSpark2.splice(i, 1);
 87 
 88             }
 89 
 90         }
 91 
 92         Fire.prototype.draw = function () {
 93 
 94             this.ctx.globalCompositeOperation = "source-over";
 95             this.ctx.fillStyle = "rgba( 15, 5, 2, 1 )";
 96             this.ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);
 97 
 98             this.grd = this.ctx.createRadialGradient(this.mouse.x, this.mouse.y - 200, 200, this.mouse.x, this.mouse.y - 100, 0);
 99             this.grd.addColorStop(0, "rgb( 15, 5, 2 )");
100             this.grd.addColorStop(1, "rgb( 30, 10, 2 )");
101             this.ctx.beginPath();
102             this.ctx.arc(this.mouse.x, this.mouse.y - 100, 200, 0, 2 * Math.PI);
103             this.ctx.fillStyle = this.grd;
104             this.ctx.fill();
105 
106 
107             this.ctx.font = "15em Amatic SC";
108             this.ctx.textAlign = "center";
109             this.ctx.strokeStyle = "rgb(50, 20, 0)";
110             this.ctx.fillStyle = "rgb(120, 10, 0)";
111             this.ctx.lineWidth = 2;
112             this.ctx.strokeText("", this.canvas.width / 2, this.canvas.height * .72);
113             this.ctx.fillText("", this.canvas.width / 2, this.canvas.height * .72);
114 
115 
116 
117             this.ctx.globalCompositeOperation = "overlay";//or lighter or soft-light
118 
119             for (var i = this.aFires.length - 1; i >= 0; i--) {
120 
121                 this.aFires[i].draw(this.ctx);
122 
123             }
124 
125             this.ctx.globalCompositeOperation = "soft-light";//"soft-light";//"color-dodge";
126 
127             for (var i = this.aSpark.length - 1; i >= 0; i--) {
128 
129                 if ((i % 2) === 0)
130                     this.aSpark[i].draw(this.ctx);
131 
132             }
133 
134 
135             this.ctx.globalCompositeOperation = "color-dodge";//"soft-light";//"color-dodge";
136 
137             for (var i = this.aSpark2.length - 1; i >= 0; i--) {
138 
139                 this.aSpark2[i].draw(the this .ctx);
 140  
141 is              }
 142  
143  
144          }
 145  
146          Fire.prototype.updateMouse = function (E) {
 147              // jump statements 
148              IF (system.win system.mac || || system.xll) { / / the PC terminal 
149                  the this .mouse.x = e.clientX;
 150                  the this .mouse.y = e.clientY;
 151              } the else { // movement end 
152                  e.preventDefault (); // prevent the default behavior 
153                  the this.mouse.x = e.changedTouches[0].clientX;
154                 this.mouse.y = e.changedTouches[0].clientY;
155             }
156 
157 
158         }

Step Six: Call

1 var oCanvas;
2         init = function () {
3 
4             oCanvas = new Fire();
5             oCanvas.start();
6 
7 
8         }
9         window.onload = init;

Random number function

1  rand = function (min, max) { return Math.random() * (max - min) + min; };

Results are as follows:

Three, PC and the mobile terminal side processing

3.1, judgment is PC or mobile terminal side

 1     //平台、设备和操作系统
 2         var system = {
 3             win: false,
 4             mac: false,
 5             xll: false
 6         };
 7         //检测平台
 8         var p = navigator.platform;
 9         system.win = p.indexOf("Win") == 0;
10         system.mac = p.indexOf("Mac") == 0;
11         system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);
12 
13 //跳转语句
14             if (system.win || system.mac || system.xll) {
15                 this.canvas.addEventListener('mousemove', this.updateMouse.bind(this), false);//PC端 鼠标移动
16             } else {
17                 this.canvas.addEventListener('touchmove', this.updateMouse.bind(this), false);//移动端 手指滑动
18             }

3.2,PC端还是移动端的事件处理

1 //跳转语句
2             if (system.win || system.mac || system.xll) {//PC端
3                 this.mouse.x = e.clientX;
4                 this.mouse.y = e.clientY;
5             } else {//移动端
6                 e.preventDefault();//阻止默认行为
7                 this.mouse.x = e.changedTouches[0].clientX;
8                 this.mouse.y = e.changedTouches[0].clientY;
9             }

 移动端需禁止缩放

1     <meta name="viewport" content="target-densitydpi=320,width=640,user-scalable=no">

 

Guess you like

Origin www.cnblogs.com/jackson-zhangjiang/p/10369815.html