html中做开场动画,实例CSS3开场动画的制作与优化_html/css_WEB-ITnose
素材:
期望效果: http://v.youku.com/v_show/id_XMjY2NTc1MzYw.html
一开始需要制作这个动画的时候,其实我是拒绝的,因为单凭这几个素材,即便我对动画了如指掌,也是无从下手的。后来有一天,我见到了wow军团再临的CG动画,脑海中突然灵光一闪,便出现了这样的构思:
“穿越重重的云层,伴随着白天到黑夜的转化,logo从遥远的地方出现,随后往屏幕方向快速移动,在logo快要充满整个屏幕的时候星光一闪,又消逝在远方…”
于是我开始了开场动画的坎坷历程。
云层制作:
云层的制作耗时比较久,期间参阅了网上一些使用CSS模拟云层的博文及示例,下面列出两个比较好的示例:
移动的云: https://codepen.io/montanaflynn/pen/orxwK
3D云: https://www.clicktorelease.com/blog/how-to-make-clouds-with-css-3d
实际上使用单图片来模拟云层会有一些体验问题,比如,当我们试图穿过一片图片生成的云时,会感觉一下就没了,对用户而言会产生一定的视觉落差,而真实的云层是一片区域,所以一片云我使用了5张图片转换方向来生成,这样在三维的场景下我们的云就有了充实感。
下面引用一段Jaume Sanchez Elias写的3D云的生成代码:
function createCloud() { vardiv = document.createElement('div'); div.className = 'cloudBase'; // 随机定位当前云团位置 var t = 'translateX( ' + random_x + 'px ) ' + 'translateY( ' + random_y + 'px ) ' + 'translateZ( ' + random_z + 'px )'; div.style.transform = t; world.appendChild(div); for (varj = 0; j < 5 + Math.round(Math.random() * 10); j++) { varcloud = document.createElement('div'); cloud.className = 'cloudLayer'; // 随机产生云层的'translateX/translateY/translateZ/rotateZ/scale // CSS值,这里是云团充实感的关键实现 cloud.data = { x: random_x, y: random_y, z: random_z, a: random_a, s: random_s }; var t = 'translateX( ' + random_x + 'px ) ' + 'translateY( ' + random_y + 'px ) ' + 'translateZ( ' + random_z + 'px ) ' + 'rotateZ( ' + random_a + 'deg ) ' + 'scale( ' + random_s + ' )'; cloud.style.transform = t; div.appendChild(cloud); layers.push(cloud); } return div;}
通过上面的方法去输出云层,我们便拥有了质感较强的云。而为了让动画的加载更快一些,我将生成的云层以固定DOM的形式写在页面中,让前期的JS消耗尽量减小,并且图片的加载会在页面加载之初进行。在有了云层DOM后,便可以开始着手穿越云层效果的制作了,穿越过程里还夹带了从白天到黑夜的背景色变化效果,这个穿越的动作我使用translateZ属性来实现,让屏幕随着时间往前推进,完成穿越云层的效果,代码实现如下(这里仅展示webkit版本代码):
@-webkit-keyframes angular { 0% { -webkit-transform: translateZ(300px); opacity: 1; } 100% { -webkit-transform: translateZ(570px); opacity: 1; }} @-webkit-keyframes dayToNight { 0% { background-color: #007fd5; opacity: 1; } 100% { background-color: #000; opacity: 1; }}
星光及logo:
logo及星光的呈现过程是一个放大及放更大/缩小的过程,通过改变它的scale可以实现,实现如下:
/* 星光场景 */@-webkit-keyframes starsense { 0% { -webkit-transform: scale(1); opacity: 0; } 30% { -webkit-transform: scale(25); opacity: 1; } 90% { -webkit-transform: scale(0); opacity: 1; } 100% { -webkit-transform: scale(0); opacity: 0; }}/* logo场景 */@-webkit-keyframes logosense { 0% { -webkit-transform: scale(0); transform: scale(0); opacity: 1; } 20% { -webkit-transform: scale(1); transform: scale(1); } 85% { -webkit-transform: scale(1); transform: scale(1); opacity: 1; -webkit-filter: blur(0); } 100% { -webkit-transform: scale(100); transform: scale(100); opacity: 0; -webkit-filter: blur(50px); }}
性能优化:
由于在测试中发现动画的性能是一个比较大的问题,在一些配置比较低的机器会有很多掉帧,卡顿的现象,因此需要进行性能方面的优化。
我使用chrome里面的工具Timeline进行了动画执行性能检查,从中发现,在动画执行周期内,渲染及重绘耗费的资源比较多,并且期间JS也占用了一些资源,于是我首先回头查看了我的动画加载函数
function loadOpenSenseAnimation() { isStart = true; openSense.className += ' begin'; world.className += ' begin'; logoSense.className += ' begin'; setTimeout(function() { viewPort.className = ' begin'; }, 4000); loadingAudio === 0 && Audio.play(); openSense.addEventListener("webkitAnimationEnd", function(){ // 动画结束时事件 console.log('动画执行结束啦!'); if (openSense) { // 执行完就抹除 openSense.parentNode.removeChild(openSense); } }, false); }
于是它变成了这样纸:
function loadOpenSenseAnimation() { Settings.isStart = true; $container.className += ' animated'; $mask.addEventListener("webkitAnimationStart", function() { // 动画开始时候播放 if (Settings.isVoice && Settings.loadingAudio === 0) { Settings.AudioPlayer.play(); } }, false); $container.addEventListener("webkitAnimationEnd", function(animation) { // 动画结束时事件 if (animation.animationName === Settings.EndingAnimatedName) { OpenSense.pass(); } }, false); }
这里我把setTimeout函数移除掉,使用animation-delay来接替setTimeout的位置,多个DOM操作被合并成了一个,把JS的消耗影响尽量降到最低。动画的声音播放使用webkitAnimationStart事件来监听,使音乐与动画的进行同步(这里需要注意webkitAnimationEnd/webkitAnimationStart的使用,每一个子节点的动画开始结束都会触发这个事件,需要判断一下animationName 确定是否是自己需要的动画事件),接下来我再次使用Timeline进行检查:
可以看到,在动画执行期间,从云层开始帧数就一直不高,结合此前的渲染重绘时间占用率过高,初步定为CSS属性使用不当。于是我查阅了CSS动画中所使用的属性:
根据Timeline掉帧的时间片段,结合这个时间段内产生作用的CSS属性,将一些可能影响性能的属性标记了出来,并进行了排除试验,我们发现,blur是损耗性能的主要因素,于是我对CSS做了一次排除优化,将blur,重复或不必要的属性进行剔除。
优化结果:
多次优化后,通过Timeline得到了下面的结果,我们可以看到,除了页面加载之初的一些掉帧,后面基本平稳在60帧,期间的无帧数是因为动画固定在logo处停了3s左右。
在线示例: http://huangxingbang.github.io/openSense/cloud.html
总结:
1.动画尽量使用opacity/translate/rotate /scale 这些可以让GPU分担工作的属性。
2.摈弃setTimeout在动画中的控制,动画播放时机的控制使用animation-delay来实现,如果需要精准控制,使用RequestAnimationFrame对动画进行更新。
3.使用webkitAnimationStart/webkitAnimationEnd对动画并行的任务进行开始/结束控制。
参考资料:
前端性能优化(CSS动画篇): https://segmentfault.com/a/1190000000490328
高性能 CSS3 动画: https://www.qianduan.net/high-performance-css3-animations/
声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
html中做开场动画,实例CSS3开场动画的制作与优化_html/css_WEB-ITnose相关推荐
- android 属性动画实例,Android属性动画完全解析 中 ,ValueAnimator和ObjectAnimator的高级用法...
大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画进行了 ...
- css动画定义,css3的动画(animation)属性的详解(附代码)
本篇文章给大家带来的内容是关于css3的动画(animation)属性的详解(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. css3动画(animation)具有以下属性: ...
- android 属性动画实例,Android 属性动画Animator工具类代码案例
代码分享-> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ packa ...
- html 浇水动画,纯CSS3实现动画插件spinkit
spinkit使用CSS3的特性实现多种动画效果,元素移动.放大缩小.翻转.进度条加载效果等等,使用了很多CSS3新的特性,是一个学习CSS3不错的网站. .spinner { width: 30px ...
- html倒计时动画,js+css3倒计时动画特效
js代码 const nums = document.querySelectorAll('.nums span'); const counter = document.querySelector('. ...
- html场景动画,HTML5 CSS3场景动画:热情的沙漠
CSS 语言: CSSSCSS 确定 body { background: black; } .container { position: relative; width: 800px; height ...
- html中怎么做扇形菜单,纯CSS3实现扇形动画菜单(简化版)实例源码
之前的一篇文章介绍这种效果的实现,但实现代码太过繁琐,所以在这里分享以下简化版的实现方法,有需要的可以参考学习. 原文章请点击这里 简化版完整实例 CSS3扇形动画菜单 *{padding: 0; m ...
- 使用css3的动画模拟太阳系行星公转
本文介绍使用css3的animation画一个太阳系行星公转的动画,再加以改进,讨论如何画椭圆的运行轨迹.然后分析京东和人人网使用animation的实际案例,最后结合css3的clip-path做一 ...
- html5+css3实现动画、逐帧动画效果
上篇博文中讲明了html5+css3实现2D-3D动画效果,介绍了html5中2d.3d的运用,顺便简明的提到了动画,而本篇将更加详细的说明动画的各运用及说明. 首先我们需要了解css3中动画的意思, ...
最新文章
- Django 第三方引用富文本编辑器6.1
- 再谈工作的主动性和有效提问
- oracle虚拟机 centos6.5,虚拟机oracle virtualbox 上安装centos6.5 网络设置
- elk之elasticsearch(二)
- (网页)Uncaught ReferenceError: pageImport is not defined
- jQuery获取select onChange的值
- Qt QT的I/O流 QT输入输出
- 疫情下的创业品牌如何逆风翻盘?
- 交叉验证(Cross Validation)简介
- 如何在android上编程,如何在Android中以编程方式与USSD对话框进行交互
- pandas最快入门(一)-读取与数据结构
- 显卡 内存分配 linux,玩转笔记本显卡共享显存设置
- 蕃茄田宋姝梦:科技赋能时代,儿童在线艺术教育的思考
- Linux系统命令行常识问答2
- 被马斯克热炒的人形机器人Optimus“擎天柱“,中国厂商或后来居上
- YoLo: You Only Look Once: Unified, Real-Time Object Detection译文
- 关于阿里云与mangoDB的关系,以及uni-app基于阿里云打包H5以及app的讲解及注意事项
- BSC智能分红代币合约可分其他代币|含营销钱包|通缩|回流|直接部署可用
- 使用油猴子对 Eureka 网址进行自定义修改
- LIMS如何有效降低实验室风险
热门文章
- ROS中odom、map坐标系的理解
- 基于阿里云函数计算实现需要用到超大依赖包的 Python 无服务器计算
- Android app 上传到google play,需要设置 隐私政策声明,kotlin命令行传值
- vue 解决ie11兼容问题
- PPT计算机应用考试基础考试,《计算机应用就基础(网考)》“上机考试”答疑.ppt...
- 【adoo】Van Emde Boas trees
- 重装 iTunes 错误代码 42401 解决办法
- windows下jenkins的安装
- python 的没落_随着python的崛起,Java是否会在未来几年没落?
- JSP药品进销存管理系统JSP药品管理系统JSP药品进销存系统)JSP医药进销存系统JSP药品药店管理