基于canvas的粒子组成文字动画特效

基于canvas的粒子组成文字动画特效

这是一款基于canvas的粒子组成文字动画特效。该特效在初始化时,动态生成粒子,并以动画的方式组成指定的文字。在生成文字之后,还可以用鼠标和文字进行交互。

使用方法
HTML结构
该特效的基本HTML结构如下。

1
2
3
4
<section id="ci-particles">
  <canvas id="canvas"></canvas>
  <h1 id="headline">jQuery之家</h1>
</section>

CSS样式
为页面添加基本样式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
body {
  background-color: #000000;
 margin: 0;
  overflow: hidden;
  font-size: 0;
}
body section {
  background: url(path/to/background.jpg) no-repeat center center fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
  width: 100vw;
  height: 100vh;
  font-weight: 700;
}
body section canvas {
  width: 100vw;
  height: 100vh;
}

Javascript
然后通过下面的js代码来生成canvas粒子文字和交互动画。

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
var canvas = document.querySelector("#canvas"),
    ctx = canvas.getContext("2d"),
    link = document.createElement('link');
    particles = [],
    amount = 0,
    mouse = { x: -9999, y: -9999 },
    radius = 1,
    colors = [
      "rgba(252,248,254,0.85)",
      "rgba(220,203,255,0.75)",
      "rgba(154,112,124,0.85)",
      "rgba(192,213,255,0.85)",
      "rgba(244,223,254,0.75)"
    ],
    headline = document.querySelector("#headline"),
    ww = window.innerWidth,
    wh = window.innerHeight;
 
function Particle(x, y) {
 
  this.x = Math.random() * ww;
  this.y = Math.random() * wh;
  this.dest = { x: x, y: y };
  this.r = Math.random() * 2 * Math.PI;
  this.vx = (Math.random() - 0.5) * 25;
  this.vy = (Math.random() - 0.5) * 25;
  this.accX = 0;
  this.accY = 0;
  this.friction = Math.random() * 0.025 + 0.94;
  this.color = colors[Math.floor(Math.random() * 2.75)];
}
 
Particle.prototype.render = function() {
 
  this.accX = (this.dest.x - this.x) / 1000;
  this.accY = (this.dest.y - this.y) / 1000;
  this.vx += this.accX;
  this.vy += this.accY;
  this.vx *= this.friction;
  this.vy *= this.friction;
  this.x += this.vx;
  this.y += this.vy;
 
  ctx.fillStyle = this.color;
  ctx.beginPath();
  ctx.arc(this.x, this.y, this.r, Math.PI * 2, false);
  ctx.fill();
 
  var a = this.x - mouse.x;
  var b = this.y - mouse.y;
 
  var distance = Math.sqrt(a * a + b * b);
  if (distance < (radius * 75)) {
 
    this.accX = (this.x - mouse.x) / 100;
    this.accY = (this.y - mouse.y) / 100;
    this.vx += this.accX;
    this.vy += this.accY;
  }
}
 
function onMouseMove(e) {
 
  mouse.x = e.clientX;
  mouse.y = e.clientY;
  }
 
  function onTouchMove(e) {
 
  if (e.touches.length > 0) {
 
    mouse.x = e.touches[0].clientX;
    mouse.y = e.touches[0].clientY;
  }
}
 
function onTouchEnd(e) {
 
  mouse.x = -9999;
  mouse.y = -9999;
}
 
function initScene() {
 
  ww = canvas.width = window.innerWidth;
  wh = canvas.height = window.innerHeight;
 
  ctx.clearRect(0, 0, canvas.width, canvas.height);
 
  link.rel = 'stylesheet';
  link.type = 'text/css';
  link.href = 'https://fonts.googleapis.com/css?family=Abril+Fatface';
  document.getElementsByTagName('head')[0].appendChild(link);
 
  ctx.font = 'bold 26vw "Abril Fatface"';
  ctx.textAlign = "center";
  ctx.fillText(headline.innerHTML, ww / 2, wh / 1.6);
 
  var data = ctx.getImageData(0, 0, ww, wh).data;
 
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.globalCompositeOperation = "screen";
 
  particles = [];
  for (var i = 0; i < ww; i += Math.round(ww / 200)) {
    for (var j = 0; j < wh; j += Math.round(ww / 200)) {
      if (data[((i + j * ww) * 4) + 3] > 200) {
       
        particles.push(new Particle(i, j));
      }
    }
  }
  amount = particles.length;
}
 
function render(a) {
 
  requestAnimationFrame(render);
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (var i = 0; i < amount; i++) {
 
    particles[i].render();
  }
}
 
headline.addEventListener("keyup", initScene);
window.addEventListener("resize", initScene);
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("touchmove", onTouchMove);
window.addEventListener("touchend", onTouchEnd);
initScene();
requestAnimationFrame(render);
当前内容只有登录了才能查看,如果您已经注册,请登录
3

发表评论