说到动画, 其实很多人心中都会有一种抵触的情绪 总是认为动画并不是项目内需要的. 并且动画也不一定是项目内必须的东西, 所以很多人并不是很在意这个玩意儿. 但是我想说的是: 区别一个人的价值并不是在完成项目的能力, 而是将项目优化的程度. 而动画正式如此, 他并不是你的必须品 但是能让你的能力更上一个台阶.
一, 什么是动画?
说到动画, 在很多的眼里 都会认为动画是一个可有可无的东西. 因为在很多程序员的日常开发中, 动画基本都是没有被用到的. 我们这里来谈到动画会不会有点多余呢?
正如我前面说到, 动画并不是项目中的必需品, 但却是项目的润滑剂. 因为它能很大程度上能增强用户的体验. 说了这么多, 究竟动画是什么呢?
动画是使元素从一种样式逐渐变化为另一种样式的效果. 并且动画能够改变任意多的样式任意多的次数.
怎么理解这句话呢? 就直接从动画的属性开始说起吧.
二, 谈一谈动画的基础属性
前面一个小节, 简单介绍了一下动画究竟是什么. 这章我就用动画的 API 来讲讲解一下动画的定义. 首先来看下面一段代码:
效果如下:
效果. gif
从上面的效果图我们可以发现: 原本静止的组件运动了起来. 首先我们来谈一谈其中用到动画的属性值:
@keyframes 关键帧
关键帧的作用是用来创建动画的. 而动画的原理就是将一套 CSS 样式逐渐变化成另一套样式. 他可以接收另种类型的参数: from/to 和百分数, 其语法为:
- @keyframes animationname {
- keyframes-selector {
- CSS-styles;
- }
- }
- animation-name
- animation-duration
再一看下面的两个属性: animation-name 和 animation-duration. 其含义分别代表动画的名称和一组动画完成的时间. 从这两个命名的规则是不是让我们想起了之前讲过的过渡呢?
我想说是的: 不仅这两个属性的含义和过渡中的两个属性类似, 并且还包含过渡中的另外两个属性:
animation-timing-function: 动画的速度曲线. 默认是 "ease"
animation-delay: 动画执行的延时时间
以上这四个属性的含义和使用的方法和前面一篇文章的过渡用法类似, 这里我就不多加赘述了. 那么既然这里都说了, 动画的效果和过渡差不多 那么我们为什么还要花费心思来创造出动画呢? 来仔细看我细细为您讲解出来吧, 首先来看下面一段代码:
- @keyframes move {
- 0% {
- top:0px;
- }
- 25%{
- top: 20px
- }
- 50% {
- top: 40px
- }
- 75% {
- top: 20px
- }
- 100% {
- top:0;
- }
- }
- .test {
- width: 20px;
- height: 20px;
- background-color: red;
- }
- .test:hover{
- animation-name: move;
- animation-duration: 3s;
- animation-iteration-count: infinite;
- animation-timing-function: linear;
- position:relative;
- }
效果如下:
效果. gif
从上面的代码我们就可以发现, 动画与过渡的第一个区别: 过渡只能代表一个状态到另一个状态的过程, 并不能重复, 而动画中增加了 animation-iteration-count 是来控制动画执行的次数, 该参数可接收的是一个整数, infinite 代表无限次.
再来看一段代码:
- @keyframes move {
- 0% {background:red; left:0px; top:0px;}
- 25% {background:yellow; left:40px; top:0px;}
- 50% {background:blue; left:40px; top:40px;}
- 75% {background:green; left:0px; top:40px;}
- 100% {background:red; left:0px; top:0px;}
- }
- .test {
- width: 20px;
- height: 20px;
- background-color: red;
- }
- .test:hover {
- animation-name: move;
- animation-duration: 1s;
- animation-iteration-count: infinite;
- animation-timing-function: linear;
- animation-direction:alternate;
- position:relative;
- }
效果如下:
效果. gif
从上面的效果我们可以清楚的发现: animation-direction 可以用来定义奇数次是否应该轮流反向播放动画.
我们再来看一个代码:
- @keyframes move {
- 0% {left:0px;}
- 100% {left:60px;}
- }
- .runner {
- width: 20px;
- height: 20px;
- animation-name: move;
- animation-iteration-count: 1;
- animation-timing-function: linear;
- position: absolute;
- }
- .user1 {
- background: red;
- animation-duration: 1s;
- }
- .user2 {
- background:black;
- animation-duration: 1s;
- animation-fill-mode: forwards;
- top:30px;
- }
- .user3 {
- background:red;
- animation-duration: 1s;
- animation-iteration-count: infinite;
- top:60px;
- }
- .playground {
- position: relative;
- height: 90px;
- }
- .stop {
- animation-play-state:paused;
- }
- <div class="playground">
- <div class="runner user1"></div>
- <div class="runner user2"></div>
- <div id=user3 class="runner user3"></div>
- </div>
- <button id="test_btn" onclick="myBtnClick()"> 暂停 </button>
- <script type="text/javascript">
- function myBtnClick(){
- document.getElementById("user3").classList.add("stop")
- }
- </script>
效果如下:
效果. gif
从上面的现象可以发现: animation-fill-mode 可以更改动画完成时的位置, 而 animation-play-state 能停止动画, 下面我们来用书面语言描述一下:
animation-play-state: 表示动画是否正在运行或者是暂停. 主要用途用于 JS 中来停止动画, 这个用的不多 不知道如何举例
animation-fill-mode: 表示对象动画时间之外的状态.
这里值得说明的是: animation-fill-mode 有四个可选值:
1, none 不改变默认行为.
2, forwards 当动画完成后, 保持最后一个属性值 (在最后一个关键帧中定义).
3, backwards 在 animation-delay 所指定的一段时间内, 在动画显示之前, 应用开始属性值 (在第一个关键帧中定义).
4, both 向前和向后填充模式都被应用.
三, 怎么来学习动画呢?
前面一节基本都将动画的效果都简单的阐述了一遍, 但是对于那种初学者来说, 在学习的时候基本一学就懂, 但是应用的时候就不怎么会, 难以下手. 针对这种问题, 作为程序员第件事儿就是应该想到的就是: 从模仿中学习.
怎么理解从模仿中学习呢? 在刚开始学习某项技术的时候, 我们应该去读一下同类技术比较成熟的写法. 从模仿到使用, 再进行改装.
在这里, 我就给大家介绍一个比较好的库: animate.CSS. 为什么介绍这个库呢? 因为它里面就涵盖了大多数的动画效果, 并且源码也是可以下载的. 我们可以通过使用它的效果来熟悉动画, 学习动画等等.
该如何来使用他呢? 来看下面一段代码, 说一下它的常规使用方法:
- // 引入 animate.CSS
- <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css">
- .test {
- width: 100px;
- height: 100px;
- background: red;
- margin: 100px;
- }
- .test:hover {
- animation: wobble 1s;
- }
- <div class="test"></div>
效果如下:
效果. gif
这里值得注意的两点:
animate 是前面所有 API 的总和, 我们可以用简写, 具体的 API 有:
animation: name duration timing-function delay iteration-count direction fill-mode;
wobble 是 animate 里面写好的动画效果, 我们在使用的时候可以直接进行引入 具体的效果 我们可以去官网里面查询更多.
我这里呢? 就简单的介绍了 animate.CSS 中的一个动画效果, 具体的还有更多, 官网也有效果 有兴趣的可以学习一下.
四, 简单的介绍一下 vue 中如何使用动画
前面谈到了动画的普通用法, 那么作为一个 vue 框架的使用者, 就不得不提到动画在 vue 中的应用了. 首先我们在介绍使用动画的使用之前, 我们首先介绍一个 vue 中特有的标签 transition, 该标签可以给
条件渲染 (使用 v-if)
条件展示 (使用 v-show)
动态组件
组件根节点
任意一种情况添加过渡 / 动画效果.
来看下面一段代码:
- <!DOCTYPE HTML>
- <HTML>
- <head>
- <meta charset="utf-8">
- <title>
- 动画
- </title>
- <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css">
- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.9/dist/vue.js">
- </script>
- <style type="text/css">
- .area{ width: 100px; height: 100px; } .red { background: red; } .yellow{
- background-color: yellow; } .fade-enter-active, .fade-leave-active { transition:
- opacity .5s; } .fade-enter, .fade-leave-to { opacity: 0; }
- </style>
- </head>
- <body>
- <div id="app">
- <button @click="isSelect=!isSelect">
- {{isSelect?'红色':'黄色'}}
- </button>
- <transition-group name="fade">
- <div class="area red" v-if="isSelect" key="red">
- </div>
- <div class="area yellow" key="yellow" v-else>
- </div>
- </transition-group>
- </div>
- <script type="text/javascript">
- new Vue({
- el: '#app',
- data: {
- isSelect: false
- },
- methods: {}
- })
- </script>
- </body>
- </HTML>
效果为:
效果. gif
从上面的效果 = 可以发现, transition 可以给包裹的组件增加动画效果, 下面就针对上面的效果, 我们介绍一下 vue 关于动画效果 / 过渡效果的几个属性.
transition/transition-group
transition 的含义是: 当存在 transition 组件内的节点被插入或删除的时候, vue 会做如下处理:
自动嗅探目标元素是否应用了 CSS 过渡或动画, 如果是, 在恰当的时机添加 / 删除 CSS 类名.
如果过渡组件提供了 JavaScript 钩子函数, 这些钩子函数将在恰当的时机被调用.
如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡 / 动画, DOM 操作 (插入 / 删除) 在下一帧中立即执行.
transition 只能包裹单个组件, transition-group 能包裹多个组件.
动画过渡的类名
在过渡动画中, 存在下面六个属性值
1, v-enter: 定义进入过渡的开始状态. 在元素被插入之前生效, 在元素被插入之后的下一帧移除.
2, v-enter-active: 定义进入过渡生效时的状态. 在整个进入过渡的阶段中应用, 在元素被插入之前生效, 在过渡 / 动画完成之后移除. 这个类可以被用来定义进入过渡的过程时间, 延迟和曲线函数.
3, v-enter-to: 2.1.8 版及以上 定义进入过渡的结束状态. 在元素被插入之后下一帧生效 (与此同时 v-enter 被移除), 在过渡 / 动画完成之后移除.
4, v-leave: 定义离开过渡的开始状态. 在离开过渡被触发时立刻生效, 下一帧被移除.
5, v-leave-active: 定义离开过渡生效时的状态. 在整个离开过渡的阶段中应用, 在离开过渡被触发时立刻生效, 在过渡 / 动画完成之后移除. 这个类可以被用来定义离开过渡的过程时间, 延迟和曲线函数.
6, v-leave-to: 定义离开过渡的结束状态. 在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除), 在过渡 / 动画完成之后移除.
这里值得我们注意的点是, 如果在 transition 中没有设置 name 的时候, 默认是 v - 开头, 如果设置了 name 正如前面 fade 一样, 其中的类名就会演变成 fade - 开头.
前面既然说了这么多 vue 中使用动画的基础 (我们这里主要是来复习动画的, vue 的知识就不过多的来复习了), 那么我们如何在 vue 去使用 animate.CSS 呢? 来看下面一段代码:
- <div id="app">
- <button @click="isSelect=!isSelect"> 点击 </button>
- <transition enter-active-class="animated bounceIn"
- leave-active-class="animated rotateOut">
- <div class="area red" v-if="isSelect"></div>
- </transition>
- </div>
效果如下:
效果. gif
从上面的代码里面我们可以发现, 我们已经为组件增加上了 animate.CSS 的动画效果, 这里如何办到的呢?
首先我们再来介绍一下 vue 的自定义类:
- , enter-class
- , enter-active-class
- , enter-to-class
- , leave-class
- , leave-active-class
- , leave-to-class
分别对应前面过渡动画的六个属性值, 来自定义我们想要的效果和动画. 这里值得注意的是: 我们在使用 animate.CSS 的类名的时候, 一般都要前面加上 animated 类才能生效.
写在最后
动画其实是非常重要的, 他能给用户一种非常舒适的体验, 可以很大程度上面增加用户的体验, 所以我建议还是要多在项目中适当的增加动画. 另外, 我在最后给大家提到了 animate.CSS - 一个很优秀的动画库. 我提到这个库不是想说 让你们找到了一个比较好偷懒的办法, 而是想让你能从使用中淬炼技术, 学习他的用法, 兼容语法, 从而将动画达到融会贯通的地步.
来源: http://www.jianshu.com/p/fd7a333bbeef