首先展示一下效果,狠狠点击 https://zhangkunusergit.github.io/vue-component/dist/jitter.html

代码github : https://github.com/zhangKunUserGit/vue-component

转载请标注:https://www.cnblogs.com/zhangkunweb/p/vue_jitter.html

先说一下用法:

<jitter :start.sync="抖动控制器" :range="{ 包含x,y, z }" :shift-percent="0.1">
这里是你要抖动的元素
</jitter>

思路:

1.抖动就是摆动,现实中的钟摆可以很形象。

2.当摆动到临界点后,就会向相反的方向摆动。

3.在没有动力时,摆动会慢慢停止。

初始化抖动:

/**
* 初始化抖动
*/
initJitter() {
// 把start变成false, 方便下次点击
this.$emit('update:start', false);
// 清除上次动画
this.clearAnimate();
// 设置currentRange, 填充this.range 中没有的项
this.currentRange = Object.assign({}, { x: 0, y: 0, z: 0 }, this.range);
// 获取需要操作的的项 和 每次需要摆动的量
const { position, shiftNumber } = this.getPositionAndShiftNumber();
this.position = position;
this.shiftNumber = shiftNumber;
// 初始 move 起始点是0
this.move = { x: 0, y: 0, z: 0 };
// 初始时 是顺时针
this.isClockwise = true;
// 执行动画
this.timer = window.requestAnimationFrame(this.continueJitter);
},

这里准备动画开始前的工作。

执行动画:

// 持续抖动
continueJitter() {
this.refreshMove(this.isClockwise ? -1 : 1);
// 绝对值
const absMove = this.getAbsMove();
const currentRange = this.currentRange;
let changeDirection = false;
for (let i = 0, l = this.position.length, p; i < l; i += 1) {
p = this.position[i];
// 判断是否到达临界值,到达后 应该反方向执行动画
if (currentRange[p] <= absMove[p]) {
// 等比例缩减
this.currentRange[p] -= this.shiftNumber[p];
// 判断如果已经无力再摆动,就让摆动停止, 只要有一个值达到了0,所有都会达到
if (this.currentRange[p] <= 0) {
// 停止在起始点上
this.jitterView({ x: 0, y: 0, z: 0 });
// 清除动画
this.clearAnimate();
return;
}
// 更新move为临界点
this.move[p] = this.isClockwise ? -this.currentRange[p] : this.currentRange[p];
// 改变摆动方向
changeDirection = true;
}
}
if (changeDirection) {
// 摆动方向取反
this.isClockwise = !this.isClockwise;
}
// 更新元素位置
this.jitterView(this.move);
// 继续执行动画
this.timer = window.requestAnimationFrame(this.continueJitter);
},

执行动画,当判断已经无力摆动后,让元素回归到原来的位置,并清除动画。

修改元素位置:

/**
* 修改元素位置
* @param x
* @param y
* @param z
*/
jitterView({ x = 0, y = 0, z = 0 }) {
this.$el.style.transform = `translate3d(${x}px, ${y}px, ${z}px)`;
},

这里需要判断需要 Z 轴摆动吗? 当需要时,必须给当前元素的父级添加 perspective, 从而修改子级透视效果

mounted() {
// 如果要执行 z 轴动画需要设置父级,从而修改子级透视效果,否则 Z 轴没有效果
if (this.range.z > 0) {
const parentEl = this.$el.parentNode;
Object.keys(this.perspectiveStyle).forEach((key) => {
parentEl.style[key] = this.perspectiveStyle[key];
});
}
},

最后看看可以传的属性:

props: {
// 抖动范围,单位是px, 例如:{x: 4, y: 2, z: 10}
range: {
type: Object,
default: () => { return { z: 8 }; },
},
start: {
type: Boolean,
required: true,
},
shiftPercent: {
type: Number,
default: 0.1, // 移动range中初始值的百分比
},
perspectiveStyle: {
type: Object,
default: () => {
return {
perspective: '300px',
perspectiveOrigin: 'center center'
};
}
}
},

上面是可以传的属性,大家可以按照情况修改

最后:

这里我只写了简单的动画,也可以根据不同情况进行修改,从而达到想要的效果。这里已经满足输入框错误抖动的效果了。

Vue 让元素抖动/摆动起来的更多相关文章

  1. Vue多元素过渡

    前面的话 前面分别介绍了单元素过渡的CSS过渡和JS过渡,本文将详细介绍Vue多元素过渡 常见示例 最常见的多标签过渡是一个列表和描述这个列表为空消息的元素: <transition> & ...

  2. chrome渲染hover状态tranform相邻元素抖动bug

    最近同事在使用 css3 的 transition + tranform 的时候影响了相邻的元素出现bug.或者说相邻的元素出现抖动bug. 然而把 hover 状态的 tranform 属性删了后, ...

  3. Vue 获取元素样式 元素高度

    看到这个问题我第一时间想的竟然是JS 不知道你是怎么想的 不过昨天有一个小哥哥 问我一个Vue的 哈哈哈 get了 我当时问他为什么不用JS获取 他说 这个性能更高 那我们来看看这个高性能的获取元素高 ...

  4. 移动端fixed的元素抖动的问题

    工作中发现,给一个元素添加fixed属性,让它固定在窗口某个位置,直接加fposition:fixed属性就能实现这个效果: 在安卓手机上的效果都比较好,但是ios系统的个别浏览器兼容性就不好,如QQ ...

  5. 003——VUE操作元素属性

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. Vue给元素添加样式

    Vue中使用样式 绑定css 数组 <style> .red{ color:red } .thin{ font-size:18px } </style> <h1 :cla ...

  7. vue单元素/组件的过渡

    (1)过渡的类名 v-enter:定义进入过渡的开始状态.在元素被插入之前生效,在元素被插入之后的下一帧移除. v-enter-active:定义进入过渡生效时的状态.在整个进入过渡的阶段中应用,在元 ...

  8. Vue挂载元素的替换

    Vue根组件已有挂载DOM'#app',在render又引进一个组件,该组件最外层也是用了'#app',为何根组件的DOM'#app'会被替换掉. //main.js import Vue from ...

  9. vue 单元素过渡

    demo <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

随机推荐

  1. DotNetty 使用ByteToMessageDecoder 国家部标808协议封装

    DotNetty 开源地址 https://github.com/Azure/DotNetty 个人博客地址   http://www.dncblogs.cn/Blog/ShowBlog/70 1.国 ...

  2. CodeForces 540B School Marks

    http://codeforces.com/problemset/problem/540/B School Marks Time Limit:2000MS     Memory Limit:26214 ...

  3. 网易云首席安全架构师谈安全新形势:DDOS两三天,游戏玩家数从几万降到几百

    本文由  网易云发布. 安全是一个永恒的话题,在业务不断云化.攻击越来越复杂的当下,互联网安全呈现了出什么样的严峻形势?对这些形势,网易云又是如何应对的? 网易云首席安全架构师沈明星 4月13日,网易 ...

  4. CentOS 安装 linux kernel 源码

    原文链接:https://blog.csdn.net/qaz1qaz1qaz2/article/details/52825389 1.下载系统包yum install rpm-buildyum ins ...

  5. Elasticsearch Java API简介

    加入依赖 我本地的Elasticsearch的版本是2.1.0,因此加入相应的maven依赖 <dependency> <groupId>org.elasticsearch&l ...

  6. Java基础梳理(一)

    List和Set比较,各自的子类比较 对比一:Arraylist与LinkedList的比较 1.ArrayList是实现了基于动态数组的数据结构,因为地址连续,一旦数据存储好了,查询操作效率会比较高 ...

  7. POJ 1287

    #include<iostream> #include<stdio.h> #define MAXN 100 #define inf 1000000000 using names ...

  8. POJ 1129

    #include<iostream> #include<stdio.h> #include<string> #define MAXN 60 using namesp ...

  9. IP等级

    IP是Ingress Protection的缩写,IP等级是针对电气设备外壳对异物侵入的防护等级,来源是国际电工委员会的标准IEC 60529,这个标准在2004年也被采用为美国国家标准.  在这个标 ...

  10. (转)Python全能自动化开发环境软件之pyenv的安装说明

    原文:http://www.magedu.com/73921.html pyenv,是一款特别好用的Python版本管理器,程序员可以建立不同的目录,在不同的目录里分别运行不同版本的Python, 并 ...