烟花效果图如下:
代码如下:
工具函数
// 获取随机颜色的函数
function getColor(){
var color = '#';
for(var i=0;i<3;i++){
var hex = getRandom(256).toString(16)
hex = hex.length===1?'0'+hex:hex;
color += hex
}
return color
}
// 获取随机数的函数
function getRandom(a, b = 0){
var max = a;
var min = b;
if(a<b){
max = b;
min = a;
}
return Math.floor(Math.random() * (max - min)) + min
}
// 设置样式的函数
function setStyle(ele, styleObj){
for(var attr in styleObj){
ele.style[attr] = styleObj[attr]
}
}
实现效果的代码:
// 创建夜空大盒子
var nightSky = document.createElement('div')
// 设置样式
setStyle(nightSky, {
width:"1000px",
height:"500px",
border:"10px solid #00f",
backgroundColor:"#000",
position:"relative"
})
// 将创建好的夜空放在body中
document.body.appendChild(nightSky)
// 点击夜空
nightSky.onclick = function(){
// 获取光标在大盒子上的位置
var e = window.event;
var x = e.offsetX;
var y = e.offsetY;
// 创建一个小烟花div
var fire = document.createElement('div')
// 设置样式
setStyle(fire, {
width:"10px",
height:"10px",
backgroundColor:getColor(),
position:"absolute",
left:x + 'px',
bottom:0
})
// 将这个小烟花放在夜空中
nightSky.appendChild(fire)
// 让这个小烟花升到空中
toUp(fire,x,y)
}
// 让小烟花升到空中
function toUp(fire,x,y){
// 获取小烟花的top值
var t = fire.offsetTop;
// 设置定时器让top值逐渐减小
var timerId = setInterval(function(){
t -= 5
// 当top值到了鼠标点击的位置 - 就停止定时器
if(t<=y){
t = y
clearInterval(timerId)
// 将当前这个小烟花删除掉
nightSky.removeChild(fire)
// 创建很多小烟花
createManyFire(x,y)
}
// 将减小后的top设置给小烟花
fire.style.top = t + 'px'
},5)
}
// 创建很多小烟花
function createManyFire(x,y){
// 获取一个30~50的随机数
var num = getRandom(30,50)
// 循环创建30~50个小烟花
for(let i=0;i<num;i++){
// 创建div
let div = document.createElement('div')
// 设置样式
setStyle(div, {
width:"10px",
height:"10px",
backgroundColor:getColor(),
position:"absolute",
left:x + 'px',
top: y + 'px',
borderRadius:"50%"
})
// 将小烟花放到夜空中
nightSky.appendChild(div)
// 让烟花炸开 - 将每个小div移动到随机位置
boom(div, x, y)
}
}
// 小烟花炸开
function boom(ele, x, y){
// 获取一个随机位置
let targetPosition = {
left:getRandom(nightSky.clientWidth-10),
top:getRandom(nightSky.clientHeight-10)
}
// ele当前的位置
let currentPosition = {
left:x,
top:y
}
// 让left和top同时移动,就通过循环设置两个定时器
for(let attr in targetPosition){
// 获取每个定时器中使用的目标位置
let target = targetPosition[attr]
// 获取每个定时器中使用的当前位置
let currentStyle = currentPosition[attr]
// 定义停止定时器数量
var k = 0
let timerId = setInterval(function(){
// 定义每次移动的距离
let percent = (target - currentStyle)/20
// 如果小于0就向下取整变成整数,如果大于0就向上取整变成整数
// -0.1 -- 1 0.2 -- 1 目的是让div向前移动
percent = percent>0?Math.ceil(percent):Math.floor(percent);
// 让当前的值跟计算好的距离相加
currentStyle += percent;
// 设置样式
ele.style[attr] = currentStyle + 'px'
// 如果移动的值跟目标位置相等了
if(currentStyle === target){
// 停止当前定时器
clearInterval(timerId)
// 定时器停止数量自增
k++
// 当停止了2次定时器时
if(k === 2){
// 将当前元素删除
nightSky.removeChild(ele)
}
}
},20)
}
}