源码是网上下载的,注释和执行过程是自己总结的;如果侵权,请私信
基于canvas和requestAnimationFrame动画的3d樱花雨,效果如下
源码链接:https://www.yuque.com/qirantianya/ofeuv8/xsb2ol
执行过程(先进行实例初始化)
-
setParameters
- 创建canvas标签,并设置宽高后加入容器中
- maxAddingInterval:设置新生花瓣的间隔时间
- reconstructMethods:改变render函数指向
-
createCherries
- 根据屏幕宽度和初始值,确定花瓣初始生成数量
- new CHERRY_BLOSSOM(init)
- 初始化该花瓣参数
-
render (动画的回调参数,无限循环改函数)
- requestAnimationFrame:开始动画,无限循环
- clearRect:清除画布内容
- 对花瓣按视角深度进行排序
- 循环绘制所有花瓣
- 生成花瓣
- 设置花瓣颜色,设置花瓣脉络颜色,设置花瓣位置,旋转缩放花瓣
- renderCherry:绘制花瓣线条
- 生成花瓣边框,绘制
- 生成花瓣内部纹路,绘制
- 移动花瓣
- 普通情况下,花瓣按随机角度飘落,旋转
- 花瓣落到一定程度,出现倒影
- 生成花瓣倒影:除了设置透明度和位置,跟生成花瓣过程一致
- 花瓣高度离水面不远时
- 判断花瓣躺平边界,当旋转角度进入边界时,花瓣不再旋转
- 花瓣接触水面时
- 花瓣水平移动,纵坐标不动
- 生成水面涟漪,涟漪慢慢扩大,直至消失
- 改变花瓣旋转角度的规则,使花瓣慢慢躺平
- 花瓣水平躺平并且花瓣涟漪达到最大之后,花瓣出现上下漂浮效果
- 生成花瓣
- 删掉超出边界的花瓣
- 每隔一段时间生成一个新花瓣
源码
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>樱花雨</title>
<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 src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
const 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();
// 创建canvas标签,并设置宽高后加入容器中 ,获取该图片实例
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:开启动画
requestAnimationFrame(this.render)