漫谈CSS transform动画技术

本文中的例子在谷歌浏览器、火狐浏览器、Opera浏览器和Safari浏览器中能正常的运行,在IE9中,需要加上-ms-前缀才能正确的运行。

CSS动画的实现需要我们先建立一个动作,用特定的mouseover或其它事件触发它。一般不是让动作立即完成,而是指定一个动作的发生以及持续方案,让动作在一定时间间隔内完成。


早期版本的现代浏览器需要在CSS使用浏览器引擎标识前缀才能正确的应用CSS变换功能,火狐是-moz-,谷歌是-webkit-,Opera是-o-,IE10仍然需要-ms-前缀。

1. CSS transform 简介

CSS Transform效果是指通过在浏览器里让网页元素移动、旋转、透明、模糊等方法来实现改变其外观的技术。在CSS里定义的变化动作会在页面生成前应用到网页元素上,所以你看不到发生的过程。然而,这些变化动作也可以由mouseover或其它相似事件触发,这样我们就可以看到它的动作过程。下一节里我们将会看到这些。

在下面,我们放置了4个完全相同的用div做成的盒子,大小是 100x60px,边框宽2px。之后,我们设定-webkit-transform属性来让它发生不同的变化:

box 1 移动到右边:-webkit-transform: translate(3em,0);
box 2 顺时针旋转30度-webkit-transform: rotate(30deg);
box 3 移动到左下方:-webkit-transform: translate(-3em,1em);
box 4 尺寸放大两倍:-webkit-transform: scale(2);
box 1
box 2
box 3
box 4

如果没有经过变换,上面的四个盒子,除了第二个是红边框外,它们应该是完全一致的一字排开。但上面你看见了,它们发生了变化。如果你的浏览器不支持CSS3,是IE6或IE8,你可以从下面的图片中看到它们的变化效果。

css-transform

需要说的是,这些经过变换的元素中的文字仍然是可选中的,包括发生旋转的那个。被放大了的那个盒子的其它属性也相应发生了变化,比如它的边框和里面文字的大小都放大了。

2. 让页面动起来

CSS transform对于程序员来说是一种强大的工具,我会因想到未来这种技术的广泛采用而激动。而用-webkit-transition来让页面元素实现某些动画效果,这则更让人兴奋。在下面的四个盒子上移动你的鼠标。

box 1
box 2
box 3
box 4

你看到的还是上一节的那四个盒子,正处于它们的初始状态。当把鼠标移动到盒子上时,CSS的动作设置会触发一个1秒钟的动画。当鼠标离开时,动作会反转运行,所有盒子会回到它们的初始位置。我们并没有使用Javascript来实现这个,完全是HTML和CSS!

是不是很酷!但你要知道,这种CSS动画不仅能应用到移动元素上,还能应用到CSS的其它属性上,包括:透明度,颜色和其它很多属性。

在下面的例子中,左边的盒子本来很小,绿色,直角;右边的是大的,红框,圆角。把鼠标分别停在两个盒子上,会使 box 1 变成 box 2 的模样, box 2 变成 box 1 的模样。

box 1
box 2

同样,这些效果是用纯HTML和CSS实现的。如果不使用CSS变换技术,你需要同时改变盒子的大小、边框的颜色、盒子角的弧度。而使用CSS让这一切立即变成了一个1秒钟的动画。

3. 一个元素上的多重变换

对一个网页元素应用多个变化动作,你只需要将这些动作定义罗列到一起,中间中空格分开。本文标题下的目录块就是使用下面的这些样式:

<style type="text/css">

  #submenu {
    background-color: #eee;
    -webkit-transition: all 1s ease-in-out;
    -moz-transition: all 1s ease-in-out;
    -o-transition: all 1s ease-in-out;
    transition: all 1s ease-in-out;
  }
  #submenu:hover {
    background-color: #fc3;
    -webkit-transform: rotate(360deg) scale(2);
    -moz-transform: rotate(360deg) scale(2);
    -o-transform: rotate(360deg) scale(2);
    -ms-transform: rotate(360deg) scale(2);
    transform: rotate(360deg) scale(2);
  }

</style>

上面这段css的作用是,当你把鼠标悬停在目录上时,目录将会变色、旋转、放大一倍,并且这些动作将在1秒钟内完成。

下面是这个效果的一个截图视频,不支持CSS3的朋友们可以通过它看一下效果。

4. 起飞的火箭

下面是一个非常有趣的例子,我们把各种动画效果组合到一个动画里。也许你单从这些CSS代码就能知道将会有什么动作发生?

<style type="text/css"> 
  /* initial state */ 
  #outerspace {
    position: relative;
    height: 400px;
    background: #0c0440 url(/images/outerspace.jpg);
  }
  div.rocket {
    position: absolute;
    bottom: 10px;
    left: 20px;
    -webkit-transition: all 3s ease-in;
    -moz-transition: all 3s ease-in;
    -o-transition: all 3s ease-in;
    transition: all 3s ease-in;
  }
  div.rocket img {
    -webkit-transition: all 2s ease-in-out;
    -moz-transition: all 2s ease-in-out;
    -o-transition: all 2s ease-in-out;
    transition: all 2s ease-in-out;
  } 
  /* hover final state */
  #outerspace:hover div.rocket {
    -webkit-transform: translate(540px,-200px);
    -moz-transform: translate(540px,-200px);
    -o-transform: translate(540px,-200px);
    -ms-transform: translate(540px,-200px);
    transform: translate(540px,-200px);
  }
  #outerspace:hover div.rocket img {
    -webkit-transform: rotate(70deg);
    -moz-transform: rotate(70deg);
    -o-transform: rotate(70deg);
    -ms-transform: rotate(70deg);
    transform: rotate(70deg);
  }

</style>
rocket animation 火箭

#外太空

最好升级你的浏览器到最新版本,否则有可能无法正确的显示这个动画。

动画过程中点线描画的边框显示的是包裹火箭图片的DIV占用的空间。这个DIV在移动的同时,我们让它内部的火箭图片进行了旋转。多简单!

对于仍然使用传统浏览器的读者,我简单讲解一下当把鼠标移动到上面的外太空区域是发生了什么:火箭从左下角发射,飞到右上角,历时3秒钟,飞行的过程中,火箭会顺时针旋转70度,做飞行姿势。效果很基础,但足以显示潜力。

5. 多种速度应用

#stage

#block

在上面的动画中,我们应用了4种不同的速度控制。

当鼠标悬停在右边的这个区域时,蓝色的方块会旋转,颜色由蓝变红,并从左上角运动到右下角,历时2秒钟。

你会发现,方块的运动轨迹是弧线的,而不是直线的。这是因为我们对横向运动使用了ease-out(减速)速度控制属性,而竖向运动使用了ease-in(加速)速度控制属性。

另外一个特征是颜色的变化是发生在第一秒,而旋转动作是出现在第二秒。

这里的技巧就是,-webkit-transition的参数可以分开写,每个参数可以定义一组值。我们还是使用了-webkit-transition-delay,它能让某个动作延迟执行。

下面就是这段CSS代码:

#block {
  ... background: blue; ...
  -webkit-transition-property: left, top, background, -webkit-transform;
  -webkit-transition-duration: 2s, 2s, 1s, 1s;
  -webkit-transition-timing-function: ease-out, ease-in, linear, ease-in-out;
  -webkit-transition-delay: 0, 0, 0, 1s;
  ...
}
#stage:hover #block {
  left: 100px;
  top: 100px; background: red; -webkit-transform: rotate(360deg);
}

早期的Firefox并不支持transition-delay属性,需要使用-moz-transition-delay,并指明初始值, 所以,上面的代码需要写成0s, 0s, 0s, 1s

6. 用鼠标悬停一个元素上来控制另一个元素

有很多人想知道如何通过对一个元素的点击或悬停等事件来操控页面上的另一个元素。如果使用Javascript,我可以通过事件句柄来改变另一个元素的className,从而触发动作。这可能需要定义一个跟CSS transitionkeyframes相关的新类。

使用CSS,我们需要额外的语法来找到相关目标元素。可以使用的CSS选择符包括> (子元素), + (相邻元素) 和 ~ (普通目标元素) 组合操作符.

我们之前的例子里都需要直接把鼠标悬停到目标元素上,或它的容器上,而这里的这个例子,当你的鼠标悬停在第一个元素(红方块)上时会触发第二个元素(蓝方块)运动。

#box1
#box2

#stage2

下面是使用的CSS代码。这里当#box2触发悬停事件时,我们用+组合符来锁定相邻的目标方块#box2~组合符的用法更灵活,它能找到更远的元素。

#box2 {
  position: absolute;
  left: 120px;
  ...
  background: blue;
  ...
}
#box1:hover + #box2 {
  -webkit-transform: rotate(360deg);
  -moz-transform: rotate(360deg);
  -o-transform: rotate(360deg);
  -ms-transform: rotate(360deg);
  transform: rotate(360deg);
  left: 627px;
  background: yellow;
}

当然,我们还可以使两个方块一同运动:

#box3
#box4

#stage3

只是要注意,不要让被悬停的元素移出了你的鼠标位置,否则动画会复位。

这些例子只能在Webkit(Safari, 谷歌浏览器), 火狐浏览器和Opera浏览器里运行,在IE10或更高版本里也许好用,但没有试过,如有人验证过,请告诉我,谢谢。

(英文:The Art of Web.)

阅读余下内容
 

《“漫谈CSS transform动画技术”》 有 8 条评论

  1. box2变成box1后有可能会离开mouseover的区域,造成反复的循环了。

  2. 那个火箭…在手机上飞出去我就返回上一页啦…Safari. 不过博主介绍得很清楚。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注


京ICP备12002735号