vue项目中使用动画钩子给项目添加复杂动画

摘要:
传统的vue动画非常简单。它可以通过使用内置的转换组件轻松实现。例如,组件进入站点后,其子元素的动画可以如下所示:˂

常规的vue动画实现方式很简单,使用内置的transition组件就能轻易的实现,比如一个组件进场之后其子元素的动画可以这么写

<transition name="normal">
     <div class="normal-player">
       <div class="top">
          <div class="back" @click="back">
            <i class="iconfont iconfanhui"></i>
         </div>
        <div class="middle">
        </div>
        <div class="bottom">
        </div>
      </div>
     </div>
 </transition>
 
.normal-player{
    &.normal-enter-active,
    &.normal-leave-active {
      transition: all 0.4s;
      .top,
      .bottom {
        transition: all 0.4s cubic-bezier(0.86, 0.18, 0.82, 1.32);
      }
    }
    &.normal-enter,
    &.normal-leave-to {
      opacity: 0;
      .top {
        transform: translate3d(0, -100px, 0);
      }
      .bottom {
        transform: translate3d(0, 100px, 0);
      }
    }
}

具体使用方法可以参考vue.js的官方文档,里面有详细说明
https://cn.vuejs.org/v2/api/#transition

这个组件里面的一些js钩子,可以实现较为复杂的动画,比如如下这个动画,再切换的时候有一个对应迷你播放器放大映射到大图的过程

vue项目中使用动画钩子给项目添加复杂动画第1张

 要实现这个动画,首先要获得小图,对于大图的定位,包括scale缩放比例,x,y值,定义一个获取位置的方法函数

    _getPosAndScale() {
      // 算出小图片(中心点)相对大图片(中心点)的距离和缩放比例
      // 底部播放器图片的宽度
      const targetWidth = 40;
      // 底部播放器距离左边的距离(图片的中心点就是宽度一半20加margin-left:20)
      const paddingLeft = 40;
      // 底部播放器底部的距离(图片的中心点也就是高度的一半20加margin-bottom:10)
      const paddingBottom = 30;
      // 唱片容器到顶部为80像素
      const paddingTop = 80;
      // 大播放器图片的宽度是padding-bottom80撑开来的所以是屏幕的宽度*0.8
      const width = window.innerWidth * 0.8;
      // 初始的缩放比例就是小图片除以大图片的宽度
      const scale = targetWidth / width;
      // 初始的x坐标,因为是小图片相对大图片所以是负值宽度
      const x = -(window.innerWidth / 2 - paddingLeft);
      // 初始的y坐标(屏幕的高度减去标题的高度,再减去大图高的一半(因为是圆所以宽高一样),最后再减去底部距离)
      const y = window.innerHeight - paddingTop - width / 2 - paddingBottom;
      console.log(x, y);
      return {
        x,
        y,
        scale
      };
    }

做了一张图方便理解~

vue项目中使用动画钩子给项目添加复杂动画第2张

有了x,y,scale,接下来就可以借助create-keyframe-animation 

当然先npm install create-keyframe-animation --save保存到项目依赖中

import animations from "create-keyframe-animation";
  // vue动画钩子提供两个参数一个EL(动画元素),一个DONE回调函数到afterEnter
    enter(el, done) {
      const { x, y, scale } = this._getPosAndScale();
      let animation = {
        0: {
          // 第0帧的时候,先让图片缩小,显示在右下角(等于和小图重叠)
          transform: `translate3d(${x}px,${y}px,0) scale(${scale})`
        },
        60: {
          // 60%的时候,让图片回到cd中心,变大
          transform: `translate3d(0,0,0) scale(1.1)`
        },
        100: {
          // 变回原来的尺寸,会有一个回弹的效果
          transform: `translate3d(0,0,0) scale(1)`
        }
      };
      // 注册动画:
      animations.registerAnimation({
        name: "move",
        animation,
        presets: {
          duration: 400,
          easing: "linear"
        }
      });
      //运行动画,done也就是钩子中直接到afterEnter
      animations.runAnimation(this.$refs.cdWrapper, "move", done);
    },
    afterEnter() {
      //运行完动画之后,注销掉动画
      animations.unregisterAnimation("move");
      this.$refs.cdWrapper.style.animation = "";
    },
    // leave是指 cd从显示到隐藏的动画
    leave(el, done) {
      // 这里我们只要直接移动变小就可以了
      this.$refs.cdWrapper.style.transition = "all 0.4s";
      const { x, y, scale } = this._getPosAndScale();
      this.$refs.cdWrapper.style[
        transform
      ] = `translate3d(${x}px,${y}px,0) scale(${scale})`;
      // 监听transitionend 事件在 CSS 完成过渡后触发done回调  
      this.$refs.cdWrapper.addEventListener("transitionend", done);
    },
    afterLeave() {
      this.$refs.cdWrapper.style.transition = "";
      this.$refs.cdWrapper.style[transform] = "";
    },

动画到这里也就完成了,也不是很复杂,关键是以后的项目中怎么融汇贯通,还是需要多多练习呀

免责声明:文章转载自《vue项目中使用动画钩子给项目添加复杂动画》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇根据文件字节流判定文件类型启用APACHE2(Ubuntu下)的USERDIR的功能下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

vue 借用element-ui实现头像上传 axios发送请求

<!-- 上传组件 --> <!-- 总结一下: action 写图片上传请求的路径 去路径哈 show-file-list就是当你上传时,是否会显示出上传的是哪一个图片,一般为false handleAvatarSuccess它是成功的回调 beforeAvatarUpload:上传之前做的一...

给微信小程序添加简单小动画

需要实现的效果很简单,当微信小程序跳转到该页面时,微信登录BUTTON从右往左淡入出现,手机登录BUTTON从左往右淡入出现,类似于animation.css的简单效果 官方文档上是这样说的: ①创建一个动画实例 animation。 ②调用实例的方法来描述动画。 ③最后通过动画实例的 export 方法导出动画数据传递给组件的 animation 属性...

使用vue做项目如何提高代码效率

最近做了两个vue项目,算上之前做的两个项目,总共有四个vue项目的经验了,但是总体来说写的代码质量不是很高,体现在以下几点 1.代码没有高效的复用   自从使用vue做项目之后,以前使用面向过程变成的习惯随之被面向对象取代了,这是一个很好的转变,让代码看起来不是那么混乱了,但是不混乱并不代表质量高,比如实现一个检验输入是否有效的功能写的代码很长,而且重复...

vue 点击弹出下拉菜单 点击其他页面收回菜单

由于elementUI的下拉菜单在项目中表现得不尽人意 (定位的原因) 于是 决定自己 整一个 小而美 理清下面几种情况就妥了 出现前 出现后 点击后 出现后未点击选项(点击空白页) 还是直接放码过来 show you my code吧~~~ 直接上点击空白(其他)页面 选项框收回 代码吧 思路:直接阻止按钮和选项框的事件冒泡,然后给document绑定...

vue,基于element的tree组件封装

封装组件代码 // 组件:树 /* 参数说明-属性: 1.treeData:展示数据(array) 2.treeEmptyText:内容为空的时候展示的文本(String) 3.treeNodeKey:每个树节点用来作为唯一标识的属性,整棵树应该是唯一的(String) 4.treeRenderAfterExpand:是否在第一次展开某个树节点后才渲染其子...

webpack4.x 从零开始配置vue 项目(一)基础搭建项目

序 现在依旧记得第一次看到webpack3.x 版本配置时候的状态刚开始看到这些真的是一脸懵。希望这篇文章能帮到刚开始入门的同学。 webpack 是什么? webpack是一个模块化打包工具,webpack 通过入口分析项目结构,找到JavaScript模块以及一些不能直接在浏览器上运行的语言、语法等 如(scss、ts、es6+等),并将其打包成可以直...