js表白-心形煙花


心形煙花

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .container{
            width: 80%;
            height: 600px;
            border: 2px solid red;
            background: #000;
            margin:20px auto;
            cursor: pointer;
            position: relative;
            left: 0;
            top: 0;
            overflow: hidden;
        }
        .fire{
            width: 6px;
            height:6px;
            position: absolute;
            animation: fireBug 3s infinite;
            bottom: 0;
        }
        @keyframes fireBug{
                  0% {opacity:1;}
                  50% {opacity:0.2;}
                  100% {opacity:1;}
            }
    </style>

</head>
<body>
    <div class="container">

    </div>
    <script src="./animate-opacity.js"></script>
</body>
<script>

    class FireWork{
        constructor(options){
            //單例模式 如果 FireWork上已經有選擇好的元素了,那么我們就不需要重復進行選擇了
            if(FireWork.main && FireWork.main.selector === options.main){
                //已經經歷過元素選擇了,所以直接賦值
                this.main = FireWork.main.ele;
            }else{
                //還沒有進行元素選擇;
                //將需要獲取的DOM放入對象中 , 進行判斷的也放入對象中
                FireWork.main = {
                    ele : document.querySelector(options.main),
                    selector : options.main
                }
                this.main = FireWork.main.ele;
            }
            //獲取煙花爆炸的方式,並放入原型中
            this.blast_type = options.blast_type;
           //將傳入的需要創建的子元素tagName放入原型中
            this.ele_tagName = options.children;
            //將獲取傳入的鼠標點擊位置
            this.x = options.x;
            this.y = options.y;
            //調用初始化方法
            this.init()
        }
        init(){
            //創建DIV
            this.ele = this.createFireWork()
            //設置邊界
            this.left_max = this.main.offsetWidth - this.ele.offsetWidth;
            this.top_max   = this.main.offsetHeight - this.ele.offsetHeight;
            //調用煙花上升的方法
            this.fireWorkUp(this.ele)
        }
        //創建DIV
        createFireWork(){
            var ele = document.createElement(this.ele_tagName)
            ele.className = "fire"
            //調用方法設置隨機顏色
            this.randomColor(ele);
            return  this.main.appendChild(ele)
        }
        //設置煙花上升
         fireWorkUp(ele){
             //設置煙花上升的橫坐標
           ele.style.left = this.x + "px";  
           //調用封裝好的運動JS , 設置元素想上運動   
            animate(ele , {top : this.y} , function(){
                //煙花到達指定地點之后消失
                ele.remove();
                //調用煙花的爆炸效果
                this.fireWorkBlast()
            }.bind(this))
        }
        //煙花爆炸效果
        fireWorkBlast(){
           //設置煙花爆炸之后散發的光點個數 
            for(var i = 0; i < 100; i++){
                //創建對應的DIV
                var ele = this.createFireWork()
                //設置隨機顏色
                this.randomColor(ele);
                //設置隨機位置
                ele.style.left = this.x + "px";
                ele.style.top = this.y + "px";
                ele.style.borderRadius = "50%";
               //判斷爆炸之后的形狀
                switch(this.blast_type){
                    //爆炸之后成圓形
                    case "circle":
                        //設置散發之后成一個圓形
                        animate(ele ,this.circleBlast( i , 20),function(ele){
                            //運動完成之后消失
                            ele.remove()
                        }.bind(this , ele));
                        break;
                    //爆炸之后成心形
                    case "heart":
                        //設置散發之后成一個愛心
                        animate(ele , this.heartBlast(i),function(ele){
                            ele.remove()
                        }.bind(this , ele))
                        break
                    //爆炸之后隨機運動
                    default :
                        animate(ele , this.randomPosition(),function(ele){
                            ele.remove()
                        }.bind(this , ele))
                        break
                }
            }
        }
        //設置隨機顏色
        randomColor(ele){
            return ele.style.backgroundColor = "#" + parseInt(parseInt("ffffff" , 16) * Math.random()).toString(16).padStart(6,0);
        }
        //散發隨機位置
        randomPosition(){
            return {
                left : parseInt(Math.random() * (this.left_max + 1)),
                top : parseInt(Math.random() * (this.top_max + 1))
            }
        }
        //散發形成一個圓形
        circleBlast(index , all){
            var r  = 100;
            var reg = (360 / all) * index;
            var deg = Math.PI / 180 * reg;
            return {
                left : parseInt(r * Math.cos( deg )) + this.x,
                top  : parseInt(r * Math.sin( deg )) + this.y
            }
        }
        //散發成一個愛心
        heartBlast(i){
            var r  = 60;
            var m = i;
            var n = -r * (((Math.sin(i) * Math.sqrt(Math.abs(Math.cos(i)))) / (Math.sin(i) + 1.4)) - 2 * Math.sin(i) + 2);
            return {
                left : n * Math.cos(m) + this.x,
                top  : n * Math.sin(m) + this.y
            }
        }

    }

    var ele_con = document.querySelector(".container")
    ele_con.addEventListener("click" , function(evt ){
            var e = evt || event;
            new FireWork({
            main : ".container",
            children : "div",
            x : e.offsetX , 
            y : e.offsetY,
            blast_type : "heart" //設置煙花爆炸之后的形狀
        });
    })
</script>
</html>

引入的的js文件

function animate( ele , attr_options , callback ){
    for(var attr in attr_options){
        // console.log(attr_options , attr_options[attr])
        attr_options[attr] = {
            //  目標點 : 傳入的數據;
            target : attr === "opacity" ? attr_options[attr] * 100 : attr_options[attr],
            //  元素當前的屬性值 ;
            iNow   : attr === "opacity" ? parseInt( getComputedStyle(ele)[attr] * 100 ) : parseInt( getComputedStyle(ele)[attr])
        }
        // console.log(attr_options , attr_options.width)
    }
    // 關閉開啟定時器;
    clearInterval( ele.timer );
    ele.timer = setInterval( function(){
        // 1. 獲取速度; width :  height : 
        for(var attr in attr_options){
            // attr : width | height;
            var item = attr_options[attr];
            // console.log(item , attr);
            var target = item.target;
            var iNow   = item.iNow;
            // 運動所必須的值我們都有了;
            // 計算速度;
            var speed = (target - iNow) / 20;
            // 速度取整;
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

            // 終止條件 : 
            if( Math.abs( target - iNow) <= Math.abs(speed) ){
                // 終止定時器 ; 
                // 送他一把;
                // clearInterval( ele.timer );
                // ele.style[attr] = target + "px";
                // 終止條件不可靠,因為目標的不一致會讓運動次數執行不同,有可能提前關閉定時器;
                ele.style[attr] = attr === "opacity" ? target / 100 :  target + "px";
                // 一條運動完成刪除對象里面的數據;
                delete attr_options[attr];

                // 如果對象里面沒有屬性了,那么我們關閉定時器就可以了;
                for(var num in attr_options){
                    // 如果attr_options里面有屬性,那么此時我就不應該終止定時器;
                    return false;
                }
                clearInterval(ele.timer);
                typeof callback === "function" ? callback() : "";
            }else{
                // 元素運動;
                // 因為 iNow 是一個臨時變量,所以不能再去操作iNow , 要去操作iNow 的數據源;
                // 多花點經歷理解這段代碼;
                attr_options[attr].iNow += speed;
                ele.style[attr] = attr === "opacity" ? attr_options[attr].iNow / 100 : attr_options[attr].iNow + "px";
            }
        }
    } , 30)
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM