【CSS】过渡动画
作者:mmseoamin日期:2023-12-02

目录

  • 过渡动画
  • 1 css 属性
    • 1.1 transform 变换(平移旋转缩放)
    • 1.2 animation 动画
      • 1.2.1 keyframes
      • 1.3 transition 过渡
      • 1.4 比较
      • 2 方式
        • 2.1 css 伪类
        • 2.2 vue 组件
          • 2.2.1 默认名称
          • 2.2.2 自定义名称
          • 2.2.3 自定义 class
          • 2.2.4 配合 animation
          • 2.2.5 多层
          • 2.2.6 封装
          • 2.3 vue 组件
            • 2.3.1 示例列表
            • 2.4 class 变化
              • 2.4.1 点击旋转
              • 2.4.2 点击持续旋转
              • 2.4.3 点击折叠收起
              • 3 效果
                • 3.1 淡入(fade in)
                • 3.2 上浮(fade up)
                • 3.3 左右摆动(wiggle)
                • 3.4 上下弹跳(bounceAround)
                • 4 性能考量

                  过渡动画

                  不加过渡动画,变化不太流畅

                  1 css 属性

                  MDN css transitions

                  1.1 transform 变换(平移旋转缩放)

                  w3school transform

                  • transform:用于元素的变形,显示变形后的状态,不是变形的过程,变形过程需要配合transition表示
                    • 2D 转换
                      • translate(50px, 100px) 平移
                      • rotate(20deg) 顺时针旋转 20 度
                      • rotateX(150deg) 绕其 X 轴旋转给定角度
                      • scaleX(2) 增大为其原始宽度的两倍
                      • scaleY(0.5) 缩减为其原始高度的一半
                      • scale(2, 3) 增大为其原始宽度的两倍和其原始高度的三倍
                      • skewX(20deg) 沿 X 轴倾斜 20 度
                      • skewY(20deg) 沿 Y 轴倾斜 20 度
                      • skew(20deg, 10deg) 沿 X 轴倾斜 20 度,同时沿 Y 轴倾斜 10 度
                      • matrix() 方法把所有 2D 变换方法组合为一个
                        • matrix(scaleX, skewY, skewX, scaleY, translateX, translateY)
                        • transform: matrix(1, -0.3, 0, 1, 0, 0); 函数描述函数描述matrix(n,n,n,n,n,n)定义 2D 转换,使用六个值的矩阵。matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n)定义 3D 转换,使用 16 个值的 4x4 矩阵。translate(x,y)定义 2D 转换,沿着 X 和 Y 轴移动元素。translate3d(x,y,z)定义 3D 转化。translateX(n)定义 2D 转换,沿着 X 轴移动元素。translateX(x)定义 3D 转化,仅使用用于 X 轴的值。translateY(n)定义 2D 转换,沿着 Y 轴移动元素。translateY(y)定义 3D 转化,仅使用用于 Y 轴的值。translateZ(z)定义 3D 转化,仅使用用于 Z 轴的值。scale(x,y)定义 2D 缩放转换,改变元素的宽度和高度。scale3d(x,y,z)定义 3D 缩放转换。scaleX(n)定义 2D 缩放转换,改变元素的宽度。scaleX(x)定义 3D 缩放转换,通过给定一个 X 轴的值。scaleY(n)定义 2D 缩放转换,改变元素的高度。scaleY(y)定义 3D 缩放转换,通过给定一个 Y 轴的值。scaleZ(z)定义 3D 缩放转换,通过给定一个 Z 轴的值。rotate(angle)定义 2D 旋转,在参数中规定角度。rotate3d(x,y,z,angle)定义 3D 旋转。rotateX(angle)定义沿 X 轴的 3D 旋转。rotateY(angle)定义沿 Y 轴的 3D 旋转。rotateZ(angle)定义沿 Z 轴的 3D 旋转。skew(x-angle,y-angle)定义 2D 倾斜转换,沿着 X 和 Y 轴。skewX(angle)定义 2D 倾斜转换,沿着 X 轴。skewY(angle)定义 2D 倾斜转换,沿着 Y 轴。perspective(n)定义 3D 转换元素的透视视图。

                          1.2 animation 动画

                          w3school animation

                          animation: [ * animation-name] [ * animation-duration]
                            [animation-timing-function] [animation-delay] [animation-iteration-count]
                            [animation-direction] [animation-fill-mode] [animation-play-state];
                          
                          • animation:动画
                            • *animation-name:关键帧的名字,该参数必需。
                            • *animation-duration:动画持续的时间,该参数必需。
                            • animation-timing-function:定时器函数,默认是ease。
                            • animation-delay:动画效果多少秒后开始,默认为0。
                            • animation-iteration-count:动画重复的次数,可以指定为一个整数,表示多少次,默认值是infinite关键字,表示无限次。
                            • animation-direction:动画方向,可能的值为forward、backward或alternating,默认值为normal。
                            • animation-fill-mode:默认值为none。
                            • animation-play-state:动画默认是否生效,默认值为running。

                              1.2.1 keyframes

                              MDN keyframes

                              • 关键帧 @keyframes 规则通过在动画序列中定义关键帧(或 waypoints)的样式来控制 CSS 动画序列中的中间步骤。和 转换 transition 相比,关键帧 keyframes 可以控制动画序列的中间步骤。
                                @keyframes myname {
                                  0% {
                                    top: 0px;
                                  }
                                  25% {
                                    top: 200px;
                                  }
                                  50% {
                                    top: 100px;
                                  }
                                  75% {
                                    top: 200px;
                                  }
                                  100% {
                                    top: 0px;
                                  }
                                }
                                
                                keyframes rotation {
                                  from {
                                    transform: rotate(90deg);
                                  }
                                  to {
                                    transform: rotate(450deg);
                                  }
                                }
                                

                                1.3 transition 过渡

                                transition: [ * transition-property] [ * transition-duration]
                                  [transition-timing-function] [transition-delay];
                                
                                • transition: 该状态变至其他状态的过渡过程
                                  • 单个属性:transition: background-color 2s;
                                  • 多个属性:
                                    • transition: background-color 2s, height 1s ease-in-out;
                                    • transition: width 2s, height 2s, transform 2s;
                                    • transition-property: 元素的哪一个 CSS 属性需要过渡效果,该参数必需
                                      • all:全部属性
                                      • transition-duration: 过渡效果的持续时间,该参数必需
                                      • transition-timing-function: 定时函数,默认是ease
                                        • linear:线性运行,各个时刻速度都一样。
                                        • ease: 快速加速,然后逐渐减速,CSS 的默认值。
                                        • ease-in:逐渐加速,结尾时变快,适用于退出页面显示的元素。
                                        • ease-out:开始时速度最快,然后逐渐慢下来,适用于进入页面显示的元素。
                                        • ease-in-out:主键加速然后变慢,与ease相似,但开始时加速较慢,适合那些在页面有着明确开始和结束的动画。
                                        • transition-delay: 过渡从多少秒以后开始,默认是0

                                          1.4 比较

                                          • animation 强调流程与控制,对元素的一个或多个属性的变化进行控制,可以有多个关键帧(animation 和 @keyframes结合使用)

                                          • transition 强调过渡,是元素的一个或多个属性发生变化时产生的过渡效果,同一个元素通过两个不同的途径获取样式,

                                            • 而第二个途径当某种改变发生(例如 hover)时才能获取样式,这样就会产生过渡动画。
                                            • 可以认为它有两个关键帧的 animation
                                            • 状态 a -> b:

                                              • width: 100->300
                                              • transition: width 2s;
                                              • 状态 b -> a:

                                                • width: 300->100
                                                • transition: width 6s;
                                                  a {
                                                    width: 100px;
                                                    transition: width 2s;
                                                  }
                                                  b {
                                                    width: 300px;
                                                    transition: width 6s;
                                                  }
                                                  

                                                  2 方式

                                                  2.1 css 伪类

                                                  w3school css 过渡

                                                  • 常需要应用过渡动画的伪类选择器

                                                    • :hover 当用户悬浮到一个元素之上的时候匹配。
                                                    • :active 在用户激活(例如点击)元素的时候匹配,点击时应用,松开就结束
                                                    • 原选择器:过渡前的状态、过渡的过程(该状态变至其他状态的过渡过程)

                                                    • 伪类选择器:过渡后的状态(可以只写有变更的样式)

                                                      /* 把鼠标悬停在 div 元素上,宽度变宽的过渡效果 */
                                                      div {
                                                        width: 100px;
                                                        height: 100px;
                                                        background: red;
                                                        transition: width 2s;
                                                      }
                                                      div:hover {
                                                        width: 300px;
                                                      }
                                                      

                                                      2.2 vue 组件

                                                      vue Transition

                                                      • 是一个内置组件
                                                      • 进入或离开可以由以下的条件之一触发
                                                        • 由 v-if 所触发的切换
                                                        • 由 v-show 所触发的切换
                                                        • 由特殊元素 切换的动态组件

                                                          在这里插入图片描述

                                                          • v-enter-from:进入动画的起始状态。在元素插入之前添加,在元素插入完成后的下一帧移除。
                                                          • v-enter-active:进入动画的生效状态。应用于整个进入动画阶段。在元素被插入之前添加,在过渡或动画完成之后移除。这个 class 可以被用来定义进入动画的持续时间、延迟与速度曲线类型。
                                                          • v-enter-to:进入动画的结束状态。在元素插入完成后的下一帧被添加 (也就是 v-enter-from 被移除的同时),在过渡或动画完成之后移除。
                                                          • v-leave-from:离开动画的起始状态。在离开过渡效果被触发时立即添加,在一帧后被移除。
                                                          • v-leave-active:离开动画的生效状态。应用于整个离开动画阶段。在离开过渡效果被触发时立即添加,在过渡或动画完成之后移除。这个 class 可以被用来定义离开动画的持续时间、延迟与速度曲线类型。
                                                          • v-leave-to:离开动画的结束状态。在一个离开动画被触发后的下一帧被添加 (也就是 v-leave-from 被移除的同时),在过渡或动画完成之后移除。

                                                            2.2.1 默认名称

                                                            
                                                            
                                                              

                                                            hello

                                                            .v-enter-active,
                                                            .v-leave-active {
                                                              transition: opacity 0.5s ease;
                                                            }
                                                            .v-enter-from,
                                                            .v-leave-to {
                                                              opacity: 0;
                                                            }
                                                            

                                                            2.2.2 自定义名称

                                                             ... 
                                                            
                                                            .fade-enter-active,
                                                            .fade-leave-active {
                                                              transition: opacity 0.5s ease;
                                                            }
                                                            .fade-enter-from,
                                                            .fade-leave-to {
                                                              opacity: 0;
                                                            }
                                                            

                                                            2.2.3 自定义 class

                                                            
                                                              

                                                            hello

                                                            2.2.4 配合 animation

                                                            
                                                              

                                                            Hello here is some bouncy text!

                                                            @keyframes bounce-in {
                                                              0% {
                                                                transform: scale(0);
                                                              }
                                                              50% {
                                                                transform: scale(1.25);
                                                              }
                                                              100% {
                                                                transform: scale(1);
                                                              }
                                                            }
                                                            .bounce-enter-active {
                                                              animation: bounce-in 0.5s;
                                                            }
                                                            .bounce-leave-active {
                                                              animation: bounce-in 0.5s reverse;
                                                            }
                                                            

                                                            2.2.5 多层

                                                            尽管过渡 class 仅能应用在 的直接子元素上,我们还是可以使用深层级的 CSS 选择器,在深层级的元素上触发过渡效果

                                                            在这种情况下,你可以通过向 组件传入 duration prop 来显式指定过渡的持续时间 (以毫秒为单位)。总持续时间应该匹配延迟加上内部元素的过渡持续时间

                                                            2.2.6 封装

                                                            
                                                            
                                                            
                                                            

                                                            2.3 vue 组件

                                                            是一个内置组件,用于对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果。

                                                            2.3.1 示例列表

                                                            
                                                              
                                                          • {{ item }}
                                                          • .list-move, /* 对移动中的元素应用的过渡 */
                                                            .list-enter-active,
                                                            .list-leave-active {
                                                              transition: all 0.5s ease;
                                                            }
                                                            .list-enter-from,
                                                            .list-leave-to {
                                                              opacity: 0;
                                                              transform: translateX(30px);
                                                            }
                                                            /* 确保将离开的元素从布局流中删除
                                                              以便能够正确地计算移动的动画。 */
                                                            .list-leave-active {
                                                              position: absolute;
                                                            }
                                                            

                                                            2.4 class 变化

                                                            过渡动画的 css 可以另起一个 css 文件书写

                                                            vue 点击图标旋转

                                                            2.4.1 点击旋转

                                                            
                                                            
                                                            

                                                            2.4.2 点击持续旋转

                                                            
                                                            
                                                            // 持续旋转
                                                            .rotation {
                                                              animation: rotation 2s infinite linear;
                                                            }
                                                            @keyframes rotation {
                                                              from {
                                                                transform: rotate(0deg);
                                                              }
                                                              to {
                                                                transform: rotate(359deg);
                                                              }
                                                            }
                                                            

                                                            2.4.3 点击折叠收起

                                                            
                                                            

                                                            把 v-if 改为两种 class 的转变,再加上过渡

                                                            
                                                            
                                                            .scroll {
                                                              box-sizing: border-box;
                                                              width: 440rpx;
                                                              font-weight: 300;
                                                              background: #ffffff;
                                                              border-radius: 5px;
                                                              border: 1rpx solid;
                                                              transition-property: all;
                                                              transition-duration: 0.1s;
                                                            }
                                                            .scroll--full {
                                                              border-color: #999999;
                                                              max-height: 155rpx;
                                                            }
                                                            .scroll--null {
                                                              border-color: #ffffff;
                                                              max-height: 0rpx;
                                                            }
                                                            

                                                            3 效果

                                                            • 下拉选择
                                                              • 下拉框:展开
                                                              • 下拉箭头:旋转
                                                              • 弹窗:缩放、淡入淡出
                                                              • 增删:移走

                                                                3.1 淡入(fade in)

                                                                @keyframes fade-in {
                                                                  0% {
                                                                    opacity: 0;
                                                                  }
                                                                  100% {
                                                                    opacity: 1;
                                                                  }
                                                                }
                                                                .fade-in {
                                                                  animation: fade-in 1s forwards linear;
                                                                }
                                                                
                                                                /* 淡入淡出 */
                                                                .v-enter-active,
                                                                .v-leave-active {
                                                                  transition: opacity 0.5s ease;
                                                                }
                                                                .v-enter-from,
                                                                .v-leave-to {
                                                                  opacity: 0;
                                                                }
                                                                

                                                                3.2 上浮(fade up)

                                                                @keyframes fade-up {
                                                                  0% {
                                                                    opacity: 0;
                                                                    transform: translateY(3em);
                                                                  }
                                                                  100% {
                                                                    opacity: 1;
                                                                    transform: translateY(none);
                                                                  }
                                                                }
                                                                .fade-up {
                                                                  animation: fade-up 3s cubic-bezier(0.05, 0.98, 0.17, 0.97) forwards;
                                                                }
                                                                

                                                                3.3 左右摆动(wiggle)

                                                                @keyframes wiggle {
                                                                  0%,
                                                                  7% {
                                                                    transform: rotateZ(0);
                                                                    opacity: 0;
                                                                  }
                                                                  15% {
                                                                    transform: rotateZ(-15deg);
                                                                    opacity: 1;
                                                                  }
                                                                  20% {
                                                                    transform: rotateZ(10deg);
                                                                  }
                                                                  25% {
                                                                    transform: rotateZ(-10deg);
                                                                  }
                                                                  30% {
                                                                    transform: rotateZ(6deg);
                                                                  }
                                                                  35% {
                                                                    transform: rotateZ(-4deg);
                                                                  }
                                                                  40%,
                                                                  100% {
                                                                    transform: rotateZ(0);
                                                                  }
                                                                }
                                                                

                                                                3.4 上下弹跳(bounceAround)

                                                                .animation {
                                                                	…
                                                                	animation: bounceAround 1.1s ease-in-out infinite;
                                                                }
                                                                @keyframes bounceAround {
                                                                	0% {transform:translateY(0);}
                                                                	20% {transform:translateY(-60px) rotate(0deg);}
                                                                	25%{transform:translateY(20px) rotate(0deg);}
                                                                	35%, 55%{transform:translateY(0px) rotate(0deg);}
                                                                	60% {transform: translateY(-20px) rotate(0deg);}
                                                                	100%{transform: translateY(-20px) rotate(360deg);}
                                                                }
                                                                

                                                                4 性能考量

                                                                CSS 制作动画属性大多是 transform 和 opacity 之类的。用这些属性制作动画非常高效,因为:

                                                                他们在动画过程中不会影响到 DOM 结构,因此不会每一帧都触发昂贵的 CSS 布局重新计算。

                                                                大多数的现代浏览器都可以在执行 transform 动画时利用 GPU 进行硬件加速。

                                                                相比之下,像 height 或者 margin 这样的属性会触发 CSS 布局变动,因此执行它们的动画效果更昂贵,需要谨慎使用。我们可以在 CSS-Triggers 这类的网站查询哪些属性会在执行动画时触发 CSS 布局变动。