js 创建keyframe_Vue中使用create-keyframe-animation与动画钩子完成复杂动画
本篇文章主要介绍了 Vue中使用create-keyframe-animation与动画钩子完成复杂动画,分享给大家
如何实现这个动画?
效果分析
点`start`的时候,我们把整个动画拆分为两种效果(过渡和动画)。
1. 中间cd消失,下方播放条显示,这是属于`过渡`
2. `过渡`开始的同时,cd同时移动、放大、缩小到左下方播放条 ,这属于`动画`
上面的效果是【过渡】加【动画】同时使用完成的
对于第一种【过渡】,我们用vue中transition标签,加设置v-enter、v-leave-to、v-enter-active、v-leave-enter即可完成
对于第二种【动画】,我们就要用keyframe来完成了。
这里我们先完成第一种过渡
vue中模板节点
// CD图片 (动画的时候图片初始位置)
start
// 下面播放状态框
// 状态看里面的图片 (动画的时候图片结束位置)
结构很简单,基本就是 两个大div ,然后把div的布局按效果图那些布置。
css部分(省略布局部分)
.cd-box
&.v-enter-active, &.v-leave-active
transition: all 0.4s
&.v-enter, &.v-leave-to
opacity: 0
.mini-player-box
&.v-enter-active, &.v-leave-active
transition: all 0.4s
&.v-enter, &.v-leave-to
transform: translate3d(0, 40px, 0)
opacity: 0
这样在fullScreen变量改变的时候,就会触发【过渡】
这里我们完成第二种动画
首先安装插件 , npm i create-keyframe-animation 这个插件是用js写css的keyframe动画用的,至于为什么keyframe不在css里面写呢?那是因为屏幕大小不一样,会导致需要移动的px不一样,所以要动态计算。
给 添加动画钩子
@enter="enter"
@after-enter="afterEnter"
@leave="leave"
@after-leave="afterLeave"
>
计算偏移量(中心点到中心的偏移,图中红线距离)
// 获得偏移量,以及scale
_getPosAndScale() {
// 左下角图片的宽度
const targetWidth = 40
// cd宽度
const width = 300
const scale = targetWidth / width
// 这里的 x,y要算,过程省略,无非就是加加减减,这的x,y都是算出来了的
const x = -167.5
const y = 497
return {x ,y , scale}
},
x,y的数值代表什么?见图
这里x为什么是负的,y是正的呢?
因为 浏览器的坐标系的中心点是在左上角 的,如图
那么动画从 cd中心到左下角,X偏移为负,y偏移为正
然后用animations插件执行动画钩子
// enter是指当 cd从隐藏到显示的动画,
enter(el, done) {
const {x, y, scale} = this._getPosAndScale()
let animation = {
// 第0帧的时候,先让图片缩小,显示在右下角
0: {
transform: `translate3d(${x}px, ${y}px, 0) scale(${scale})`
},
// 60%的时候,让图片回到cd中心,变大
60: {
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'
}
})
//运行动画
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'] = ''
}
写到这里,我们就把刚开始的效果给写完啦!
但在写js的keyframe的时候
我们还可以加上rotate,让动画效果有一个回弹效果
let animation = {
0: {
transform: `translate3d(${x}px, ${y}px, 0) scale(${scale}) rotate(0deg)`
},
60: {
transform: `translate3d(0 ,0 , 0) scale(1.1) rotate(365deg)`
},
100: {
transform: `translate3d(0 ,0 , 0) scale(1) rotate(360deg)`
}
}
所有源码
@enter="enter"
@after-enter="afterEnter"
@leave="leave"
@after-leave="afterLeave"
>
start
/* eslint-disable */
import animations from 'create-keyframe-animation'
export default {
components: {},
props: {},
data() {
return {
fullScreen: true
}
},
computed: {},
watch: {},
created() {},
mounted() {
// const {x, y, scale} = this._getPosAndScale()
console.log(this._getPosAndScale())
console.log(animations)
},
methods: {
switchMode() {
this.fullScreen = !this.fullScreen
},
_getPosAndScale() {
const targetWidth = 40
const paddingLeft = 20
const paddingBottom = 20
const paddingTop = 0
const width = 300
const scale = targetWidth / width
const x = -(window.innerWidth / 2 - paddingLeft)
const y = window.innerHeight - paddingTop - paddingBottom - width / 2
return {x ,y , scale}
},
enter(el, done) {
const {x, y, scale} = this._getPosAndScale()
let animation = {
0: {
transform: `translate3d(${x}px, ${y}px, 0) scale(${scale}) rotate(0deg)`
},
60: {
transform: `translate3d(0 ,0 , 0) scale(1.1) rotate(365deg)`
},
100: {
transform: `translate3d(0 ,0 , 0) scale(1) rotate(360deg)`
}
}
animations.registerAnimation({
name: 'move',
animation,
presets: {
duration: 400,
easing: 'linear'
}
})
animations.runAnimation(this.$refs.cdWrapper, 'move', done)
},
afterEnter(){
animations.unregisterAnimation('move')
this.$refs.cdWrapper.style.animation = ''
},
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})`
// this.$refs.cdWrapper.style['transform'] = 'rotate(360deg)'
// transitionend 事件在 CSS 完成过渡后触发
this.$refs.cdWrapper.addEventListener('transitionend', () => {
done()
})
},
afterLeave() {
this.$refs.cdWrapper.style.transition = ''
this.$refs.cdWrapper.style['transform'] = ''
}
}
}
.index
background: #eee
width: 100%
height: 100%
display : flex
flex-direction: column
justify-content : space-between
align-items: center
.cd-box
display : flex
justify-content : center
align-items : center
width: 300px
height: 300px
background: #eee
border-radius: 50%
&.v-enter-active, &.v-leave-active
transition: all 0.4s
&.v-enter, &.v-leave-to
opacity: 0
.bg
width: 300px
height: 300px
border-radius: 50%
.mini-box
position: absolute
bottom: 0
right: 0
left: 0
display : flex
align-items center
border: 1px solid #555
width: 100%
height: 40px
box-sizing : border-box
&.v-enter-active, &.v-leave-active
transition: all 0.4s
&.v-enter, &.v-leave-to
transform: translate3d(0, 40px, 0)
opacity: 0
.mini-img
height: 40px
width: 40px
box-sizing : border-box
img
height: 100%
width: 100%
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
js 创建keyframe_Vue中使用create-keyframe-animation与动画钩子完成复杂动画相关推荐
- 二进制文件mysql创表_MySQL_MYSQL中如何存取二进制文件,首先创建测试表testtable CREATE TA - phpStudy...
MYSQL中如何存取二进制文件 首先创建测试表testtable CREATE TABLE testtable ( id INT(5) NOT NULL AUTO_INCREMENT PRIMARY ...
- three.js创建简单动画(vue中使用three.js59)
简单动画 1.demo效果 2.知识要点 2.1 three.js动画分类 2.1.1基础动画 2.1.2移动相机 2.1.3变形和蒙皮 2.1.4加载外部动画 2.2 基础动画实现方式 2.2.1 ...
- python中使用zip函数基于两个列表数据list创建字典dict数据(Create a dictionary by passing the output of zip to dict)
python中使用zip函数基于两个列表数据list创建字典dict数据(Create a dictionary by passing the output of zip to dict) 目录
- SRPG游戏开发(三十一)第八章 游戏中的数据 - 一 创建新项目(Create New Project)
返回总目录 第八章 游戏中的数据(Data in Game) 在之前的章节中,我们进行地图对象的生成,移动等操作. 这一章本来可以进行战斗的编写,不过数据缺失是一个问题. 所以这一章我们先来建立一些数 ...
- js如何在浏览器中运行php文件下载,JavaScript_用JS在浏览器中创建下载文件,但受限于浏览器,很多情况下 - phpStudy...
用JS在浏览器中创建下载文件 但受限于浏览器,很多情况下我们都只能给出个链接,让用户点击打开->另存为.如下面这个链接: file.js 用户点击这个链接的时候,浏览器会打开并显示链接指向的文件 ...
- android sqlite 创建空表,sqlite3在android中创建表错误(sqlite3 create table error in android)...
sqlite3在android中创建表错误(sqlite3 create table error in android) 我试图在android中使用sqlite3创建表我的开放助手是这样的: pub ...
- 使用Vue.js在WordPress中创建单页面应用SPA
吐槽一下,掘金好像并不能插入gist的代码框 效果有点打折扣 博客原文地址里有gist代码: 使用Vue.js在WordPress中创建单页面应用SPA 英文原文地址:premium.wpmudev. ...
- 用js在页面中创建svg标签不显示的问题
问题描述 直接在页面写入SVG,图形正常可以显示, 但是使用js动态创建SVG,添加入DOM节点,页面无法显示SVG图形 原因 SVG是基于XML格式定义图像的一种技术,因此创建节点的时候,需要指定命 ...
- three.js 交互_如何使用Three.js创建交互式3D角色
three.js 交互 View demo 查看演示 Download Source 下载源 Ever had a personal website dedicated to your work an ...
最新文章
- 学javascript有哪些开发工具
- JAVA学习之路 (三) 运算符
- kaggle房价预测问题
- [ubuntu]deb软件源
- python创建虚拟环境失败_virtualenv 创建虚拟环境不成功
- 2013-01-09 13:31 IE不支持textarea的maxlength属性,Firefox支持
- Java自学视频整理
- php laravel手册,学习Laravel
- Unity读取CSV表格时出现中文乱码处理方式
- 一:评分卡模型分数计算
- 甘超波:NLP理解层次
- P1434 [SHOI2002]滑雪【记忆化搜索DP】
- 无法在浏览器中创建CAD文档
- 《网络攻防》 免杀原理与实践
- RAID磁盘阵列、mdadm、群晖软RAID
- python植物大战僵尸 豆约翰,python植物大战僵尸六之添加僵尸
- Linux内核在中国大发展的黄金十年-写于中国Linux存储、内存管理和文件系统峰会十周年之际...
- python生成微信个性签名的词云图
- 常见算法之Flood Fill算法
- 接口自动化测试从入门到高级实战(最新干货)
热门文章
- Matlab安装问题
- 服务器内部的硬盘不是dns,dns无响应是不是欠费?这个还需了解
- js requestanimationframe动画 时间控制
- linux 进程监控 工具,你值得拥有:25个Linux性能监控工具
- Spring Security OAuth2 单点登录
- 能源消耗监测管理系统:实现企业用能定额、降低成本节能管理
- matplotlib matplotlib中统计直方图hist()、箱线图的画法(四)
- 启动vs项目时,无法启动IIS管理器,找不到xxx模块
- Java实现英文段落分句_java英文段落拆分成句(Split an article into sentences)
- 5段SQL可以测试出你对SQL性能优化知识了解多少