用animejs简单实现烟花

PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛

背景

这一次的活动主题是春节创意大赛,春节我第一想到的就是烟花,以前武汉江滩都会有跨年烟花表演。因为疫情还有保护环境的原因,武汉已经好多年没有烟花表演了,所以我想用代码实现烟花表演。话不多说,我们看代码:

技术

实现

静态页面

  • html
<div class="sky"></div>
复制代码
  • css
 * {
            margin: 0;
            padding: 0;
        }
        .sky {
            width: 100vw;
            height: 100vh;
            background-image: url("./img/yejing.jpg");
            background-repeat: no-repeat;
            background-position: 50% 50%;
            background-size: 110% 110%;
            transform-origin: 50% 50%;
            overflow: hidden;
            position: relative;
        }
        .firework {
            width: 5px;
            height: 5px;
            position: absolute;
            bottom: 5px;
            left: 50%;
            opacity: 0;
            border-radius: 999px;
        }
        .firecracker {
            width: 5px;
            height: 5px;
            position: absolute;
            border-radius: 10px;
        }
复制代码

有了上面的代码就可以实现一个静态的页面(武汉江滩夜间图)了,效果如下:

image.png

实现烟花动画

问:“实现烟花要几步了?”

答:“1.烟花上天、2.烟花爆炸”

首先引入代码库

<script src="https://cdn.bootcdn.net/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
复制代码

接下来我们就来实现这两步

1.烟花上天js 代码

  • 创建烟花
    let $targets = $("<div class='firework'></div>");
    $(".sky").append($targets);
复制代码
  • 烟花上天
Firework($targets);
let Firework = ($targets) => {
            let left = Math.ceil(100 * Math.random()) + '%';
            let bottom = Math.ceil(150 * Math.random()) + clientHeight / 2;
            let color = 'linear-gradient(rgb(' + Math.ceil(Math.random() * 255) + ', ' + Math.ceil(Math.random() * 255) + ', 255), rgba(0, 0, 255, 0))';
            let delay = 1000 * Math.ceil(5 * Math.random());
            $targets.css({
                "background": color,
                "left": left,
            });
            anime({
                targets: $targets[0],
                bottom: bottom,
                height: [5, 100, 0],
                duration: 2000,
                delay: delay,
                easing: 'linear',
            });
        }
复制代码

2.烟花爆炸js 代码

  • 创建烟花火星
let renderFireworkPoint = () => {
    let html = '';
    for (let i = 0; i < 20; i++) {
        html += `<div class="firecracker point${i}"></div>`
    }
    return html;
}
复制代码
  • 爆炸动画
let animeFireworkPoint = ($targets, r) => {
            // 第1象限
            for (let i = 0; i < 5; i++) {
                let targets = $targets.closest('.point' + i);
                let deg = Math.PI / 2 / 5 * i;
                animeFireworkPointFunc(targets, deg, r);
            }
            // 第2象限
            for (let i = 0; i < 5; i++) {
                let targets = $targets.closest('.point' + (i + 5));
                let deg = Math.PI / 2 / 5 * i + Math.PI / 2;
                animeFireworkPointFunc(targets, deg, r);
            }
            // 第3象限
            for (let i = 0; i < 5; i++) {
                let targets = $targets.closest('.point' + (i + 10));
                let deg = Math.PI / 2 / 5 * i + Math.PI;
                animeFireworkPointFunc(targets, deg, r);
            }
            // 第4象限
            for (let i = 0; i < 5; i++) {
                let targets = $targets.closest('.point' + (i + 15));
                let deg = Math.PI / 2 / 5 * i + Math.PI / 2 + Math.PI;
                animeFireworkPointFunc(targets, deg, r);
            }
        }
        let animeFireworkPointFunc = function ($targets, deg, r) {
            let translateX = r * Math.cos(deg);
            let translateY = -1 * r * Math.sin(deg);
            anime({
                targets: $targets[0],
                translateX: { value: translateX },
                translateY: { value: translateY },
                direction: 'normal',
                duration: 1000, // 持续时间
                autoplay: true, //自动播放
                easing: 'easeOutBack', //时间曲线
                complete: () => {
                    anime.remove($targets);
                    $targets.remove();
                }
            });
        }

复制代码

动画1.gif

多个烟花

  • 什么?一个烟花不够看,那我们就放50个试一试!!!
for (let i = 0; i < 50; i++) {
    let $targets = $("<div class='firework'></div>");
    $(".sky").append($targets);
    Firework($targets);
}
复制代码

我来看效果

动画.gif

扫描二维码关注公众号,回复: 13666748 查看本文章

完整代码

let clientWidth = document.body.clientWidth
        let clientHeight = document.body.clientHeight
        $(() => {
            for (let i = 0; i < 50; i++) {
                let $targets = $("<div class='firework'></div>");
                $(".sky").append($targets);
                Firework($targets);
            }
        });
        let Firework = ($targets) => {
            let left = Math.ceil(100 * Math.random()) + '%';
            let bottom = Math.ceil(150 * Math.random()) + clientHeight / 2;
            let color = 'linear-gradient(rgb(' + Math.ceil(Math.random() * 255) + ', ' + Math.ceil(Math.random() * 255) + ', 255), rgba(0, 0, 255, 0))';
            let delay = 1000 * Math.ceil(5 * Math.random());
            $targets.css({
                "background": color,
                "left": left,
            });
            let tl = anime.timeline({
                targets: $targets[0],
                delay: delay,
                opacity: 1,
                duration: 500
            });
            tl.add({
                targets: $targets[0],
                bottom: bottom,
                height: [5, 100, 0],
                duration: 2000,
                delay: delay,
                easing: 'linear',
                complete: () => {
                    let $html = $(renderFireworkPoint());
                    $(".sky").append($html);
                    $html.closest(".firecracker").css({ left, bottom, background: color });
                    animeFireworkPoint($html, 60);
                    $targets.remove();
                }
            });
        }
        let renderFireworkPoint = () => {
            let html = '';
            for (let i = 0; i < 20; i++) {
                html += `<div class="firecracker point${i}"></div>`
            }
            return html;
        }
        let animeFireworkPoint = ($targets, r) => {
            // 第1象限
            for (let i = 0; i < 5; i++) {
                let targets = $targets.closest('.point' + i);
                let deg = Math.PI / 2 / 5 * i;
                animeFireworkPointFunc(targets, deg, r);
            }
            // 第2象限
            for (let i = 0; i < 5; i++) {
                let targets = $targets.closest('.point' + (i + 5));
                let deg = Math.PI / 2 / 5 * i + Math.PI / 2;
                animeFireworkPointFunc(targets, deg, r);
            }
            // 第3象限
            for (let i = 0; i < 5; i++) {
                let targets = $targets.closest('.point' + (i + 10));
                let deg = Math.PI / 2 / 5 * i + Math.PI;
                animeFireworkPointFunc(targets, deg, r);
            }
            // 第4象限
            for (let i = 0; i < 5; i++) {
                let targets = $targets.closest('.point' + (i + 15));
                let deg = Math.PI / 2 / 5 * i + Math.PI / 2 + Math.PI;
                animeFireworkPointFunc(targets, deg, r);
            }
        }
        let animeFireworkPointFunc = function ($targets, deg, r) {
            let translateX = r * Math.cos(deg);
            let translateY = -1 * r * Math.sin(deg);
            anime({
                targets: $targets[0],
                translateX: { value: translateX },
                translateY: { value: translateY },
                direction: 'normal',
                duration: 1000, // 持续时间
                autoplay: true, //自动播放
                easing: 'easeOutBack', //时间曲线
                complete: () => {
                    anime.remove($targets);
                    $targets.remove();
                }
            });
        }
复制代码

结语

  • 首先很感谢大家看到这里,这次的文章就分享到这里,祝大家新春快乐,虎虎生威生,龙活虎
  • 如果对大家有帮助或收获的,点赞鼓励!谢谢!!!

往期文章

猜你喜欢

转载自juejin.im/post/7053444656830349348