PK创意闹新春,我正在参加「春节创意投稿大赛」,详情请看:春节创意投稿大赛
背景
这一次的活动主题是春节创意大赛,春节我第一想到的就是烟花
,以前武汉江滩都会有跨年烟花表演。因为疫情还有保护环境的原因,武汉已经好多年没有烟花表演了,所以我想用代码实现烟花表演。话不多说,我们看代码:
技术
- animejs
- jquery
实现
静态页面
- 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;
}
复制代码
有了上面的代码就可以实现一个静态的页面(武汉江滩夜间图)了,效果如下:
实现烟花动画
问:“实现烟花要几步了?”
答:“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();
}
});
}
复制代码
多个烟花
- 什么?一个烟花不够看,那我们就放50个试一试!!!
for (let i = 0; i < 50; i++) {
let $targets = $("<div class='firework'></div>");
$(".sky").append($targets);
Firework($targets);
}
复制代码
我来看效果
完整代码
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();
}
});
}
复制代码
结语
- 首先很感谢大家看到这里,这次的文章就分享到这里,祝大家新春快乐,虎虎生威生,龙活虎
- 如果对大家有帮助或收获的,点赞鼓励!谢谢!!!