JS飞入飞出动画 加速动画 缓入缓出效果

该代码示例展示了如何用JavaScript创建一个飞入飞出的动画效果,利用tween算法实现缓入和缓出。通过定义animate函数,结合Promise处理动画的顺序,动态改变HTML元素的left属性,实现元素从屏幕一侧飞入,再飞出到另一侧的效果。
摘要由CSDN通过智能技术生成

JS飞入飞出动画 加速动画 缓入缓出效果

在线预览 /my/demo/fly.html online visit

<!DOCTYPE html>
<body>
 <div id="gift-fly" style=" position: absolute; width: 50px;height: 50px;background-color: #327dff "> 动画盒子</div>
</body>
<script>
    let flyDiv = document.getElementById("gift-fly")
    animate(flyDiv, {"left": 500}, 3000, "easeIn").then(res => {
        console.log("飞入动画执行完了")
        animate(flyDiv, {"left": 0}, 3000, "easeOut").then(res => {
            console.log("飞出动画执行完了")
        })
    })

    /**
     * @param elem {HTMLElement} 执行动画的HTML元素
     * @param params {JSON} 动画执行过过程中需要修改的HTML属性
     * @param duration {Number} 可选,动画执行时间,单位毫秒
     * @param easing {String} 可选,动画执行的方式,缓入easeIn、缓出easeOut
     */
    function animate(elem, params, duration, easing) {
        return new Promise(success => {
            /*
             * 描述: tween动画算法。
             * @param Number t: 动画已经执行的时间(实际上时执行多少次/帧数)
             * @param Number b: 起始位置
             * @param Number c: 终止位置
             * @param Number d: 从起始位置到终止位置的经过时间(实际上时执行多少次/帧数)
             */
            let tween = {
                easeIn: function (t, b, c, d) {//缓入
                    return c * (t /= d) * t + b;
                },
                easeOut: function (t, b, c, d) {//缓出
                    return -c * (t /= d) * (t - 2) + b;
                }
            };
            let attribute = {
                get: function (elem, attr) {
                    let val;
                    if (elem.currentStyle) {
                        if (attr === "opacity") {
                            val = elem.filters.alpha[attr];
                        } else {
                            val = elem.currentStyle[attr];
                        }
                    } else {
                        val = getComputedStyle(elem)[attr];
                        if (attr === "opacity") {
                            val = 100 * val;
                        }
                    }
                    return val;
                },
                set: function (elem, attr, val) {
                    if (attr == 'opacity') {
                        elem.style.filter = 'alpha(opacity=' + (val) + ')';
                        elem.style.opacity = (val) / 100;
                    } else {
                        elem.style[attr] = val + 'px';
                    }
                }
            };
            let effect = {
                animate: function (elem, params, duration, easing) {
                    let dt = new Date().getTime(),
                        b = 0,
                        c = 0,
                        d = duration || 500,
                        fps = 1000 / 60;

                    let changes = [];

                    for (let attr in params) {
                        b = parseFloat(attribute.get(elem, attr));
                        c = params[attr] - b;

                        changes.push({

                            attr: attr,

                            b: b,

                            c: c
                        });
                    }

                    easing = easing || "easeOut";
                    setTimeout(function () {
                        let t = new Date().getTime() - dt;
                        let b, c, attr;
                        for (let i = 0; i < changes.length; i++) {
                            b = changes[i].b;
                            c = changes[i].c;
                            attr = changes[i].attr;

                            attribute.set(elem, attr, tween[easing](t, b, c, d));
                            if (d <= t) {
                                attribute.set(elem, attr, params[attr]);
                                success();
                                return;
                            }
                        }
                        setTimeout(arguments.callee, fps);
                    }, fps);
                }
            };
            effect.animate(elem, params, duration, easing);
        })
    }
</script>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值