canvas动画科技园_Canvas动画(PC端 移动端)

本文介绍了如何使用HTML5的Canvas标签和JavaScript API来创建跟随鼠标或手指移动的火焰动画,包括创建Canvas标签、获取Canvas上下文、绘制火花和火焰、更新与绘制函数的详细步骤,同时提供了PC端和移动端的事件处理方式。
摘要由CSDN通过智能技术生成

Canvas动画(PC端 移动端)

一,介绍与需求

1.1,介绍

canvas是HTML5中新增一个HTML5标签与操作canvas的javascript API,它可以实现在网页中完成动态的2D与3D图像技术。 标记和 SVG以及 VML 之间的一个重要的不同是, 有一个基于 JavaScript 的绘图 API,而 SVG 和 VML 使用一个 XML 文档来描述绘图。SVG 绘图很容易编辑与生成,但功能明显要弱一些。canvas可以完成动画、游戏、图表、图像处理等原来需要Flash完成的一些功能

1.2,需求

实现特殊的动画效果

二,动画实现

以跟随鼠标/手指移动的火为例

第一步:创建Canvas标签

1

第二步:获取Canvas标签

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 }

第三步:绘制火花

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 }

第四步:绘制火焰

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 }

第五步:绘制火

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(this.ctx);140

141 }142

143

144 }145

146 Fire.prototype.updateMouse = function(e) {147 //跳转语句

148 if (system.win || system.mac || system.xll) {//PC端

149 this.mouse.x =e.clientX;150 this.mouse.y =e.clientY;151 } else {//移动端

152 e.preventDefault();//阻止默认行为

153 this.mouse.x = e.changedTouches[0].clientX;154 this.mouse.y = e.changedTouches[0].clientY;155 }156

157

158 }

第六步:调用

1 varoCanvas;2 init = function() {3

4 oCanvas = newFire();5 oCanvas.start();6

7

8 }9 window.onload = init;

随机数函数

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

效果如下:

三,PC端与移动端处理

3.1,判断是PC端还是移动端

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值