179 lines
4.9 KiB
JavaScript
179 lines
4.9 KiB
JavaScript
|
|
/**
|
|||
|
|
* 雪花
|
|||
|
|
* canvas版 无需依赖jquery
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
var configSnowflake = {};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 雪球
|
|||
|
|
* eg: Snowflake(canvasID);
|
|||
|
|
* @param {[type]} elementName [description]
|
|||
|
|
*/
|
|||
|
|
var Snowflake = function (elementName) {
|
|||
|
|
|
|||
|
|
configInit();
|
|||
|
|
var snowElement = document.getElementById(elementName);
|
|||
|
|
var canvasContext = snowElement.getContext("2d");
|
|||
|
|
var width = configSnowflake.clientWidth;
|
|||
|
|
var height = configSnowflake.clientHeight;
|
|||
|
|
|
|||
|
|
//canvas尺寸修正
|
|||
|
|
snowElement.width = width;
|
|||
|
|
snowElement.height = height;
|
|||
|
|
|
|||
|
|
//构建雪球的数量
|
|||
|
|
var snowNumber = 50;
|
|||
|
|
|
|||
|
|
//构建雪球对象
|
|||
|
|
var snowArrObjs = initSnow(snowNumber, width, height);
|
|||
|
|
var snowArrNum = snowArrObjs.length;
|
|||
|
|
/**
|
|||
|
|
* 绘制页面
|
|||
|
|
* @return {[type]} [description]
|
|||
|
|
*/
|
|||
|
|
var render = function () {
|
|||
|
|
//清理之前的矩形数据
|
|||
|
|
canvasContext.clearRect(0, 0, width, height);
|
|||
|
|
for (var i = 0; i < snowArrNum; ++i) {
|
|||
|
|
snowArrObjs[i].render(canvasContext);
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 更新雪花
|
|||
|
|
* @return {[type]} [description]
|
|||
|
|
*/
|
|||
|
|
var update = function () {
|
|||
|
|
for (var i = 0; i < snowArrNum; ++i) {
|
|||
|
|
snowArrObjs[i].update();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 绘制与更新
|
|||
|
|
* @return {[type]} [description]
|
|||
|
|
*/
|
|||
|
|
var renderAndUpdate = function () {
|
|||
|
|
render();
|
|||
|
|
update();
|
|||
|
|
requestAnimationFrame(renderAndUpdate);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
renderAndUpdate();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
function initSnow(snowNumber, width, height) {
|
|||
|
|
//雪球参数
|
|||
|
|
var options = {
|
|||
|
|
//雪球的半球距离
|
|||
|
|
minRadius: 3,
|
|||
|
|
maxRadius: 10,
|
|||
|
|
// 运动的范围区域
|
|||
|
|
maxX: width,
|
|||
|
|
maxY: height,
|
|||
|
|
//速率
|
|||
|
|
minSpeedY: 0.05,
|
|||
|
|
maxSpeedY: 2,
|
|||
|
|
speedX: 0.05,
|
|||
|
|
//滤镜
|
|||
|
|
minAlpha: 0.5,
|
|||
|
|
maxAlpha: 1.0,
|
|||
|
|
minMoveX: 4,
|
|||
|
|
maxMoveX: 18
|
|||
|
|
};
|
|||
|
|
var snowArr = [];
|
|||
|
|
for (var i = 0; i < snowNumber; ++i) {
|
|||
|
|
snowArr[i] = new Snow(options);
|
|||
|
|
}
|
|||
|
|
return snowArr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function configInit() {
|
|||
|
|
//rem设置
|
|||
|
|
(function(doc, win) {
|
|||
|
|
var docEl = doc.documentElement,
|
|||
|
|
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
|
|||
|
|
recalc = function() {
|
|||
|
|
var clientWidth = docEl.clientWidth;
|
|||
|
|
var clientHeight = docEl.clientHeight;
|
|||
|
|
if (!clientWidth) return;
|
|||
|
|
docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';
|
|||
|
|
//宽与高度
|
|||
|
|
document.body.style.height = clientWidth * (900 / 1440) + "px";
|
|||
|
|
configSnowflake.clientWidth = clientWidth;
|
|||
|
|
configSnowflake.clientHeight = clientHeight;//clientWidth * (900 / 1440);
|
|||
|
|
};
|
|||
|
|
recalc();
|
|||
|
|
win.addEventListener(resizeEvt, recalc, false);
|
|||
|
|
doc.addEventListener('DOMContentLoaded', recalc, false);
|
|||
|
|
})(document, window);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 雪球类
|
|||
|
|
*/
|
|||
|
|
function Snow(snowSettings) {
|
|||
|
|
this.snowSettings = snowSettings;
|
|||
|
|
this.radius = randomInRange(snowSettings.minRadius, snowSettings.maxRadius);
|
|||
|
|
//初始的x位置
|
|||
|
|
this.initialX = Math.random() * snowSettings.maxX;
|
|||
|
|
this.y = -(Math.random() * 500);
|
|||
|
|
//运行的速率
|
|||
|
|
this.speedY = randomInRange(snowSettings.minSpeedY, snowSettings.maxSpeedY);
|
|||
|
|
this.speedX = snowSettings.speedX;
|
|||
|
|
//滤镜
|
|||
|
|
this.alpha = randomInRange(snowSettings.minAlpha, snowSettings.maxAlpha);
|
|||
|
|
//角度.默认是360
|
|||
|
|
this.angle = Math.random(Math.PI * 2);
|
|||
|
|
//运行的距离
|
|||
|
|
this.x = this.initialX + Math.sin(this.angle);
|
|||
|
|
//x移动距离
|
|||
|
|
this.moveX = randomInRange(snowSettings.minMoveX, snowSettings.maxMoveX);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 绘制雪球
|
|||
|
|
* @param {[type]} canvasContext [description]
|
|||
|
|
* @return {[type]} [description]
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
Snow.prototype.render = function (canvasContext) {
|
|||
|
|
//清除路径
|
|||
|
|
//开始一个画布中的一条新路径(或者子路径的一个集合)
|
|||
|
|
canvasContext.beginPath();
|
|||
|
|
//用来填充路径的当前的颜色,白色的雪球
|
|||
|
|
canvasContext.fillStyle = "rgba(255, 255, 255, " + this.alpha + ")";
|
|||
|
|
//一个中心点和半径,为一个画布的当前子路径添加一条弧线
|
|||
|
|
//坐标,圆,沿着圆指定弧的开始点和结束点的一个角度
|
|||
|
|
//弧沿着圆周的逆时针方向(TRUE)还是顺时针方向(FALSE)遍历
|
|||
|
|
canvasContext.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
|
|||
|
|
//关闭子路径
|
|||
|
|
canvasContext.closePath();
|
|||
|
|
//fill() 方法使用 fillStyle 属性所指定的颜色、渐变和模式来填充当前路径
|
|||
|
|
canvasContext.fill();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
Snow.prototype.update = function () {
|
|||
|
|
this.y += this.speedY;
|
|||
|
|
if (this.y > this.snowSettings.maxY) {
|
|||
|
|
this.y -= this.snowSettings.maxY;
|
|||
|
|
}
|
|||
|
|
this.angle += this.speedX;
|
|||
|
|
if (this.angle > Math.PI * 2) {
|
|||
|
|
this.angle -= Math.PI * 2;
|
|||
|
|
}
|
|||
|
|
//?
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 随机处理
|
|||
|
|
* @param {[type]} min [description]
|
|||
|
|
* @param {[type]} max [description]
|
|||
|
|
* @return {[type]} [description]
|
|||
|
|
*/
|
|||
|
|
function randomInRange(min, max) {
|
|||
|
|
var random = Math.random() * (max - min) + min;
|
|||
|
|
return random;
|
|||
|
|
}
|