js 小球缓动动画

参考:https://www.jianshu.com/p/003415b07a1a


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>

        /**
 * 创建抛物线小球
 * @param ballEl 小球对象
 * @param startLoc 起始位置 相对于整个页面来说的
 * @param endLoc 终点位置 相对于整个页面来说
 * @return ball, ballWrapper, ballStyle, ballWrapperStyle
 */
        const createBall = ({ ballCss, startLoc, id }) => {
            // 创建小球样式
            let ballStyle = document.createElement('style');
            let ballWrapperStyle = document.createElement('style');
            ballCss = `
            #cbBallStyle_${id} {
                ${ballCss}
                position: absolute;
                top: 0;
                left: 0;
            }`;
            {
                ballWrapperStyle.type = 'text/css';
                const ballWrapperCss = `
                #cbBallWrapperStyle_${id} {
                    position: fixed;
                    top: ${startLoc[1]}px;
                    left: ${startLoc[0]}px;
                    z-index: 9999;
                }`;
                ballWrapperStyle.innerHTML = ballWrapperCss;
                // 将style样式存放到head标签
                document.getElementsByTagName('head')[0].appendChild(ballWrapperStyle);

                ballStyle.type = 'text/css';
                ballStyle.innerHTML = ballCss;
                // 将style样式存放到head标签
                document.getElementsByTagName('head')[0].appendChild(ballStyle);
            }

            let ballWrapper = document.createElement('div');
            ballWrapper.setAttribute('id', 'cbBallWrapperStyle_' + id);
            document.body.appendChild(ballWrapper);

            let ball = document.createElement('div');
            ball.setAttribute('id', 'cbBallStyle_' + id);
            ballWrapper.appendChild(ball);
            return { ball, ballWrapper, ballStyle, ballWrapperStyle }
        };

        /**
         * 清除小球和style
         * @param ball
         * @param ballWrapper
         * @param ballStyle
         * @param ballWrapperStyle
         */
        const clearBall = ({ ballWrapper, ballStyle, ballWrapperStyle }) => {
            ballWrapper.parentNode.removeChild(ballWrapper);
            ballStyle.parentNode.removeChild(ballStyle);
            ballWrapperStyle.parentNode.removeChild(ballWrapperStyle);
        };

        const createKeyFrames = ({ ball, ballWrapper, startLoc, endLoc, duration, id }) => {
            let x1 = startLoc[0];
            let y1 = startLoc[1];
            let x2 = endLoc[0];
            let y2 = endLoc[1];
            let keyFramesCss = '';
            let cubicBezier = '';
            // 向上抛
            if (y2 !== y1) {
                keyFramesCss = `
            @keyframes hor-animation_${id} {
                0% {
                    left: 0px;
                }
                100% {
                    left: ${x2 - x1}px;
                }
            }
            @keyframes ver-animation_${id} {
                0% {
                    top: ${y1}px;
                }
                100% {
                    top: ${y2}px;
                }
            }`;
                if (y2 < y1) {
                    cubicBezier = 'cubic-bezier(.13,.6,.41,.8)';
                } else {
                    cubicBezier = 'cubic-bezier(.72,.1,.92,.43)';
                }
            } else if (y2 === y1) {
                keyFramesCss = `
            @keyframes hor-animation_${id} {
                0% {
                    left: 0px;
                }
                100% {
                    left: ${x2 - x1}px;
                }
            }
            @keyframes ver-animation_${id} {
                0% {
                    top: ${y1}px;
                }
                45% {
                    top: ${y1 - 50}px;
                }
                55% {
                    top: ${y1 - 50}px;
                }
                100% {
                    top: ${y2}px;
                }
            }`;
                cubicBezier = 'cubic-bezier(.49,.48,.49,.48)';
            }

            let keyFramesStyle = document.createElement('style');
            keyFramesStyle.type = 'text/css';
            keyFramesStyle.innerHTML = keyFramesCss;
            document.getElementsByTagName('head')[0].appendChild(keyFramesStyle);
            ballWrapper.setAttribute('style', `
    animation: ver-animation_${id} ${duration}s infinite;
    animation-timing-function: ${cubicBezier};`);
            ball.setAttribute('style',
                `animation: hor-animation_${id} ${duration}s linear infinite;`);
        };
        /**
         * 抛物线小球运动函数
         * @param ballEl 小球对象
         * @param startLoc 起始位置 相对于整个页面来说的
         * @param endLoc 终点位置 相对于整个页面来说
         * @param duration 运行时间
         */
        const parabolaBall = ({ ballCss, startLoc, endLoc, duration }) => {
            if (!duration) duration = 0.5;
            if (!ballCss) ballCss = `width: 20px;
                          height: 20px;
                          border-radius: 50%;
                          background-color: #00aa00;`;
            let id = parseInt(Math.random() * 10000) + new Date().getTime();
            // 创建小球
            const { ball, ballWrapper, ballStyle, ballWrapperStyle } = createBall({ ballCss, startLoc, id });
            createKeyFrames({ ball, ballWrapper, startLoc, endLoc, duration, id });


            setTimeout(() => {
                clearBall({ ballWrapper, ballStyle, ballWrapperStyle });
            }, duration * 1000)
        };

        // export default parabolaBall;

    </script>
    <script>
        console.log(parabolaBall, '===parabolaBall')

        parabolaBall({ startLoc: [0, 0], endLoc: [100, 100], duration: 1 })
    </script>
</body>

</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

web修理工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值