vue3学习随便记12

过渡与动画

Vue 提供了一些抽象概念,可以帮助处理过渡和动画:

  • 组件进入DOM和离开DOM的钩子,在 CSS 和 JS 均可用,使用内置组件 <transition>
  • 过渡模式,在过渡期间编排顺序
  • 处理多个元素就地更新的钩子,使用 <transition-group>组件,通过 FLIP技术提高性能
  • 使用 watchers 处理应用中不同状态的过渡

除了这些抽象概念,直接绑定 class 和 style 应用CSS动画和过渡,对于简单的用例也够了。

基于class的动画和过渡

    <div id="app">
        点击该按钮以做你不应做的事:
        <div :class="{ shake: noActivated }">
            <button @click="noActivated = true">在此点击</button>
            <span v-if="noActivated">Oh no!</span>
        </div>
    </div>
    <script>
        const { createApp } = Vue
        const app = createApp({
            data() {
                return {
                    noActivated: false
                }
            }
        })
        const vm = app.mount('#app')
    </script>

点击按钮后,按钮左右振动几下,右边显示Oh no!

这个动画的关键是绑定的CSS class,以下是CSS部分

        body {
            margin: 30px;
        }

        button {
            background: #d93419;
            border-radius: 4px;
            display: inline-block;
            border: none;
            padding: 0.75rem 1rem;
            margin: 20px 10px 0 0;
            text-decoration: none;
            color: #ffffff;
            font-family: sans-serif;
            font-size: 1rem;
            cursor: pointer;
            text-align: center;
            -webkit-appearance: none;
            -moz-appearance: none;
        }

        button:focus {
            outline: 1px dashed #fff;
            outline-offset: -3px;
        }

        .shake {
            animation: shake 0.82s cubic-bezier(.36, .07, .19, .97) both;
            transform: translate3d(0, 0, 0);
            backface-visibility: hidden;
            perspective: 1000px;
        }

        @keyframes shake {

            10%,
            90% {
                transform: translate3d(-1px, 0, 0);
            }

            20%,
            80% {
                transform: translate3d(2px, 0, 0);
            }

            30%,
            50%,
            70% {
                transform: translate3d(-4px, 0, 0);
            }

            40%,
            60% {
                transform: translate3d(4px, 0, 0);
            }
        }

animation属性和font属性一样,是一个属性组合,例子中动画名为 shake,所以绑定到选择器的关键帧名称为shake,持续 0.82 秒,动画速度曲线是立方贝塞尔曲线,both则表示轮流反向播放动画。在关键帧指示中,不同时间点的transform属性不同(从而造成动画效果),transform属性值,可以是不同的变换函数,例子中使用了三维坐标的平移变换。(可以参考 transform - CSS(层叠样式表) | MDN 了解各种变换,这差不多就是数学了)。变换只是在xoy平面平移,所以,backface-visibility (元素背面是否可见)和 perspective (z轴方向观测视距)并“无意义”(它的意义是提示浏览器需要硬件加速,见后)。

过渡与Style绑定

    <style>
        .movearea {
            height: 200px;
            transition: 0.2s background-color ease;
        }
    </style>

    <div id="app">
        <div @mousemove="xCoordinate" class="movearea" :style="{ backgroundColor: `hsl(${x}, 80%, 50%)` }">
            <h3>将鼠标划过屏幕</h3>
            <p>x: {{ x }}</p>
        </div>
    </div>
    <script>
        const { createApp } = Vue
        const app = createApp({
            data() {
                return {
                    x: 0
                }
            },
            methods: {
                xCoordinate(e) {
                    this.x = e.clientX
                }
            }
        })
        const vm = app.mount('#app')
    </script>

当鼠标划过该区域,背景色将根据x坐标的值变化,该动画效果的关键是绑定到style的值是一个对象表达式,其中包含了随鼠标x坐标变化的变量。class .movearea 对背景色变化使用了ease(缓动)过渡效果。

动画有关的性能问题

动画要实现好的性能,一方面是使用不触发重绘的 property,另一方面是能利用硬件加速。

从  CSS Triggers  可以了解哪些属性会在动画时触发重绘,我们发现 transform 的改变不会触发几何形状变化或绘制,这意味着这个操作可能是由复合线程在GPU帮助下执行的(复合线程如何在页面快照上实现动画效果我也不清楚)。改变 opacity 不会触发几何形状改变,不过它是可视属性,会导致绘制发生,所以需要小心。总的来说,transform 和 opacity 都可以在复合线程(compositor thread)完成,JS动画则先在main thread执行,然后触发compositor进行下一步操作,使得 CSS动画(在不触发layout或paint时)可以比 JS 动画流畅,不过 CSS 动画只有修改如下属性才能满足“仅触发Compositor,不触发layout或paint”:

  • backface-visibility
  • opacity
  • perspective
  • perspective-origin
  • transfrom

参考  关于JS动画和CSS3动画的性能差异 - KiraChen - 博客园   。使用上述属性,将让浏览器知道你需要硬件加速,我们可以应用以下任何一个property来提示浏览器:

perspective: 1000px;
backface-visibility: hidden;
transform: translateZ(0);

 动画时长与缓动效果

对于简单的 UI 过渡,0.25s 差不多了。如果需要移动较大距离,那么可以加长动画时长,不过此时需要用心调试。另外,起始动画比结束动画时间稍长一些较好,因为用户通常一开始需要动画引导,后面则没有耐心关注动画,因为用户考虑的是继续他的操作了。

缓动效果是动画的过渡效果。不过,对于ease-in和ease-out,开始动画节点应该用ease-out(从当前状态进入动画状态,淡出),结束动画节点则 ease-in(从动画状态进入最终固定状态,淡入),例如,对按钮在鼠标移上去时背景色过渡,可以

.button {
  background: #1b8f5a;
  /* 应用于初始状态,因此此转换将应用于返回状态 */
  transition: background 0.25s ease-in;
}

.button:hover {
  background: #3eaf7c;
  /* 应用于悬停状态,因此在触发悬停时将应用此过渡 */
  transition: background 0.35s ease-out;
}

制作动画还是比较费神的,直接使用一些工具或库可以省事,这里略过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值