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>

目录结构

相关推荐
文心快码BaiduComate4 分钟前
新增Zulu-CLI、企业版对话支持自定义模型、一键设置自动执行、复用相同终端,8月新能力速览!
前端·后端·程序员
walking9577 分钟前
JavaScript 神技巧!从 “堆代码” 到 “写优雅代码”,前端人必看
前端·面试
前端西瓜哥12 分钟前
图形编辑器开发:基于矩阵的画布缩放和移动实现
前端
walking95712 分钟前
前端 er 收藏!高性价比 JS 工具库,轻量又强大
前端·面试
gongzemin21 分钟前
Vue 项目权限管理 路由 按钮权限
前端·vue.js
walking95728 分钟前
效率党必藏! JavaScript 自动化脚本,覆盖文件管理、天气查询、通知提醒(含详细 demo)
前端·面试
lichenyang45329 分钟前
用React写一个技能冷却的案例,关于节流
前端
wuzuyu36531 分钟前
SyntaxError: Failed to execute ‘open‘ on ‘XMLHttpRequest‘: Invalid URL
ajax·html·api
walking95732 分钟前
前端进阶必看!藏在浏览器与代码里的技巧
前端
又写一个小bug1 小时前
如何让你的Vue项目支持局域网访问 - 完整指南
前端