vue之flip动画解析
<template> <div> <ul class="container"> <li v-for="item in base" :key="item.id" ref="lis"> <div class="item" :style="'backgroundColor: ' + item.c"></div> </li> </ul> <el-button @click="sort">排序</el-button> </div> </template> <script> function getColor() { const random = () => parseInt(Math.random() * 256) return `rgb(${random()},${random()},${random()})` } const base = Array.from({ length: 64 }, (_, i) => { return { id: i + 1, c: getColor() } }) // 上面的内容应该是不需要解释的, 无非就是生成一些数据, 并且进行渲染 export default { data() { return { base } }, methods: { // 排序 sort() { const lis = this.$refs.lis // 排序之前, 获取当前的 64 个小盒子的 位置 top和left值 const oldRect = this.getRect(lis) // 通过遍历的方式, 拷贝当前的数据 const newBase = [] this.base.map((i) => { newBase.push({ id: i.id, c: i.c }) }) // 再创建一个数组, 用来装乱序后的数据 const randomBase = [] while (newBase.length) { const index = parseInt(Math.random() * newBase.length) randomBase.push(newBase[index]) newBase.splice(index, 1) } // 把乱序后的数据, 赋值给base this.base = randomBase // 这里我的理解是 vNode 已经更新完了, 但是没有映射到 Dom 中的时刻 this.$nextTick(() => { // 获取上面的 lis 更新后的位置 const newRect = this.getRect(lis) lis.map((i, index) => { // 计算乱序后的每个方块的位置 相对于之前的位置的 的 top 值和 left 值的变化 const x = oldRect[index].top - newRect[index].top const y = oldRect[index].left - newRect[index].left // javascript 设置动画帧 就是使用transform 和 translate 进行位移操作 const step = [ { transform: `translate(${y}px, ${x}px)` }, { transform: 'translate(0)' } ] // 播放动画 i.animate(step, 600) }) }) }, // 获取矩阵位置 返回矩阵每个单元 相对于当前屏幕的 top 和 left 值 getRect(doms) { return doms.map((i) => { const info = i.getBoundingClientRect() return { top: info.top, left: info.left } }) } } } </script> <style lang='scss' scoped> .container { display: grid; grid-template-columns: repeat(8, 80px); grid-template-rows: repeat(8, 80px); li { justify-self: center; align-self: center; .item { width: 60px; height: 60px; border: 1px solid #333; } } } </style>
上面是一个 VUE 组件的 完整 案例
效果 参考 https://cn.vuejs.org/v2/guide/transitions.html#%E5%88%97%E8%A1%A8%E7%9A%84%E6%8E%92%E5%BA%8F%E8%BF%87%E6%B8%A1
<a herf="https://cn.vuejs.org/v2/guide/transitions.html#%E5%88%97%E8%A1%A8%E7%9A%84%E6%8E%92%E5%BA%8F%E8%BF%87%E6%B8%A1" ></a>
本想把生活活成一首诗, 时而优雅 , 时而豪放 , 结果活成了一首歌 , 时而不靠谱 , 时而不着调