HTML5之 夜景放烟花

参考网址

https://blog.csdn.net/Gou_Hailong/article/details/122269931

https://blog.csdn.net/u013343616/article/details/122233674

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=gb2312">
  <style>
    body{margin:0;padding:0;overflow: hidden;}
    .city{width:100%;position:fixed;bottom: 0px;z-index: 100;}
    .city img{width: 100%;}
  </style>
  <title>html5夜景放烟花绽放动画效果</title>
</head>
<body onselectstart = "return false">

<div style="height:700px;overflow:hidden;">

  <canvas id='cas' style="background-color:rgba(0,5,24,1);">浏览器不支持canvas</canvas>
  <div class="city"><img src="img/city.png" alt="" /></div>
  <img src="img/moon.png" alt="" id="moon" style="visibility: hidden;"/>
  <div style="display:none">
    <div class="shape">新年快乐</div>
    <div class="shape">合家幸福</div>
        <div class="shape">万事如意</div>
        <div class="shape">心想事成</div>
        <div class="shape">财源广进</div>
  </div>
  
</div>

  <script>
    var canvas = document.getElementById("cas");
    var ocas = document.createElement("canvas");
    var octx = ocas.getContext("2d");
    var ctx = canvas.getContext("2d");
    ocas.width = canvas.width = window.innerWidth;
    ocas.height = canvas.height = 700;
    var bigbooms = [];
  
    window.onload = function(){
      initAnimate()
    }

    function initAnimate(){
      drawBg();

      lastTime = new Date();
      animate();
    }

    var lastTime;
    function animate(){
      ctx.save();
      ctx.fillStyle = "rgba(0,5,24,0.1)";
      ctx.fillRect(0,0,canvas.width,canvas.height);
      ctx.restore();


      var newTime = new Date();
            if(newTime-lastTime>500+(window.innerHeight-767)/2){
        var random = Math.random()*100>2?true:false;
        var x = getRandom(canvas.width/5 , canvas.width*4/5);
        var y = getRandom(50 , 200);
        if(random){
          var bigboom = new Boom(getRandom(canvas.width/3,canvas.width*2/3) ,2,"#FFF" , {x:x , y:y});
          bigbooms.push(bigboom)
        }
        else {
          var bigboom = new Boom(getRandom(canvas.width/3,canvas.width*2/3) ,2,"#FFF" , {x:canvas.width/2 , y:200} , document.querySelectorAll(".shape")[parseInt(getRandom(0, document.querySelectorAll(".shape").length))]);
          bigbooms.push(bigboom)
        }
        lastTime = newTime;
        console.log(bigbooms)
      }

      stars.foreach(function(){
        this.paint();
      })

      drawMoon();

      bigbooms.foreach(function(index){
        var that = this;
        if(!this.dead){
          this._move();
          this._drawLight();
        }
        else{
          this.booms.foreach(function(index){
            if(!this.dead) {
              this.moveTo(index);
            }
            else if(index === that.booms.length-1){
              bigbooms[bigbooms.indexOf(that)] = null;
            }
          })
        }
      });
      
      raf(animate);
    }

    function drawMoon(){
      var moon = document.getElementById("moon");
      var centerX = canvas.width-200 , centerY = 100 , width = 80;
      if(moon.complete){
        ctx.drawImage(moon , centerX , centerY , width , width )
      }
      else {
        moon.onload = function(){
          ctx.drawImage(moon ,centerX , centerY , width , width)
        }
      }
      var index = 0;
      for(var i=0;i<10;i++){
        ctx.save();
        ctx.beginPath();
        ctx.arc(centerX+width/2 , centerY+width/2 , width/2+index , 0 , 2*Math.PI);
        ctx.fillStyle="rgba(240,219,120,0.005)";
        index+=2;
        ctx.fill();
        ctx.restore();
      }
      
    }
	
	    Array.prototype.foreach = function(callback){
	      for(var i=0;i<this.length;i++){
	        if(this[i]!==null) callback.apply(this[i] , [i])
	      }
	    }

	    var raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); };
	    
	    canvas.onclick = function(){
	      var x = event.clientX;
	      var y = event.clientY;
	      var bigboom = new Boom(getRandom(canvas.width/3,canvas.width*2/3) ,2,"#FFF" , {x:x , y:y});
	      bigbooms.push(bigboom)
	    }
	
	    // canvas.addEventLisener("touchstart" , function(event){
	    //  var touch = event.targetTouches[0];
	    //  var x = event.pageX;
	    //  var y = event.pageY;
	    //  var bigboom = new Boom(getRandom(canvas.width/3,canvas.width*2/3) ,2,"#FFF" , {x:x , y:y});
	    //  bigbooms.push(bigboom)
	    // })
	
	    var Boom = function(x,r,c,boomArea,shape){
	      this.booms = [];
	      this.x = x;
	      this.y = (canvas.height+r);
	      this.r = r;
	      this.c = c;
	      this.shape = shape || false;
	      this.boomArea = boomArea;
	      this.theta = 0;
	      this.dead = false;
	      this.ba = parseInt(getRandom(80 , 200));
	    }
	    Boom.prototype = {
	      _paint:function(){
	        ctx.save();
	        ctx.beginPath();
	        ctx.arc(this.x,this.y,this.r,0,2*Math.PI);
	        ctx.fillStyle = this.c;
	        ctx.fill();
	        ctx.restore();
	      },
	      _move:function(){
	        var dx = this.boomArea.x - this.x , dy = this.boomArea.y - this.y;
	        this.x = this.x+dx*0.01;
	        this.y = this.y+dy*0.01;
	
	        if(Math.abs(dx)<=this.ba && Math.abs(dy)<=this.ba){
	          if(this.shape){
	            this._shapBoom();
	          }
	          else this._boom();
	          this.dead = true;
	        }
	        else {
	          this._paint();
	        }
	      },
	      _drawLight:function(){
	        ctx.save();
	        ctx.fillStyle = "rgba(255,228,150,0.3)";
	        ctx.beginPath();
	        ctx.arc(this.x , this.y , this.r+3*Math.random()+1 , 0 , 2*Math.PI);
	        ctx.fill();
	        ctx.restore();
	      },
	      _boom:function(){
	        var fragNum = getRandom(30 , 200);
	        var style = getRandom(0,10)>=5? 1 : 2;
	        var color;
	        if(style===1){
	          color = {
	            a:parseInt(getRandom(128,255)),
	            b:parseInt(getRandom(128,255)),
	            c:parseInt(getRandom(128,255))
	          }
	        }
	
	        var fanwei = parseInt(getRandom(300, 400));
	        for(var i=0;i<fragNum;i++){
	          if(style===2){
	            color = {
	              a:parseInt(getRandom(128,255)),
	              b:parseInt(getRandom(128,255)),
	              c:parseInt(getRandom(128,255))
	            }
	          }
	          var a = getRandom(-Math.PI, Math.PI);
	          var x = getRandom(0, fanwei) * Math.cos(a) + this.x;
	          var y = getRandom(0, fanwei) * Math.sin(a) + this.y; 
	          var radius = getRandom(0 , 2)
	          var frag = new Frag(this.x , this.y , radius , color , x , y );
	          this.booms.push(frag);
	        }
	      },
	      _shapBoom:function(){
	        var that = this;
	        putValue(ocas , octx , this.shape , 5, function(dots){
	          var dx = canvas.width/2-that.x;
	          var dy = canvas.height/2-that.y;
	          for(var i=0;i<dots.length;i++){
	            color = {a:dots[i].a,b:dots[i].b,c:dots[i].c}
	            var x = dots[i].x;
	            var y = dots[i].y;
	            var radius = 1;
	            var frag = new Frag(that.x , that.y , radius , color , x-dx , y-dy);
	            that.booms.push(frag);
	          }
	        })
	      }
	    }
	
	    function putValue(canvas , context , ele , dr , callback){
	      context.clearRect(0,0,canvas.width,canvas.height);
	      var img = new Image();
	      if(ele.innerHTML.indexOf("img")>=0){
	        img.src = ele.getElementsByTagName("img")[0].src;
	        imgload(img , function(){
	          context.drawImage(img , canvas.width/2 - img.width/2 , canvas.height/2 - img.width/2);
	          dots = getimgData(canvas , context , dr);
	          callback(dots);
	        })
	      }
	      else {
	        var text = ele.innerHTML;
	        context.save();
	        var fontSize =200;
	        context.font = fontSize+"px 宋体 bold";
	        context.textAlign = "center";
	        context.textBaseline = "middle";
	        context.fillStyle = "rgba("+parseInt(getRandom(128,255))+","+parseInt(getRandom(128,255))+","+parseInt(getRandom(128,255))+" , 1)";
	        context.fillText(text , canvas.width/2 , canvas.height/2);
	        context.restore();
	        dots = getimgData(canvas , context , dr);
	        callback(dots);
	      }
	    }
	
	    function imgload(img , callback){
	      if(img.complete){
	        callback.call(img);
	      }
	      else {
	        img.onload = function(){
	          callback.call(this);
	        }
	      }
	    }
	
	    function getimgData(canvas , context , dr){
	      var imgData = context.getImageData(0,0,canvas.width , canvas.height);
	      context.clearRect(0,0,canvas.width , canvas.height);
	      var dots = [];
	      for(var x=0;x<imgData.width;x+=dr){
	        for(var y=0;y<imgData.height;y+=dr){
	          var i = (y*imgData.width + x)*4;
	          if(imgData.data[i+3] > 128){
	            var dot = {x:x , y:y , a:imgData.data[i] , b:imgData.data[i+1] , c:imgData.data[i+2]};
	            dots.push(dot);
	          }
	        }
	      }
	      return dots;
	    }
	
	    function getRandom(a , b){
	      return Math.random()*(b-a)+a;
	    }
	
	
	    var maxRadius = 1 , stars=[];
	    function drawBg(){
	      for(var i=0;i<100;i++){
	        var r = Math.random()*maxRadius;
	        var x = Math.random()*canvas.width;
	        var y = Math.random()*2*canvas.height - canvas.height;
	        var star = new Star(x , y , r);
	        stars.push(star);
	        star.paint()
	      }
	
	    }
	
	    var Star = function(x,y,r){
	      this.x = x;this.y=y;this.r=r;
	    }
	    Star.prototype = {
	      paint:function(){
	        ctx.save();
	        ctx.beginPath();
	        ctx.arc(this.x , this.y , this.r , 0 , 2*Math.PI);
	        ctx.fillStyle = "rgba(255,255,255,"+this.r+")";
	        ctx.fill();
	        ctx.restore();
	      }
	    }
	
	    var focallength = 250;
	    var Frag = function(centerX , centerY , radius , color ,tx , ty){
	      this.tx = tx;
	      this.ty = ty;
	      this.x = centerX;
	      this.y = centerY;
	      this.dead = false;
	      this.centerX = centerX;
	      this.centerY = centerY;
	      this.radius = radius;
	      this.color = color;
	    }
	
	    Frag.prototype = {
	      paint:function(){
	        ctx.save();
	        ctx.beginPath();
	        ctx.arc(this.x , this.y , this.radius , 0 , 2*Math.PI);
	        ctx.fillStyle = "rgba("+this.color.a+","+this.color.b+","+this.color.c+",1)";
	        ctx.fill()
	        ctx.restore();
	      },
	      moveTo:function(index){
	        this.ty = this.ty+0.3;
	        var dx = this.tx - this.x , dy = this.ty - this.y;
	        this.x = Math.abs(dx)<0.1 ? this.tx : (this.x+dx*0.1);
	        this.y = Math.abs(dy)<0.1 ? this.ty : (this.y+dy*0.1);
	        if(dx===0 && Math.abs(dy)<=80){
	          this.dead = true;
	        }
	        this.paint();
	      }
	    }
	  </script>
	
	</body>
	</html>

目录结构

相关推荐
前端小小王33 分钟前
React Hooks
前端·javascript·react.js
迷途小码农零零发42 分钟前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀1 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef3 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
sunshine6413 小时前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻4 小时前
Vue(四)
前端·javascript·vue.js
蜜獾云4 小时前
npm淘宝镜像
前端·npm·node.js
dz88i84 小时前
修改npm镜像源
前端·npm·node.js
Jiaberrr4 小时前
解锁 GitBook 的奥秘:从入门到精通之旅
前端·gitbook