浅谈 CSS3 的 Transform 动画技术让元素动起来
本文中的例子在谷歌浏览器、火狐浏览器、Opera 浏览器和 Safari 浏览器中能正常的运行,但是在 IE9 中,需要加上 -ms-
前缀才能正确的运行。
CSS 动画的实现需要我们先建立一个动作,用特定的 mouseover
或其它事件触发它。一般不是让动作立即完成,而是指定一个动作的发生以及持续方案,让动作在一定时间间隔内完成。
早期版本的现代浏览器需要在 CSS 使用浏览器引擎标识前缀才能正确的应用 CSS 变换功能,火狐是 -moz-
,谷歌是 -webkit-
,Opera 是 -o-
,IE10 仍然需要 -ms-
前缀。
https://www.wenjiangs.com/article/browser-prefix.html
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); |
如果没有经过变换,上面的四个盒子,除了第二个是红边框外,它们应该是完全一致的一字排开。但上面你看见了,它们发生了变化。如果你的浏览器不支持 CSS3,是 IE6 或 IE8,你可以从下面的图片中看到它们的变化效果。
需要说的是,这些经过变换的元素中的文字仍然是可选中的,包括发生旋转的那个。被放大了的那个盒子的其它属性也相应发生了变化,比如它的边框和里面文字的大小都放大了。
.showbox { float: left; margin: 4em 1em; width: 100px; height: 60px; border: 2px solid green; background-color: #fff; line-height: 60px; text-align: center; }
<div class="showbox" style="transform: translate(3em,0);">box 1</div> <div class="showbox" style="transform: rotate(30deg); border-color: red;">box 2</div> <div class="showbox" style="transform: translate(-3em,1em);">box 3</div> <div class="showbox" style="transform: scale(2);">box 4</div> <div style="clear: left;"></div>
让页面动起来
CSS Transform 对于程序员来说是一种强大的工具,我会因想到未来这种技术的广泛采用而激动。而用 -webkit-transition
来让页面元素实现某些动画效果,这则更让人兴奋。在下面的四个盒子上移动你的鼠标。
你看到的还是上一节的那四个盒子,正处于它们的初始状态。当把鼠标移动到盒子上时,CSS的动作设置会触发一个 1 秒钟的动画。当鼠标离开时,动作会反转运行,所有盒子会回到它们的初始位置。我们并没有使用 Javascript 来实现这个,完全是 HTML 和 CSS 代码。
是不是很酷!但你要知道,这种 CSS 动画不仅能应用到移动元素上,还能应用到 CSS 的其它属性上,包括:透明度、颜色和其它很多属性。
在下面的例子中,左边的盒子本来很小,绿色、直角;右边的是大的,红框、圆角。把鼠标分别停在两个盒子上,会使 box 1 变成 box 2 的模样, box 2 变成 box 1 的模样。
同样这些效果是用纯 HTML 和 CSS 实现的。如果不使用 CSS 变换技术,你需要同时改变盒子的大小、边框的颜色、盒子角的弧度。而使用 CSS 让这一切立即变成了一个1秒钟的动画。
点击这里查看示例:http://run.wenjiangs.com/code/#/?code=edSH8e29
单个元素的多重变换
对一个网页元素应用多个变化动作,你只需要将这些动作定义罗列到一起,中间中空格分开。本文标题下的目录块就是使用下面的这些样式:
<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秒钟内完成。
点击这里查看示例:http://run.wenjiangs.com/code/#/?code=NhwpdR30
起飞的火箭
下面是一个非常有趣的例子,我们把各种动画效果组合到一个动画里。也许你单从这些 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>
最好升级你的浏览器到最新版本,否则有可能无法正确的显示这个动画。
动画过程中点线描画的边框显示的是包裹火箭图片的 DIV 占用的空间。这个 DIV 在移动的同时,我们让它内部的火箭图片进行了旋转。
对于仍然使用传统浏览器的读者,我简单讲解一下当把鼠标移动到上面的外太空区域是发生了什么:火箭从左下角发射、飞到右上角、历时3秒钟,飞行的过程中,火箭会顺时针旋转 70 度,做飞行姿势。效果很基础,但足以显示潜力。
多种速度应用
在上面的动画中,我们应用了 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。
鼠标悬停一个元素上来控制另一个元素
有很多人想知道如何通过对一个元素的点击或悬停等事件来操控页面上的另一个元素。如果使用 Javascript,我可以通过事件句柄来改变另一个元素的 className,从而触发动作。这可能需要定义一个跟 CSS Transition 或 Keyframes 相关的新类。
使用 CSS,我们需要额外的语法来找到相关目标元素。可以使用的 CSS 选择符包括 > (子元素)、+ (相邻元素) 和 ~ (普通目标元素)组合操作符.
我们之前的例子里都需要直接把鼠标悬停到目标元素上,或它的容器上,而这里的这个例子,当你的鼠标悬停在第一个元素(红方块)上时会触发第二个元素(蓝方块)运动。
下面是使用的 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; }
当然我们还可以使两个方块一同运动,只是要注意,不要让被悬停的元素移出了你的鼠标位置,否则动画会复位。
这些例子只能在 Webkit(Safari、谷歌浏览器)、 火狐浏览器和 Opera 浏览器里运行,在 IE10 或更高版本里也许好用,但没有试过,如有人验证过,请告诉我,谢谢。
英文原文:The Art of Web
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论