1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2 <HTML>
3 <HEAD>
4 <TITLE> Love </TITLE>
5 <META NAME="Generator" CONTENT="EditPlus">
6 <META NAME="Author" CONTENT="">
7 <META NAME="Keywords" CONTENT="">
8 <META NAME="Description" CONTENT="">
9 <style>
10 html, body {
11 height: 100%;
12 padding: 0;
13 margin: 0;
14 background: #000;
15 }
16 canvas {
17 position: absolute;
18 width: 100%;
19 height: 100%;
20 }
21 </style>
22 <style type="text/css">
23 div{auto;
24 color: #ea80b0;
25 font-size: 5rem;
26 font-family: STXingkai;
27 text-shadow: 0 0 10px plum,0 0 20px plum,0 0 30px plum,0 0 40px plum;
28 }
29 .box{
30 position: absolute;
31 top: 50%;
32 left: 45%;
33 -webkit-transform: translateY(-50%);
34 -ms-transform: translateY(-50%);
35 -o-transform: translateY(-50%);
36 transform: translateY(-50%);
37 }
38 </style>
39 </HEAD>
40
41 <BODY>
42 <canvas id="pinkboard"></canvas>
43 <script>
44 /*
45 * Settings
46 */
47 var settings = {
48 particles: {
49 length: 500, // maximum amount of particles
50 duration: 2, // particle duration in sec
51 velocity: 100, // particle velocity in pixels/sec
52 effect: -0.75, // play with this for a nice effect
53 size: 30, // particle size in pixels
54 },
55 };
56
57 /*
58 * RequestAnimationFrame polyfill by Erik Möller
59 */
60 (function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());
61
62 /*
63 * Point class
64 */
65 var Point = (function() {
66 function Point(x, y) {
67 this.x = (typeof x !== 'undefined') ? x : 0;
68 this.y = (typeof y !== 'undefined') ? y : 0;
69 }
70 Point.prototype.clone = function() {
71 return new Point(this.x, this.y);
72 };
73 Point.prototype.length = function(length) {
74 if (typeof length == 'undefined')
75 return Math.sqrt(this.x * this.x + this.y * this.y);
76 this.normalize();
77 this.x *= length;
78 this.y *= length;
79 return this;
80 };
81 Point.prototype.normalize = function() {
82 var length = this.length();
83 this.x /= length;
84 this.y /= length;
85 return this;
86 };
87 return Point;
88 })();
89
90 /*
91 * Particle class
92 */
93 var Particle = (function() {
94 function Particle() {
95 this.position = new Point();
96 this.velocity = new Point();
97 this.acceleration = new Point();
98 this.age = 0;
99 }
100 Particle.prototype.initialize = function(x, y, dx, dy) {
101 this.position.x = x;
102 this.position.y = y;
103 this.velocity.x = dx;
104 this.velocity.y = dy;
105 this.acceleration.x = dx * settings.particles.effect;
106 this.acceleration.y = dy * settings.particles.effect;
107 this.age = 0;
108 };
109 Particle.prototype.update = function(deltaTime) {
110 this.position.x += this.velocity.x * deltaTime;
111 this.position.y += this.velocity.y * deltaTime;
112 this.velocity.x += this.acceleration.x * deltaTime;
113 this.velocity.y += this.acceleration.y * deltaTime;
114 this.age += deltaTime;
115 };
116 Particle.prototype.draw = function(context, image) {
117 function ease(t) {
118 return (--t) * t * t + 1;
119 }
120 var size = image.width * ease(this.age / settings.particles.duration);
121 context.globalAlpha = 1 - this.age / settings.particles.duration;
122 context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);
123 };
124 return Particle;
125 })();
126
127 /*
128 * ParticlePool class
129 */
130 var ParticlePool = (function() {
131 var particles,
132 firstActive = 0,
133 firstFree = 0,
134 duration = settings.particles.duration;
135
136 function ParticlePool(length) {
137 // create and populate particle pool
138 particles = new Array(length);
139 for (var i = 0; i < particles.length; i++)
140 particles[i] = new Particle();
141 }
142 ParticlePool.prototype.add = function(x, y, dx, dy) {
143 particles[firstFree].initialize(x, y, dx, dy);
144
145 // handle circular queue
146 firstFree++;
147 if (firstFree == particles.length) firstFree = 0;
148 if (firstActive == firstFree ) firstActive++;
149 if (firstActive == particles.length) firstActive = 0;
150 };
151 ParticlePool.prototype.update = function(deltaTime) {
152 var i;
153
154 // update active particles
155 if (firstActive < firstFree) {
156 for (i = firstActive; i < firstFree; i++)
157 particles[i].update(deltaTime);
158 }
159 if (firstFree < firstActive) {
160 for (i = firstActive; i < particles.length; i++)
161 particles[i].update(deltaTime);
162 for (i = 0; i < firstFree; i++)
163 particles[i].update(deltaTime);
164 }
165
166 // remove inactive particles
167 while (particles[firstActive].age >= duration && firstActive != firstFree) {
168 firstActive++;
169 if (firstActive == particles.length) firstActive = 0;
170 }
171
172
173 };
174 ParticlePool.prototype.draw = function(context, image) {
175 // draw active particles
176 if (firstActive < firstFree) {
177 for (i = firstActive; i < firstFree; i++)
178 particles[i].draw(context, image);
179 }
180 if (firstFree < firstActive) {
181 for (i = firstActive; i < particles.length; i++)
182 particles[i].draw(context, image);
183 for (i = 0; i < firstFree; i++)
184 particles[i].draw(context, image);
185 }
186 };
187 return ParticlePool;
188 })();
189
190 /*
191 * Putting it all together
192 */
193 (function(canvas) {
194 var context = canvas.getContext('2d'),
195 particles = new ParticlePool(settings.particles.length),
196 particleRate = settings.particles.length / settings.particles.duration, // particles/sec
197 time;
198
199 // get point on heart with -PI <= t <= PI
200 function pointOnHeart(t) {
201 return new Point(
202 160 * Math.pow(Math.sin(t), 3),
203 130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25
204 );
205 }
206
207 // creating the particle image using a dummy canvas
208 var image = (function() {
209 var canvas = document.createElement('canvas'),
210 context = canvas.getContext('2d');
211 canvas.width = settings.particles.size;
212 canvas.height = settings.particles.size;
213 // helper function to create the path
214 function to(t) {
215 var point = pointOnHeart(t);
216 point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;
217 point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;
218 return point;
219 }
220 // create the path
221 context.beginPath();
222 var t = -Math.PI;
223 var point = to(t);
224 context.moveTo(point.x, point.y);
225 while (t < Math.PI) {
226 t += 0.01; // baby steps!
227 point = to(t);
228 context.lineTo(point.x, point.y);
229 }
230 context.closePath();
231 // create the fill
232 context.fillStyle = '#ea80b0';
233 context.fill();
234 // create the image
235 var image = new Image();
236 image.src = canvas.toDataURL();
237 return image;
238 })();
239
240 // render that thing!
241 function render() {
242 // next animation frame
243 requestAnimationFrame(render);
244
245 // update time
246 var newTime = new Date().getTime() / 1000,
247 deltaTime = newTime - (time || newTime);
248 time = newTime;
249
250 // clear canvas
251 context.clearRect(0, 0, canvas.width, canvas.height);
252
253 // create new particles
254 var amount = particleRate * deltaTime;
255 for (var i = 0; i < amount; i++) {
256 var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
257 var dir = pos.clone().length(settings.particles.velocity);
258 particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);
259 }
260
261 // update and draw particles
262 particles.update(deltaTime);
263 particles.draw(context, image);
264 }
265
266 // handle (re-)sizing of the canvas
267 function onResize() {
268 canvas.width = canvas.clientWidth;
269 canvas.height = canvas.clientHeight;
270 }
271 window.onresize = onResize;
272
273 // delay rendering bootstrap
274 setTimeout(function() {
275 onResize();
276 render();
277 }, 10);
278 })(document.getElementById('pinkboard'));
279 </script>
280 <div class="box">姓名</div>
281 </BODY>
282 </HTML>