CSS 的 animations (动画) 和 transitions(变换)擅于实现从点 A 到点 B 的直线运动,运动轨迹是直线路径。给一个元素添加了 animation 或者 transition 以后,无论你如何调整贝塞尔曲线,都无法让它沿着弧形路径运动。你可以通过自定义 timing function 属性,做出弹动的效果,但是它沿着 X 和 Y 轴相对移动的值永远是相同的。

与其使用 JavaScript 实现外观自然的运动,不如尝试用这种简单的方式:分层动画,绕过已有的限制。通过使用两个或多个元素实现动画效果,我们可以更加细粒度地控制某个元素的路径,沿着 X 轴运动使用一种 timing function ,沿着 Y 轴运动使用另一种 timing function 。

问题所在

当我们深入探讨解决方案之前,看看到底问题在哪。CSS animations 和 transitions 限制我们只能沿直线路径运动。元素总是沿着点 A 到点 B 的最短路径运动,如果我们另辟蹊径,告诉 CSS 沿着“更好的路径”,而不是“最短路径”运动呢?

用 CSS (开启硬件加速)实现两点之间的运动,最直截了当的方式是使用 transform 的 translate 在一定时间内移动某个元素。这就产生了直线运动。在 @keyframes 中,我们打算在 (0,0) 和 (100,-100) 间来回运动,见上图例子:@keyframes straightLine {

50% {

transform: translate3D(100px, -100px, 0);

}

}

.dot {

animation: straightLine 2.5s infinite linear;

}

这些看起来并不难懂,但我们稍等片刻,思考一下我们需要的解决方案,拆分开来的动画,视觉上长什么样子呢。

0% 时,元素从 (0,0) 出发,50% 时,我们用了 translate3D(100px, -100px, 0) 把它移动到 (100,-100),然后原路返回。换句话说,我们把元素向右移动了 100px,向上移动了 100px,两个方向联合作用使元素沿着一个角度运动。

解决方案:每个轴执行自己的动画函数

那么,原先展示的例子中我们如何实现的弧形路径呢?为了让创建的路径不是直线,我们想让元素沿 X 轴和 Y 轴的运动速度不同步。

先前例子中都用到了 linear 线性运动函数,如果我们给运动的元素包裹一个容器,我们可以为 X 轴应用一种动画函数,Y 轴应用另一种动画函数。以下例子,我们在 X 轴使用 ease-in ,Y 轴使用 ease-out 。

每个轴元素的具体实现

不幸的是,我们不能只把 transform 动画简单叠加:因为只有最后声明的动画会执行。那么我们如何把两个动画效果联合起来呢?可以把一个元素放入另一个元素内部,给容器元素加一种动画,给里面的子元素添加另一种动画。

在以上例子中,你已经看到一个点沿着弧形路径运动,看到两个独立的元素一起做动画,只不过容器元素是完全透明的。为了清晰地看到两个元素沿着弧形路径是如何相互作用的,我们给容器元素加个边框看看呗:

那个点藏在带边框的盒子内部,跟随盒子一起沿 X 轴远动,同时它自己又在 Y 轴方向上下运动。去掉容器盒子的边框,我们就得到了弧形路径。与其在 HTML 中用两个元素,还不如用伪元素实现嘞。如果 HTML 是这样:

我们可以添加伪元素:.dot {

/* 容器:沿 X 轴运动 */

}

.dot::after {

/* 黑点儿,沿 Y 轴运动 */

}

然后,我们需要两块独立的动画代码:X 轴,Y 轴各一块。注意一处用了 ease-in,另一处用了 ease-out:.dot {

/*省略 一些布局代码...*/

animation: xAxis 2.5s infinite ease-in;

}

.dot::after {

/* 渲染小黑点儿*/

animation: yAxis 2.5s infinite ease-out;

}

@keyframes xAxis {

50% {

animation-timing-function: ease-in;

transform: translateX(100px);

}

}

@keyframes yAxis {

50% {

animation-timing-function: ease-out;

transform: translateY(-100px);

}

}

加上 WebKit 前缀,用一些自定义的贝塞尔曲线代替 ease-in 和 ease-out,我们就可以实现文章最开头展示的效果:.demo-dot {

-webkit-animation: xAxis 2.5s infinite cubic-bezier(0.02, 0.01, 0.21, 1);

animation: xAxis 2.5s infinite cubic-bezier(0.02, 0.01, 0.21, 1);

}

.demo-dot::after {

content: '';

display: block;

width: 20px;

height: 20px;

border-radius: 20px;

background-color: #fff;

-webkit-animation: yAxis 2.5s infinite cubic-bezier(0.3, 0.27, 0.07, 1.64);

animation: yAxis 2.5s infinite cubic-bezier(0.3, 0.27, 0.07, 1.64);

}

@-webkit-keyframes yAxis {

50% {

-webkit-animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1);

animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1);

-webkit-transform: translateY(-100px);

transform: translateY(-100px);

}

}

@keyframes yAxis {

50% {

-webkit-animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1);

animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1);

-webkit-transform: translateY(-100px);

transform: translateY(-100px);

}

}

@-webkit-keyframes xAxis {

50% {

-webkit-animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64);

animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64);

-webkit-transform: translateX(100px);

transform: translateX(100px);

}

}

@keyframes xAxis {

50% {

-webkit-animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64);

animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64);

-webkit-transform: translateX(100px);

transform: translateX(100px);

}

}

以下是文章起始处的例子:

你可能注意到我们在所有例子中都用了 @keyframes ,这纯粹是因为我们想展示黑点儿往返的两种状态。如果只想实现点 A 至点 B 的运动,使用 transition 属性做分层动画同样好用。

如果有个绝对定位的元素,通过给 left 和 bottom 属性加特效,就可以实现弧形路径运动,单个元素就可以,不需要容器元素。为什么不这么做呢:它性能稍差一些,动画的每一帧都会引起重绘。使用带伪元素的分层动画,translate 属性又开了硬件加速,动画效果更好,性能也更高。译者自己搞了个绝对定位的例子:

android 属性动画 弧形,CSS分层动画可以让元素沿弧形路径运动相关推荐

  1. css实现圆环路径,笔记:CSS、canvas 和 SVG 分别实现元素沿环形路径运动动画

    CSS 部分 最早接触到使用 CSS 使元素以环形路径运动的办法来自于 Lea Verou 的书<CSS 揭秘>中第八章中的<沿环形路径平移的动画>.虽然随着 CSS 的发展部 ...

  2. html 路径线条动画,CSS分层动画可以让元素沿弧形路径运动

    CSS 的 animations (动画) 和 transitions(变换)擅于实现从点 A 到点 B 的直线运动,运动轨迹是直线路径.给一个元素添加了 animation 或者 transitio ...

  3. html弹跳动画效果,CSS弹跳动画效果的实现方法

    这是只用了一个div来做的小动画,纯粹利用CSS3的animation来完成,就像是一个正方形在地上弹跳,碰到地面的时候尖角还会压缩变圆,阴影的部分也会随着正方形升高而缩小,至于到底该怎么完成呢?让我 ...

  4. 使用UE4动画蒙太奇实现分层动画

    目标 在之前的博客<学习UE4官方第三人称模板中的内容>中,角色已经可以移动和跳跃了.这一篇将会在之前的基础上,增加一个"拳击"动作,而且想要在移动与跳跃的同时做&qu ...

  5. html边框环绕一周动画,环绕式CSS边框动画

    我正在尝试使用纯CSS获得类似环绕效果的边框动画. 现在我在做它的方式是:before和:after伪元素大小发生变化.一个用于顶部和右侧边框,一个用于底部和左侧边框. 但是,由于宽度和高度的差异,我 ...

  6. css4个伪元素,CSS_CSS3中的content属性使用示例,CSS中主要的伪元素有四个:befo - phpStudy...

    CSS3中的content属性使用示例 CSS中主要的伪元素有四个:before/after/first-letter/first-line,在before/after伪元素选择器中,有一个conte ...

  7. CSS3: 利用分层动画让元素沿弧形路径运动

    原文:Moving along a curved path in CSS with layered animation 翻译:涂鸦码龙 译者注:部分代码示例在原文中可以看效果(作者写在博文里面了-), ...

  8. Android 属性动画(Property Animation) ObjectAnimator的介绍

    先说下属性动画与视图动画的区别: 视图动画系统仅提供为 View 对象添加动画效果的功能,因此,如果您想为非 对象添加动画效果,则必须实现自己的代码才能做到.视图动画系统也存在一些限制,因为它仅公开 ...

  9. Android 属性动画(Property Animation) ValueAnimator 的介绍

    先说下属性动画与视图动画的区别: 视图动画系统仅提供为 View 对象添加动画效果的功能,因此,如果您想为非 对象添加动画效果,则必须实现自己的代码才能做到.视图动画系统也存在一些限制,因为它仅公开 ...

最新文章

  1. hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)
  2. NDK,动态链接库,JNI
  3. golang 结构体 slice 排序
  4. python井字棋ai_实现AI下井字棋的alpha-beta剪枝算法(python实现)
  5. 助农两年销量千万 “李佳琦公益”实现“造血式”帮扶
  6. truffle migrate 强制重新部署合约
  7. 基于预计算的全局光照技术
  8. 计算机专业英语 9次作业合集 从第九次到第一次
  9. CPI通常用于衡量计算机性能,2021考研408计算机组成原理习题:计算机的性能指标...
  10. Vue 事件修饰符(stop、prevent、self、capture、once、passive)
  11. Redis Redis主从架构(图灵学院)
  12. win10matlab2016启动卡,教你解决win10专业版开机卡死的方法
  13. oracle中的表别名怎么,Oracle 表别名
  14. 阿里云Linux服务器部署Mysql,JDK以及Tomcat教程
  15. c语言 for each循环,C#中foreach循环对比for循环的优势和劣势
  16. 为何上千名科技专家呼吁暂停大型AI研究?
  17. WEEK16 周记 限时CSP模拟——区间动态规划_宇宙狗的危机
  18. TCP-IP详解笔记5
  19. Linux命令 之 ifconfig命令
  20. 三星t5 android,同样是移动固态硬盘 三星T5为什么那么贵?

热门文章

  1. 为什么三层交换机无法替代路由器?
  2. 深耕大数据“试验田” 发掘新经济“钻石矿”
  3. 在C#中读取枚举值的描述属性
  4. selenium借助AutoIt识别上传(下载)详解
  5. Git忽略文件方法【转】
  6. Wince 启动程序并最小化
  7. 游戏杆编程心得二:如何判断按钮的有效按下
  8. 学生为什么要在CSDN写博客?
  9. 通过代码动态创建IIS站点
  10. 数据库高可用架构(MySQL、Oracle、MongoDB、Redis)