简易烟花效果


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

</body>
<script src="./js/utils.js"></script>
<script>
// 烟花效果逻辑:
/*
创建夜空 - 创建div,放在body中,设置样式
给夜空绑定单击事件
记录鼠标的位置 - 使用事件对象的pageX  pageY
创建小烟花 - 创建小div,设置样式,放在夜空中 - 设置left值是鼠标的pageX
烟花上升到鼠标位置 - 给小div添加动画效果 - top属性的动画 - pageY
在这个位置创建很多小div - 指定创建数量 - 循环创建 - 添加样式 - 放在夜空中
让每个小div都动画到一个随机位置 - 在夜空中获取一个随机坐标 - 设置小div动画到随机位置
到了随机位置以后,把小div删掉 - 动画结束后,清除定时器,删除小div - 夜空.removeChild(小div)
*/

function FireWorks(){
    // 给对象添加属性 - 创建标签作为对象的属性
    this.nightSky = document.createElement('div')
    // 设置样式
    this.setStyle(this.nightSky, {
        width: '1000px',
        height: '500px',
        backgroundColor: '#000',
        border: '10px solid #00f',
        position: 'relative'
    })
    // 将夜空放在body中
    document.body.appendChild(this.nightSky)
    // 绑定事件
    this.nightSky.onclick = () => {
        var e = window.event;
        var x = e.pageX;
        var y = e.pageY;
        // 调用创建小烟花的方法
        this.createFire(x, y)
    }
}
// 创建小烟花的方法
FireWorks.prototype.createFire = function(x, y){
    // 创建小div
    var fire = document.createElement('div')
    // 设置样式
    this.setStyle(fire, {
        width: '10px',
        height: '10px',
        backgroundColor: this.getColor(),
        left: x + 'px',
        bottom: 0,
        position: 'absolute'
    })
    // 将小烟花放在夜空中
    this.nightSky.appendChild(fire)
    // 让小烟花升空
    this.toSky(x, y, fire)
}
// 小烟花升空的方法
FireWorks.prototype.toSky = function(x, y, fire){
    // 调用工具库中的animate函数实现动画
    animate(fire, {
        top: y
    }, () => {
        // 将原来的一个小烟花删除
        fire.parentElement.removeChild(fire)
        // console.log(this);
        // console.log('升空结束');
        // 当前升空动画结束以后,创建30~50个小烟花
        var num = this.getRandom(30, 50)
        // console.log(num);
        // 循环创建很多小div
        for(let i=0;i<num;i++){
            // 创建小div
            var div = document.createElement('div')
            // 设置样式
            this.setStyle(div, {
                width: '10px',
                height: '10px',
                backgroundColor: this.getColor(),
                position: 'absolute',
                left: x + 'px',
                top: y + 'px',
                borderRadius: '50%'
            })
            // 放在夜空中
            this.nightSky.appendChild(div)
            // 每个小烟花要炸开
            this.boom(div)
        }
    })
}
// 炸开的方法
FireWorks.prototype.boom = function(ele){
    // 让ele动画到一个随机位置
    // 获取随机位置
    var randomLeft = this.getRandom(this.nightSky.clientWidth - 10)
    var randomTop = this.getRandom(this.nightSky.clientHeight - 10)
    // 让ele开始动画
    animate(ele, {
        left: randomLeft,
        top: randomTop
    }, () => {
        // console.log("动画结束了");
        // 让夜空删掉ele
        ele.parentElement.removeChild(ele)
    })
}
// 获取随机颜色的方法
FireWorks.prototype.getColor = function(){
    var color = '#'
    for(var i=0;i<3;i++){
        var hex = this.getRandom(256).toString(16)
        hex = hex.length === 1 ? '0' + hex : hex;
        color += hex
    }
    return color
}
// 获取随机数的方法
FireWorks.prototype.getRandom = function(a, b = 0){
    var abs = Math.abs(a - b)
    var min = Math.min(a, b)
    return Math.floor(Math.random() * abs) + min
}
// 批量设置样式的方法
FireWorks.prototype.setStyle = function(ele, styleObj){
    for(var key in styleObj){
        ele.style[key] = styleObj[key]
    }
}

var f = new FireWorks()
console.log(f);
</script>
</html>

/**
 * 获取随机数的函数
 * @param {number} a 代表范围的数字
 * @param {number} b 代表范围的数字
 * @return {number} 返回范围内的随机整数
 */
function getRandom(a, b){
    return Math.floor(Math.random() * Math.abs(a - b)) + Math.min(a, b)
}
/**
 * 获取16进制的随机颜色值
 */
function getColor(){
    var color = '#'
    for(var i=0;i<3;i++){
        var hex = getRandom(0, 256).toString(16)
        color += hex.length === 1 ? '0' + hex : hex;
    }
    return color
}
/**
 * 批量设置样式的函数
 * @param {node} ele 被设置样式的标签对象
 * @param {object} styleObj 要设置的样式组成的键值对
 */
function setStyle(ele, styleObj){
    for(var key in styleObj){
        ele.style[key] = styleObj[key]
    }
}
/**
 * 进行动画的函数
 * @param {node} ele 要进行动画的元素
 * @param {object} obj 动画的属性和值组成的键值对
 * @param {function} fn 动画结束后要执行的函数
 */
function animate(ele, obj, fn){ 
    var k = 0
    for(var key in obj){
        k++
        (function(key){
            var currentStyle = getComputedStyle(ele)[key]
            var target = obj[key]
            if(key === 'opacity'){
                currentStyle *= 100
                target *= 100
            }
            currentStyle = parseInt(currentStyle)
            var timerId = setInterval(function(){
                var speed = (target - currentStyle) / 20
                currentStyle += speed > 0 ? Math.ceil(speed) : Math.floor(speed)
                if(key === 'opacity') ele.style[key] = currentStyle / 100
                else ele.style[key] = currentStyle + 'px'
                if(currentStyle === target){
                    clearInterval(timerId)
                    if(--k === 0) fn()
                }
            }, 20)
        })(key)
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值