用CSS3制做版头动画

网易看游戏官网(kanyouxi.163.com/)(已下架),是我之前…css

怎样的动画?

这个动画并不算复杂,但包含了transform,rotate,translate,keyframes,缓动,和循环次数这几个重要的内容。好了,先看看动画效果,下面是录屏动画,也能够到网易看游戏官网(kanyouxi.163.com/)(已下架)上去看看。html

animation.gif

有几个关键点,按顺序分别为:html5

  1. 白色iPhone向上翻动,而后作几个小幅度抖动;
  2. 字幕从右边出现,把白色iPhone向左推进;
  3. 白色iPhone快到心头后,黑色iPhone也跟随出现;
  4. 大标题“网易看游戏”背景波浪式闪烁滚动。

下面让咱们咱们一个个来。css3

注:这是一个CSS3进阶实践文章,若是你对CSS3动画还不是很了解,请先看这里:CSS3动画,1分钟快速了解一下再回来。markdown

1. 向上翻动并抖动

这里有几个关键属性,详细使用方法能够进去看:@keyframestransform:rotate(deg);transform-origin:x,y;iphone

准备动画关键帧 @keyframes

@keyframes iphone-front{
    0% {
        transform:rotate(-30deg);
        transform-origin:125px 650px;
        }
    100% {
        transform:rotate(0deg); 
        transform-origin:125px 600px;
        }            
}
复制代码

咱们直接用百份比来做为帧点,由于后面还会把它再细分多个帧。工具

设置旋转与Anchor Point(锚点transform-origin:x,y;

transform:rotate(-30deg);
transform-origin:125px 650px;
复制代码

旋转是必须的,但为什么要修改Anchor Point呢?oop

Anchor Point,是借用了cocos2D里的说法,是指变换的原点。性能

由于transform的默认锚点是中心,即(50%,50%),在transform里Anchor Point属性就是transform-origin,如下是默认值:动画

transform-origin:50%,50%
复制代码

在支持3D的变换里,还有第3个数值:z,默认是0

若是不修改,就会以iPhone的中心为原点旋转,这不是咱们想要的效果,因此把它移到下方的水平中央去。

这个图片的宽度是250px,高度为525px,下方中央就是(125px,525px),但为了模拟实物在桌子上摇摆,还要往下移一些,通过尝试,咱们最终选择了(125px,650px),以下图示:

添加抖动与拟物

抖动其实也是几个关键帧组合的产物,首次旋转不是0度,而是过了一点点的10度,接着往返各两个关键帧,幅度逐渐减少。添加关键帧后的@keyframes改动以下:

@keyframes iphone-front{
    0% {
        transform:rotate(-30deg);
        transform-origin:125px 650px;
        }
    50% {
        transform:rotate(10deg);
        transform-origin:125px 600px;
        }
    75% {
        transform:rotate(-5deg);
        }
    100% {
        transform:rotate(0deg);
        }
}
复制代码

注意,上面33%位置的帧处,添加了一条transform-origin:125px 600px;,由于若是一成不变的锚点,会给人感受像是一个钟摆,太死板不够拟物化,想像一下:一个东西以某个抛物线落到地上,通过与地面碰撞,改变运动方向,最终慢慢停下来,因此咱们把中心点的高度也减少一点,让人看上去“不那么规律”。

在关键帧的时间点上,也模拟了慢出的缓动效果。所谓的动画感受作得好很差,也就是缓动效果作得如何,够不够接近物理世界给人的认知。

这个帧点也并不是最后的时间点,请继续往下看。

2. 字幕出现并推走iPhone

字幕出现

字幕在另一个元素,因此咱们新建一个关键帧组:

@keyframes content{
    0% { transform: translate3d(550px,0,0);}
    100% { transform: translate3d(0,0,0);}
}
复制代码

由于是iPhone动画先走,而后才是字幕,因此动画延时执行animation-delay

animation-delay:.2s;
复制代码

但为了两个关键帧组能更好的同步,不用算来算去,咱们也以这样作:

@keyframes content{
    0% { opacity: 0;}
    40% { transform: translate3d(550px,0,0); opacity: 0;}
    100% { transform: translate3d(0,0,0); opacity: 1; }
}
复制代码

先用透明度隐藏它,在40%才开始,在移动的过程再逐渐显示,让过程更平滑。

前面还说到,中间还要用字幕推iPhone一下,怎么作?

模拟碰撞

纯CSS3是作不了的,除非全程用JS进行,或者用Box2D进行碰撞判断。但咱们这里只是一个简单的走过场动画,不须要人机交互,也不会变化移动的距离,因此,咱们用一个变戏法,两个动画一块儿并行,在关键节点埋关键帧,即:字幕移动到iPhone位置时,iPhone才开始移动。

两个关键帧组结合起来就是:

@keyframes iphone-front{
    0% {transform:rotate(-30deg); transform-origin:125px 650px; opacity: 0;}
    20% {transform:rotate(10deg); transform-origin:125px 600px; opacity: 1;}
    30% {transform:rotate(-5deg);}
    38% {transform:rotate(0deg);}
    60% {transform: translate3d(0,0,0);  opacity: 1;}
    90% {transform: translate3d(-340px,0,0); }
    100% {transform: translate3d(-340px,0,0);}
}
@keyframes content{
    0% { opacity: 0;}
    40% { transform: translate3d(550px,0,0); opacity: 0;}
    60% { transform: translate3d(225px,0,0); opacity: 1; }
    80% { transform: translate3d(0,0,0); opacity: 1; }
    100% { transform: translate3d(0,0,0); opacity: 1; }
}

/*如下选择器略去了非动画属性设置,例如宽高等,咱们就当他们默认就是正确的值吧*/
.iphone-front{ 
    animation: iphone-front 1.8s ease-out forwards;
}
.content{
    animation: content 1.8s ease-out;
}
复制代码

能够看出,这里没有使用delay属性,是为了更直观的设置并行动画,你们都在60%的位置碰头,都使用了ease-out缓出。

为何iphone-front的100%帧处要重复90%的内容?由于咱们用了animation-fill-mode属性,值为forwards,即停在最后一帧,若是100%没有写,就会退回到最初状态了。

3. 黑色iPhone跟随出现

黑色iPhone的动画更简单,只是一个渐现加移动,一样也是另一个并行动画,不过此次能够用delay了,先预估一下大概出现的时间,能够获得从0.5s开始:

@keyframes iphone-back{
    0% { transform: translate3d(97px,0,0); opacity: 0;}
    40%{ opacity: 0; }
    50%{ transform: translate3d(0,0,0); opacity: 1;}
    100% {opacity: 1; }
}
.iphone-back-ani{
    animation: iphone-back 1.8s ease-out .5s forwards;
}
复制代码

这里不须要最后一帧重复写代码了,由于它原本就是(0,0,0),不会产生任何变化。

为什么用translate3d(x,y,z);而不用translateX(x)?由于早前有人认为这个效率会更高,特别在移动端性能更优。

查看手册:transform

4. 大标题背景波浪

这个不涉及transfrom,让前景与背景重叠在一块儿,背景图片在y轴不间断移动,无限循环,无缓动;关键的是这个背景图必须上下能无缝链接:

前景图

背景滚动图

@keyframes title{
    0% { background-position: 0 0;}
    100% { background-position: 0 -76px;}
}

.title-bg{
    width: 301px; 
    height: 61px; 
    position:absolute;
    top:0;
    left:0;
    z-index:1;
    background: url(title_text_bg.png) repeat-y;
    animation: title 1.2s linear;
    animation-iteration-count:infinite;
}
.title-front{
    width: 301px; 
    height: 61px;
    position:absolute;
    top:0;
    left:0;
    z-index:2;
    background: url(title_text_front.png) no-repeat;
}
复制代码

这是最简单的作法,适合大多数状况。也有另一些更高级的,例如使用mask,关于mask,有兴趣请看《CSS Masking》

其它效果

JS制做的气泡动画

结语

手写动画,虽然比较费时,但能让你了解现实原理。若是须要可视化制做,推荐一个在线工具给你们:cssanimate,相比其它生成器,优势是能够设置多个关键帧,并且能够经过鼠标拖动直接操做,推荐!

【完】