实例介绍
【实例截图】
【核心代码】
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>樱花雨</title>
<script src="js/jquery.min.js"></script>
<style>
html, body{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.container{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: #000000;
}</style>
</head>
<body>
<div id="jsi-cherry-container" class="container"></div>
<script>
var RENDERER = {
INIT_CHERRY_BLOSSOM_COUNT : 30,
MAX_ADDING_INTERVAL : 10,
init : function(){
this.setParameters();
this.reconstructMethods();
this.createCherries();
this.render();
},
setParameters : function(){
this.$container = $('#jsi-cherry-container');
this.width = this.$container.width();
this.height = this.$container.height();
this.context = $('<canvas />').attr({width : this.width, height : this.height}).appendTo(this.$container).get(0).getContext('2d');
this.cherries = [];
this.maxAddingInterval = Math.round(this.MAX_ADDING_INTERVAL * 1000 / this.width);
this.addingInterval = this.maxAddingInterval;
},
reconstructMethods : function(){
this.render = this.render.bind(this);
},
createCherries : function(){
for(var i = 0, length = Math.round(this.INIT_CHERRY_BLOSSOM_COUNT * this.width / 1000); i < length; i ){
this.cherries.push(new CHERRY_BLOSSOM(this, true));
}
},
render : function(){
requestAnimationFrame(this.render);
this.context.clearRect(0, 0, this.width, this.height);
this.cherries.sort(function(cherry1, cherry2){
return cherry1.z - cherry2.z;
});
for(var i = this.cherries.length - 1; i >= 0; i--){
if(!this.cherries[i].render(this.context)){
this.cherries.splice(i, 1);
}
}
if(--this.addingInterval == 0){
this.addingInterval = this.maxAddingInterval;
this.cherries.push(new CHERRY_BLOSSOM(this, false));
}
}
};
var CHERRY_BLOSSOM = function(renderer, isRandom){
this.renderer = renderer;
this.init(isRandom);
};
CHERRY_BLOSSOM.prototype = {
FOCUS_POSITION : 300,
FAR_LIMIT : 600,
MAX_RIPPLE_COUNT : 100,
RIPPLE_RADIUS : 100,
SURFACE_RATE : 0.5,
SINK_OFFSET : 20,
init : function(isRandom){
this.x = this.getRandomValue(-this.renderer.width, this.renderer.width);
this.y = isRandom ? this.getRandomValue(0, this.renderer.height) : this.renderer.height * 1.5;
this.z = this.getRandomValue(0, this.FAR_LIMIT);
this.vx = this.getRandomValue(-2, 2);
this.vy = -2;
this.theta = this.getRandomValue(0, Math.PI * 2);
this.phi = this.getRandomValue(0, Math.PI * 2);
this.psi = 0;
this.dpsi = this.getRandomValue(Math.PI / 600, Math.PI / 300);
this.opacity = 0;
this.endTheta = false;
this.endPhi = false;
this.rippleCount = 0;
var axis = this.getAxis(),
theta = this.theta Math.ceil(-(this.y this.renderer.height * this.SURFACE_RATE) / this.vy) * Math.PI / 500;
theta %= Math.PI * 2;
this.offsetY = 40 * ((theta <= Math.PI / 2 || theta >= Math.PI * 3 / 2) ? -1 : 1);
this.thresholdY = this.renderer.height / 2 this.renderer.height * this.SURFACE_RATE * axis.rate;
this.entityColor = this.renderer.context.createRadialGradient(0, 40, 0, 0, 40, 80);
this.entityColor.addColorStop(0, 'hsl(330, 70%, ' 50 * (0.3 axis.rate) '%)');
this.entityColor.addColorStop(0.05, 'hsl(330, 40%,' 55 * (0.3 axis.rate) '%)');
this.entityColor.addColorStop(1, 'hsl(330, 20%, ' 70 * (0.3 axis.rate) '%)');
this.shadowColor = this.renderer.context.createRadialGradient(0, 40, 0, 0, 40, 80);
this.shadowColor.addColorStop(0, 'hsl(330, 40%, ' 30 * (0.3 axis.rate) '%)');
this.shadowColor.addColorStop(0.05, 'hsl(330, 40%,' 30 * (0.3 axis.rate) '%)');
this.shadowColor.addColorStop(1, 'hsl(330, 20%, ' 40 * (0.3 axis.rate) '%)');
},
getRandomValue : function(min, max){
return min (max - min) * Math.random();
},
getAxis : function(){
var rate = this.FOCUS_POSITION / (this.z this.FOCUS_POSITION),
x = this.renderer.width / 2 this.x * rate,
y = this.renderer.height / 2 - this.y * rate;
return {rate : rate, x : x, y : y};
},
renderCherry : function(context, axis){
context.beginPath();
context.moveTo(0, 40);
context.bezierCurveTo(-60, 20, -10, -60, 0, -20);
context.bezierCurveTo(10, -60, 60, 20, 0, 40);
context.fill();
for(var i = -4; i < 4; i ){
context.beginPath();
context.moveTo(0, 40);
context.quadraticCurveTo(i * 12, 10, i * 4, -24 Math.abs(i) * 2);
context.stroke();
}
},
render : function(context){
var axis = this.getAxis();
if(axis.y == this.thresholdY && this.rippleCount < this.MAX_RIPPLE_COUNT){
context.save();
context.lineWidth = 2;
context.strokeStyle = 'hsla(0, 0%, 100%, ' (this.MAX_RIPPLE_COUNT - this.rippleCount) / this.MAX_RIPPLE_COUNT ')';
context.translate(axis.x this.offsetY * axis.rate * (this.theta <= Math.PI ? -1 : 1), axis.y);
context.scale(1, 0.3);
context.beginPath();
context.arc(0, 0, this.rippleCount / this.MAX_RIPPLE_COUNT * this.RIPPLE_RADIUS * axis.rate, 0, Math.PI * 2, false);
context.stroke();
context.restore();
this.rippleCount ;
}
if(axis.y < this.thresholdY || (!this.endTheta || !this.endPhi)){
if(this.y <= 0){
this.opacity = Math.min(this.opacity 0.01, 1);
}
context.save();
context.globalAlpha = this.opacity;
context.fillStyle = this.shadowColor;
context.strokeStyle = 'hsl(330, 30%,' 40 * (0.3 axis.rate) '%)';
context.translate(axis.x, Math.max(axis.y, this.thresholdY this.thresholdY - axis.y));
context.rotate(Math.PI - this.theta);
context.scale(axis.rate * -Math.sin(this.phi), axis.rate);
context.translate(0, this.offsetY);
this.renderCherry(context, axis);
context.restore();
}
context.save();
context.fillStyle = this.entityColor;
context.strokeStyle = 'hsl(330, 40%,' 70 * (0.3 axis.rate) '%)';
context.translate(axis.x, axis.y Math.abs(this.SINK_OFFSET * Math.sin(this.psi) * axis.rate));
context.rotate(this.theta);
context.scale(axis.rate * Math.sin(this.phi), axis.rate);
context.translate(0, this.offsetY);
this.renderCherry(context, axis);
context.restore();
if(this.y <= -this.renderer.height / 4){
if(!this.endTheta){
for(var theta = Math.PI / 2, end = Math.PI * 3 / 2; theta <= end; theta = Math.PI){
if(this.theta < theta && this.theta Math.PI / 200 > theta){
this.theta = theta;
this.endTheta = true;
break;
}
}
}
if(!this.endPhi){
for(var phi = Math.PI / 8, end = Math.PI * 7 / 8; phi <= end; phi = Math.PI * 3 / 4){
if(this.phi < phi && this.phi Math.PI / 200 > phi){
this.phi = Math.PI / 8;
this.endPhi = true;
break;
}
}
}
}
if(!this.endTheta){
if(axis.y == this.thresholdY){
this.theta = Math.PI / 200 * ((this.theta < Math.PI / 2 || (this.theta >= Math.PI && this.theta < Math.PI * 3 / 2)) ? 1 : -1);
}else{
this.theta = Math.PI / 500;
}
this.theta %= Math.PI * 2;
}
if(this.endPhi){
if(this.rippleCount == this.MAX_RIPPLE_COUNT){
this.psi = this.dpsi;
this.psi %= Math.PI * 2;
}
}else{
this.phi = Math.PI / ((axis.y == this.thresholdY) ? 200 : 500);
this.phi %= Math.PI;
}
if(this.y <= -this.renderer.height * this.SURFACE_RATE){
this.x = 2;
this.y = -this.renderer.height * this.SURFACE_RATE;
}else{
this.x = this.vx;
this.y = this.vy;
}
return this.z > -this.FOCUS_POSITION && this.z < this.FAR_LIMIT && this.x < this.renderer.width * 1.5;
}
};
$(function(){
RENDERER.init();
});</script>
</body>
</html>
标签: 樱花
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论