export class Shake {
static directions = ["left", "up"]; // 抖动方向数组 上下和左右抖动
constructor(element, options) {
this.element = document.getElementById(element); // 元素对象
this.settings = Object.assign(
{
interval: 1000, // 抖动间隔时间
distance: 20, // 抖动距离
times: 5, // 抖动次数
callback: function () { }, // 抖动完成后的回调函数
},
options
); // 用户自定义配置项
this.originalStyle = this.element.getAttribute("style") || ""; // 元素原始样式
console.log(this.originalStyle, " this.originalStyle", this.element);
this.timerId = null; // 定时器ID
}
shake() {
this.clearTimer(); // 清除定时器
const direction =
Shake.directions[Math.floor(Math.random() * Shake.directions.length)]; // 随机选择一个方向
this.element.classList.add(`shake-${direction}`); // 添加抖动动画类名
let count = 0;
this.timerId = setInterval(() => {
if (count >= this.settings.times) {
this.clearTimer(); // 清除定时器
this.removeShakeAnimation(); // 移除抖动动画类名和恢复元素原始样式
this.settings.callback(); // 执行回调函数
} else {
const direction =
Shake.directions[Math.floor(Math.random() * Shake.directions.length)]; // 随机选择一个方向
this.element.classList.remove(`shake-${direction === "left" ? "up" : "left"}`); // 移除上一次抖动动画类名
this.element.classList.add(`shake-${direction}`); // 添加抖动动画类名
count++;
}
}, this.settings.interval);
}
shakeMultiple(times) {
this.clearTimer(); // 清除定时器
const direction =
Shake.directions[Math.floor(Math.random() * Shake.directions.length)]; // 随机选择一个方向
this.element.classList.add(`shake-${direction}`); // 添加抖动动画类名
setTimeout(() => {
this.removeShakeAnimation(); // 移除抖动动画类名和恢复元素原始样式
this.settings.callback(); // 执行回调函数
}, this.settings.interval * times);//次数和间隔时间的乘积
}
clearTimer() {
if (this.timerId) {
clearInterval(this.timerId); // 清除定时器
this.timerId = null; // 清空定时器ID
}
}
removeShakeAnimation() {
const direction = this.element.classList[0].split("-")[1]; // 获取抖动方向
this.element.classList.remove(`shake-${direction}`); // 移除抖动动画类名
this.element.setAttribute("style", this.originalStyle + " !important"); // 恢复元素原始样式
}
}
使用如下:
//抖动
handeleShake(id) {
const element = document.getElementById(id);
//获取元素抖动前的样式
const originalStyle = element.style.cssText;
const shake = new Shake(id, {
interval: 100,
distance: 30,
times: 2,
callback: function () {
console.log("抖动完成!");
element.style.cssText = originalStyle;
//移除样式
element.classList.remove("shake-left");
element.classList.remove("shake-up");
}
});
shake.shakeMultiple(5);
},
css如下
.shake-left {
-webkit-animation: shake-left 0.2s linear infinite;
animation: shake-left 0.2s linear infinite;
}
.shake-up {
-webkit-animation: shake-up 0.2s linear infinite;
animation: shake-up 0.2s linear infinite;
}
@-webkit-keyframes shake-left {
0% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
25% {
-webkit-transform: translateX(-10px);
transform: translateX(-10px);
}
50% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
75% {
-webkit-transform: translateX(10px);
transform: translateX(10px);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
@keyframes shake-left {
0% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
25% {
-webkit-transform: translateX(-10px);
transform: translateX(-10px);
}
50% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
75% {
-webkit-transform: translateX(10px);
transform: translateX(10px);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
@-webkit-keyframes shake-up {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
25% {
-webkit-transform: translateY(-10px);
transform: translateY(-10px);
}
50% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
75% {
-webkit-transform: translateY(-10px);
transform: translateY(-10px);
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
@keyframes shake-up {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
25% {
-webkit-transform: translateY(-10px);
transform: translateY(-10px);
}
50% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
75% {
-webkit-transform: translateY(-10px);
transform: translateY(-10px);
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
动画效果 也可以做定位移动