canvas實現雪花效果
this.defaultConfig = {
canvasId:'mycanvas',//canvas id
snowCount:200,//雪花數
radius:4,//半徑
intervalTime:40//毫秒
};
this.config = $.extend(this.defaultConfig,config);
var that = this;
//獲取mycanvas畫布
var can = document.getElementById(this.config.canvasId);
var ctx = can.getContext("2d");
//畫布寬度
var wid = $(document).width();
//畫布高度
var hei = $(document).height();
//兩張雪花圖片
var snowImage2 = document.getElementById('snow_2');
var counter = 0;can.width = wid;
can.height = hei;
//雪花數目
var snow = this.config.snowCount;
//雪花座標、半徑
var arr = []; //儲存各圓座標及半徑
for (var i = 0; i < snow; i++) {
arr.push({
x: Math.random() * wid,
y: Math.random() * hei,
r: Math.random() * that.config.radius + 1,
snowType:0
})
}
//畫雪花
this.DrawSnow = function() {
counter++;
ctx.clearRect(0, 0, wid, hei);
ctx.beginPath();
for (var i = 0; i < snow; i++) {
var p = arr[i];
var snow_image = (p.snowType == 0)?snowImage:snowImage2;
if(counter % 3 == 0){ //每3張切換一次圖片
p.snowType = 1 - p.snowType;
}
ctx.drawImage(snow_image, p.x, p.y, p.r*2, p.r*2);
}
ctx.fill();
that.SnowFall();
ctx.closePath();
}
//雪花飄落
this.SnowFall =function() {
for (var i = 0; i < snow; i++) {
var p = arr[i];
p.y += Math.random() * 1 + 2;
if (p.y > hei) {
p.y = 0;
}
p.x += Math.random() * 1 + 1;
if (p.x > wid) {
p.x = 0;
}
}
}
this.run = function(){
setInterval(that.DrawSnow, that.config.intervalTime);
}
}
備註:
1. 使用兩張圖片是因為一開始使用gif圖片時intervalTime只有幾十毫秒,還沒看出動畫效果,就已經重新繪製圖片,導致動畫效果不明顯,尺寸小的圖會有明顯的抖動,類似旋轉雪花,尺寸大的雪花圖基本看不出動畫,所以採用兩張圖片來解決這個問題。每3幀切換一次圖片,能夠比較流暢的看到動畫效果。兩張雪花圖類似 + 和x 的形狀,
2. 兩種方法獲取圖片:
第一種圖片方式:
html
<img src="$imagePrefix/201612_snowflower_pc/snow_1.png" id="snow_1" alt="">
<img src="$imagePrefix/201612_snowflower_pc/snow_2.png" id="snow_2" alt="">
js
var snowImage = document.getElementById('snow_1');var snowImage2 = document.getElementById('snow_2');
第二種圖片方式:
var snowImage = new Image();
snowImage.src = 'address1'
var snowImage2 = new Image();
snowImage.src = 'address2'
3. 使用通過二次呼叫來調節遠近疏密能獲得比較好的效果。
new SnowAnimate( {
canvasId:'mycanvas',//canvas id
snowCount:400,//雪花數
radius:4,//半徑
intervalTime:60
}).run();
new SnowAnimate( {
canvasId:'mycanvas2',//canvas id
snowCount:200,//雪花數
radius:12,//半徑
intervalTime:40
}).run();
4. 效果: