<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>JavaScript下雪特效</title>
</head>
<body style="background-color:black">
<script>
// Cross-browser-compliant
requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function (callback) {
setTimeout(callback, 1000 / 60);
};
/**
* Snow Class
* @param {int} x
* @param {int} y
* @param {int} radius
* @param {Function} fn Formular to calculate x pos and y pos
*/
function Snow(x, y, radius, fn) {
this.x = x;
this.y = y;
this.r = radius;
this.fn = fn;
}
Snow.prototype.update = function () {
this.x = this.fn.x(this.x, this.y);
this.y = this.fn.y(this.y, this.y);
if (this.x > window.innerWidth ||
this.x < 0 ||
this.y > window.innerHeight ||
this.y < 0
) {
this.x = getRandom('x');
this.y = 0;
}
}
Snow.prototype.draw = function (cxt) {
var grd = cxt.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.r);
grd.addColorStop(0, "rgba(255, 255, 255, 0.9)");
grd.addColorStop(.5, "rgba(255, 255, 255, 0.5)");
grd.addColorStop(1, "rgba(255, 255, 255, 0)");
cxt.fillStyle = grd;
cxt.fillRect(this.x - this.r, this.y - this.r, this.r * 2, this.r * 2);
}
/**
* Snowlist class
* Container to hold snow objects
*/
SnowList = function () {
this.list = [];
}
SnowList.prototype.push = function (snow) {
this.list.push(snow);
}
SnowList.prototype.update = function () {
for (var i = 0, len = this.list.length; i < len; i++) {
this.list[i].update();
}
}
SnowList.prototype.draw = function (cxt) {
for (var i = 0, len = this.list.length; i < len; i++) {
this.list[i].draw(cxt);
}
}
SnowList.prototype.get = function (i) {
return this.list[i];
}
SnowList.prototype.size = function () {
return this.list.length;
}
/**
* Generate random x-pos, y-pos or fn functions
* @param {string} option x|y|fnx|fny
* @return {int|Function}
*/
function getRandom(option) {
var ret, random;
switch (option) {
case 'x':
ret = Math.random() * window.innerWidth;
break;
case 'y':
ret = Math.random() * window.innerHeight;
break;
case 'r':
ret = 2 + (Math.random() * 6);
break;
case 'fnx':
random = 27 + Math.random() * 100;
ret = function (x, y) {
return x + 0.5 * Math.sin(y / random);
};
break;
case 'fny':
random = 0.4 + Math.random() * 1.4
ret = function (x, y) {
return y + random;
};
break;
}
return ret;
}
// Start snow
function startSnow() {
// Create canvas
var canvas = document.createElement('canvas'),
cxt;
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
canvas.setAttribute('style', 'position: fixed;left: 0;top: 0;pointer-events: none;');
canvas.setAttribute('id', 'canvas_snow');
document.getElementsByTagName('body')[0].appendChild(canvas);
cxt = canvas.getContext('2d');
// Create snow objects
var snowList = new SnowList();
for (var i = 0; i < 200; i++) {
var snow, randomX, randomY, randomR, randomFnx, randomFny;
randomX = getRandom('x');
randomY = getRandom('y');
randomR = getRandom('r');
randomFnx = getRandom('fnx');
randomFny = getRandom('fny');
snow = new Snow(randomX, randomY, randomR, {
x: randomFnx,
y: randomFny
});
snow.draw(cxt);
snowList.push(snow);
}
// Update snow position data, and redraw them in each frame
requestAnimationFrame(function () {
cxt.clearRect(0, 0, canvas.width, canvas.height);
snowList.update();
snowList.draw(cxt);
requestAnimationFrame(arguments.callee);
})
}
// Handle window resize
window.onresize = function () {
var canvasSnow = document.getElementById('canvas_snow');
canvasSnow.width = window.innerWidth;
canvasSnow.height = window.innerHeight;
}
// Let it snow O(”_”)0
startSnow();
</script>
<canvas height="400" width="900" style="position: fixed;left: 0;top: 0;pointer-events: none;" id="canvas_snow"></canvas>
</body>
</html>
评论
阅读上一篇
剑指offer算法题——查找
2018-02-08 22:04:33
阅读下一篇
前端性能优化最佳实践
2018-01-05 23:49:44