css揭秘实战技巧 - 过渡与动画[七]

1,334 阅读6分钟

全目录

本系列文章,主要是围绕css3属性,实现我们常见的各种效果,这些效果都是我们实战开发中经常可以用到的效果:

  1. css揭秘实战技巧- 背景与边框 [一]
  2. css揭秘实战技巧- 形状 [二]
  3. css揭秘实战技巧 - 视觉效果[三]
  4. css揭秘实战技巧 - 字体排印[四]
  5. css揭秘实战技巧 - 用户体验[五]
  6. css揭秘实战技巧 - 结构与布局[六]
  7. css揭秘实战技巧 - 过渡与动画[七]

前言

  1. 逐帧动画 - “加载中” 案例
  2. 闪烁效果
  3. 打字动画
  4. 状态平滑的动画

二:逐帧动画

以大家最常见的 “加载中” 的效果为例:

方案一:直接让设计给一个gif图片即可。

但是这种方案的缺陷就是gif本身是不透明的,而且我们无法去加一个特殊样式,只能依靠设计给什么样的效果,我们就显示什么样的效果。

方案二:采用js去实现,但是很麻烦。

方案三:完全采用css去实现,无需加载其他资源,而且可以定制开发。

首先,来一张背景图:

看到这张图,可能已经瞬间感觉离我们想要的效果已经不远了,只需要设置背景图片为该图片,并且通过backgroud-position去控制背景图片的位置,然后再加上动画不就是我们想要的效果了,我们来试一下:

width: 50px;
height: 50px;
background: url("./img/loader.png") 0 0;
background-size: cover;

这个时候,效果就是只显示第一张图片,接下来,我们添加动画

div{
    width: 50px;
    height: 50px;
    background: url("./img/loader.png") 0 0;
    background-size: cover;
    animation: loader 1s infinite;
}
@keyframes loader {
    to {
        background-position: -800px 0;
    }
}

此时,我们添加完动画以后,发现最后效果并不是我们想要的 ,为什么呢?这就回到了我们此节的标题,逐帧动画

默认情况下,动画的运行速度是按贝塞尔曲线运行的,可以简单理解为并不是匀速去运行的,那我们该怎么样调整速度呢? 使用step()函数,它可以传入一个参数,表示此次动画是分几步完成的,例如,step(8) 表示此次动画是分8部完成,也就是总共8帧,且逐帧匀速去执行的。

所以,最终代码如下:

div{
    width: 50px;
    height: 50px;
    background: url("./img/loader.png") 0 0;
    background-size: cover;
    animation: loader 1s infinite steps(8);
}
@keyframes loader {
    to {
        background-position: -800px 0;
    }
}

三:闪烁效果

用css可以实现各种类型的闪烁效果:例如,对整个元素,对文字颜色,对边框颜色等都是可以实现闪烁效果的,这里,我们以文字闪烁为例, 这也是最常见的一个效果,用于突出提示某些文字的信息。

实现思路:首先还是通过动画去控制文字的颜色,不同情况下,文字的颜色不同,这样带来的效果就是文字的闪烁效果。

初步代码如下:

//文字开始颜色为黑色,1s后颜色为透明,如此 循环闪烁
p{
    animation: blink 1s infinite;
}
@keyframes blink {
    to {
        color: transparent;
    }
}

此时的问题:当1s的动画结束以后,文字颜色又由透明变为黑色,此时这个过程是很生硬的直接跳回原来的颜色,那么,如何让文字更加平稳的显现,同时又可以让文字更加平稳的隐去,这是接下来要实现的关键。

啦啦啦 ,另外一个法宝属性就出来了:animation-direction

animation-direction 的 唯 一 作 用 就 是 反 转 每 一 个 循 环 周 期 (reverse),或第偶数个循环周期(alternate),或第奇数个循环周期 (alternate-reverse)。它的伟大之处在于,它会同时反转调整函数, 从而产生更加逼真的动画效果。

看了说明,可能还不太清楚,我们来看一下图片:

例如:alternate,是反转偶数的循环周期,正常我们颜色是从黑色变成透明,但是到了第二周期(偶数周期),由于进行了反转,此时颜色就成了从透明变成黑色,如此循环,就是我们上图中所看到的效果啦,这样看起来确实过度的更加平稳。

最终代码如下:

p{
    animation: blink 1s infinite alternate;
}
@keyframes blink {
    50% {
        color: transparent;
    }
}

四:打字动画

首先,我们来看一下效果:

实现思路:

让容器的宽度成为动画的主体:把所有文本包裹在这个容 器中,然后让它的宽度从 0 开始以步进动画的方式、一个字一个字地扩张到 它应有的宽度。你可能已经察觉到了,这个方法是有局限的:它并不适用于 多行文本 11 。然而幸运的是,在绝大多数情况下,我们把这种效果应用在类似 标题的单行文本上。

代码如下:

//html代码
<div>
    CSS is awesome!
</div>

//css代码
div{
    font-family: Consolas, Monaco, monospace; //这些都是等宽字体
    font-size: 30px;
    width: 15ch; 
    white-space: nowrap;
    overflow: hidden;
    border-right: .05em solid;
    animation: write 8s steps(15);
}
@keyframes write{
    from {
        width: 0
    }
}

注意:此处我们用到一个ch单位:在等宽字体中,“0”字形的宽度和其他所有字形的宽度是一样的。因 此,如果我们用 ch 单位来表达这个标题的宽度,那取值实际上就是字符的 数量:在这个例子中就是 15。

五:状态平滑的动画

首先,我们来看一个效果:点击查看,

效果描述:这张图 片原本是横幅的。圆形区域显露 出的是图片的右半部分,而当用 户的鼠标移到图上时,它会缓慢 地向左滚动,从而显露出原先被 裁掉的部分。在默认情况下,当 用户把鼠标移开时,图片会生硬 地跳回原始位置,这很容易让人 误以为 UI 崩坏了。因为这是一个 非常小的网站,而这张图片又非 常显眼,所以我实在无法对这个 问题视而不见

所以,接下来想要实现的效果的核心就是:如何手动的触发动画的执行,同时如何暂定动画的执行。

当然,答案很简单:animation-play-state ! 它就是为暂停动画专门设计的。

代码如下:

@keyframes panoramic {
    to { background-position: 100% 0; }
}
.panoramic {
    width: 150px; height: 150px;
    background: url("img/naxos-greece.jpg"); 
    background-size: auto 100%;
    animation: panoramic 10s linear infinite alternate; 
    animation-play-state: paused; //默认暂停动画
}
.panoramic:hover, .panoramic:focus { 
    animation-play-state: running; //鼠标附上去的时候,执行动画
}