animation动画实践

由于业务关系,有幸参与腾讯课堂app下载页面制作,原则上ie8、9可表现为静态版本,而高级浏览则为动画版本。在这把一些重要思想和中间遇到的一些问题记录下,以供知识积累及讨论交流。

区分浏览器

既然要实现高级浏览器与低级浏览器不同效果,所以必要的区分下浏览器,使用js给body添加class

var lte9 = document.all && !window.atob;

if(lte9){
    //$('body').addClass('lte9');
    document.documentElement.className += ' lte9'
}else{
    //$('body').addClass('modern');
    document.documentElement.className += ' modern'
}

全屏元素布局

背景图片(这个是不兼容的,可以通过js来解决,这里因为图片本身很大,所以直接忽略不兼容,设置background-position: center,那样即使有超大的屏幕,也可以实现居中显示):

background-size: cover;

由于是全屏设计,所以可能会遇到屏大屏小,元素参考点以中间为标准,向上下左右延展:

position: absoulte;
top: 50%;
left: 50%;
margin-left: npx;
margin-top: npx;

或者嵌套一层div,设置

display:table-cell;
vertical-align:midddle;

元素默认位置原则:

先按照psd稿设置所处位置,那样就不需要给lte9进行位置重置,高级浏览器再通过关键帧动画改变起点位置,注意动画中位置偏移应使用translate而不是top/left或margin值

进入动画

第一种是每次进入都有动画,第二种方案是只有第一次进入有动画,对于之后的滚动都是静态模式

如果采用第一种,我们把动画控制的class绑定在js切换的active上即可

如果采用第二种,就需要另起一个class,如这里用的on

动画元素一个个出现

因为动画元素得按照顺序一个个出现,所以在运动之前视觉上是看不见的。这里有两种方法处理:

  • 默认设置动画元素的opacity为0,再给lte9的重置为1
  • 默认不处理,给modern的设置opacity为0,这里采用第二种,给高级浏览器动画元素设置opacity为0

缩放动画

默认缩放动画统一采用scale,但是特殊情况除外

如果要保持某些像素不虚则不适合使用scale,因为在扩大的时候就会变虚,如波纹,如果通过border或box-shadow扩展出来的都比较粗且虚,所以使用width和height改变大小,通过translate改变位移来实现扩展动画

如果使用scale缩放背景图片也虚得一塌糊涂,所以放弃背景图片而采用img标签,设置img的width:100%;,scale父元素的时候,img也会响应的扩展,且不影响画质,第一屏的两层切换就是用了在scale的元素中使用了img,而非直接背景图

多个相当元素依次进入动画

通过设置animation-delay来依次进入动画,如流星,波纹圆圈

.meteor-list .meteor-item{
    animation: meteoFlush 2.4s 0.12s linear infinite;
}
.meteor-list .item--2{
    animation-delay: 1.3s;
}
.meteor-list .item--3{
    animation-delay: 0.8s;
}

infinite动画中间有空档

如流星划过,动画应该是持续的,中间可能隔段时间又重新开始,如动画时间为1.2s,而间隔时间为1.2s。就可以通过设置动画时间为2.4s,而关键帧的设置可以在50%的时候就到达运动结束的位置,也就是50%-100%这段时间其实就是空出来的间隔时间。

.meteor-list .meteor-item{
    animation: meteoFlush 2.4s 0.12s linear infinite;
}

[@-webkit-keyframes](/user/-webkit-keyframes) meteoFlush{
    0%{
        opacity: 0;
        transform: translate3d(55px, -35px, 0);
    }
    25%{
        opacity: 1;
    }
    50%, 100%{
        opacity: 0;
        transform: translate3d(-85px, 35px, 0);
    }
}

动画暂停

当进入第一屏的第二层时,流星动画暂停

.s-1-2-on .meteor-item {
  animation-play-state: paused;
}

多次动画

如“学习成就梦想”实现了三次动画,刚进入的时候是fade in动画,滚动进入第二层的时候是缩小动画,往回滚是放大动画

抓住最终结束状态,并设置为默认的css,这里最终结束状态有两个,一个是第一层的时候大小为原始大小,一个是第二层的时候大小为一半大小。

.s-1 .s-slogan {
  position: absolute;
  width: 588px;
  height: 93px;
  top: 50%;
  left: 50%;
  margin-left: -294px;
  margin-top: -230px;
  z-index: 20;
  opacity: 1;
}

.s-1-2-on .s-slogan {
  transform: scale(.5);
  transform-origin: center bottom;
  opacity: 1;
}

动画的实现通过class来控制,如刚进入的fade in动画,父元素追加classs-1-1-on

.s-1-1-on .s-slogan {
  animation: fadeIn 1.3s 1.1s cubic-bezier(.67,.01,.38,1) forwards;
}

进入第二层的时候,父元素追加classs-1-2-on in,离开的时候先把in换成out,再动画结束之后删除追加的s-1-2-on out

.s-1-2-on.in .s-slogan{
    animation: ttShrink 1s forwards;
}
.s-1-2-on.out .s-slogan{
    animation: ttShrink 1s reverse forwards;
}

[@keyframes](/user/keyframes) ttShrink{
    0%{
        transform: scale(1);
    }
    100%{
        transform: scale(.5);
    }
}

反向动画

见上面的in和out,注意正向和反向动画得把动画分别绑定在两个不同的class,而默认的class只负责设置为正向动画结束后停留的位置。

延迟动画

延迟的动画如果第一帧的透明度不是从0开始,得重新添加一个关键帧,不然会出现一个半透明的在等着动画。如:

.s-2.on .s-img-msg{
    animation: msgShow 0.2s 1s both;    
}
[@keyframes](/user/keyframes) msgShow{
    0%{
        opacity: 0;
        transform: scale(0.5);
    }
    1%{
        opacity: 0.5;
        -webkit-transform: scale(0.5);
    }
    100%{
        opacity: 1;
        transform: scale(1);
    }
}

因为opacity从0.5开始,而动画是延迟在1s后执行,所以如果不特殊处理,就意味着在opacity:0.5;的时候,会持续1s等待。这里将0%设置为opacity:0;,而把实际关键帧0.5放在了1%

多个动画结合于同一元素

第三屏对话框的动画,fade in和width动画结合

.on .chat-item--1 .item-text{
    animation-name: fadeIn, sizeExpanded1;
}
[@keyframes](/user/keyframes) fadeIn{
    0%{
        opacity: 0;
    }
    100%{
        opacity: 1;
    }
}
[@-webkit-keyframes](/user/-webkit-keyframes) sizeExpanded1 {
    0% {
        height: 0;
        width: 0;
    }
    100% {
        height: 85px;
        width: 408px;
    }
}

多帧动画,通过多帧控制实现弹簧效果

可通过关键帧来控制

[@keyframes](/user/keyframes) qrFlip{
    0%{
        opacity: 0;
        transform: rotateX(50deg);
    }
    70%{
        transform: rotateX(-10deg);
    }
    80%{
        transform: rotateX(6deg);
    }
    90%{
        transform: rotateX(-4deg);
    }
    95%{
        transform: rotateX(2deg);
    }
    100%{
        opacity: 1;
        transform: rotateX(0);
    }
}

最后,对于lte9其实也可以采用js来实现动画,这里就不作讨论了。总之,css3动画是个比较丰富的课题,只有一步步去探索,才会实现更大的可能。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏互联网杂技

移动端开发的一些技巧

开篇语 最近接手了一个移动端的项目。个人感觉是自己做得比较快而且比较健壮的一个。。。移动端最主要就是页面要适用不同的手机屏幕,ipad等。下面就分享一些技巧,让...

26010
来自专栏九彩拼盘的叨叨叨

学习纲要:CSS 基础概念

451
来自专栏Elson的web征途

30分钟彻底弄懂flex布局

目前在不考虑IE以及低端安卓机(4.3-)的兼容下,已经可以放心使用flex进行布局了。什么是flex布局以及它的好处,这里就不再赘述。

1056
来自专栏一“技”之长

Bootstrap响应式前端框架笔记十八——导航滚动监听

    Bootstrap框架中提供了十分方便的方法来使用导航关联内容快,并且开发者可以监听滚动进行导航按钮的切换,示例如下:

511
来自专栏V站

自适应丨Html5响应式(自适应)网页设计

viewport是网页默认的宽度和高度, 上面这行代码的意思是:网页宽度默认等于屏幕宽度(width=device-width), 原始缩放比例(initia...

1555
来自专栏前端知识分享

第54天:原生js实现轮播图效果

一系列的大小相等的图片平铺,利用CSS布局只显示一张图片,其余隐藏。通过计算偏移量利用定时器实现自动播放,或通过手动点击事件切换图片。

631
来自专栏QQ空间开发团队的专栏

Android相机开发那些坑

这篇文章总结了Android相机开发的相关知识、流程,以及容易遇到的坑,希望能帮助今后可能会接触Android相机开发的朋友快速上手,节省时间,少走弯路。

22.9K5
来自专栏青玉伏案

iOS开发之仿射变换示例总结

本篇博客比较简单,但还是比较实用的。其中的示例依然使用Swift3.0来实现,该博客算是下篇博客的一个引子,因为我们下篇博客要介绍使用Swift开发iOS应用中...

1818
来自专栏向治洪

实用Android 屏幕适配方案分享

真正可用,并且简单易行,可以在多个屏幕大小和屏幕密度上有良好表现的Android 屏幕适配方案,已用在一款成熟互联网应用中,效果还不错。 ? 说起andro...

21210
来自专栏mySoul

事件冒泡和传播

这还要从遥远的荒诞说起,两家网景和ie,为了能争夺市场,互相使用相反的技术,当网景使用事件传播的时候,ie使用事件冒泡。(两个正好相反)这个时候w3c来了,为了...

1126

扫码关注云+社区