如何实现全屏红包雨
冷静分析一下,无外乎就是
- 红包下落动画
- 点击红包的动画
- 游戏结束弹个优惠券
核心功能点就是红包的下落功能,第一反应就是。要么使用canvas
、要么使用CSS3。
我采用的css3.
- 单个红包@keyframes下落动画
- 红包点击事件判断
- 全部红包生成位置及下落方式
- 扣点细节(提高用户体验)
-
- 点击反馈
- 提前加载图片
- 优化红包点击事件
1 动画减少回流与重绘,提升动画性能
一句话:回流一定会重绘,重绘不一定会回流。
回流 (Reflow)
当Render Tree
中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
会导致回流的操作:
- 页面首次渲染
- 浏览器窗口大小发生改变
- 元素尺寸或位置发生改变
- 元素内容变化(文字数量或图片大小等等)
- 元素字体大小变化
- 添加或者删除可见 的
DOM
元素 - 激活
CSS
伪类(例如::hover
) - 查询某些属性或调用某些方法
一些常用且会导致回流的属性和方法:
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
重绘 (Repaint)
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color
、background-color
、visibility
等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
使用transform代替width, height, top, left等值的改变
根据浏览器的渲染流程,如果引起元素位置大小的改变,需要重新进行布局计算,然后重新生成位图,交给GPU渲染展示
而transform的改变不会对元素的位置大小产生改变,而是使用已经生成的位图,对它进行旋转,缩放,移动。
随机生成红包 保证随机性的同时,生成的红包位置 不能重叠
直接改top,动画期间页面的painting
css
@keyframes redRainAn {
0% {
top: $top-p;
}
100% {
top:calc(100vh + #{$img-height})
}
}
修改transform,动画期间页面的painting,从图中可以看出 没有发生任何的回流和重绘
css
@keyframes redRainAn {
0% {
transform: translateY(0);
}
100% {
transform: translateY(calc(100vh + #{$img-height}));
}
}
css3硬件加速(GPU加速). 比起考虑如何减少回流重绘,我们更希望不需要回流和重绘 使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘
2内存控制
组件销毁是否删除了监听器,以免内存泄露;
3图片压缩
推荐一个好用的压缩网站,保证图片清晰的同时能大幅度降低图片内存大小tinypng.com/
4 压缩后的图片上传到CDN中使用
5 将功能与业务分开,维护更加简单
如红包雨下雨动画由一个人开发,业务相关由其他同学开发