js+css实现抖动效果

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);
    }
}

动画效果 也可以做定位移动

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值