0


程序员过圣诞 | 用HTML写出绽放的烟花

文章目录


一、前言

2022年圣诞节到来啦,圣诞节是基督教纪念耶稣诞生的重要节日。亦称耶稣圣诞节、主降生节,天主教亦称耶稣圣诞瞻礼。耶稣诞生的日期,《圣经》并无记载。公元336年罗马教会开始在12月25日过此节。12月25日原是罗马帝国规定的太阳神诞辰。有人认为选择这天庆祝圣诞,是因为基督教徒认为耶稣就是正义、永恒的太阳。5世纪中叶以后,圣诞节作为重要节日,成了教会的传统,并在东西派教会中逐渐传开。因所用历法不同等原因,各教派会举行庆祝的具体日期和活动形式也有差别。圣诞节习俗传播到亚洲主要是在十九世纪中叶,日本、韩国等都受到了圣诞文化的影响。现在西方在圣诞节常互赠礼物,举行欢宴,并以圣诞老人、圣诞树等增添节日气氛,已成为普遍习俗。圣诞节也成为西方世界以及其他很多地区的公共假日。

二、创意名

圣诞节就要到了,本篇我们将用html+js写一个动态的烟花代码,程序员的浪漫这不就来了吗,感兴趣的小伙伴可下载学习,安静的在家中读懂它的那一刻,在这疫情肆虐的日子里也是一件很不错的事,将有趣的东西分享给你,希望你度过一个愉快的圣诞节!

三、效果展示

基础版动画效果,有声音

在这里插入图片描述
进阶版动画效果,可点击绽放烟花

在这里插入图片描述

四、烟花代码

动画主要由焰火类,背景图和随机函数等组成。进阶版可点击屏幕直接开始绽放烟花。
以下是HTML部分,完整代码及效果点击下载👉烟花代码
进阶版👉烟花代码2

<!doctypehtml><html><head><metacharset="utf-8"><title>动态烟花代码</title><style>html,
        *{margin: 0;padding: 0
        }body{background-image:url(bg.png);background-size: 100% 100%;background-size: 100%;background-repeat:no-repeat;}.demo{margin: 0 auto;width: 100%;height: 100%;}h1{margin: 150px auto 30px auto;text-align: center;font-family:'Roboto';}</style></head><body><divclass="demo"></div><scriptsrc="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script><scriptsrc="fireworks.js"></script><script>$('.demo').fireworks({sound:true,opacity:0.6,width:'100%',height:'100%'});</script></body></html>

js部分

// 焰火集合类classFireworks{
    _timer =null
    _animater =null
    _useAnimationFrame =true
    
    ctx =null// 画布上下文,都画这上面
    offScreenCtx =null// 离屏 canvas,优化性能
    fps =60// 帧率控制
    fireworks =[]// 焰火数组
    fireworkCount =8// 焰火数量
    fireworkInterval =400// 焰火爆炸间隔💥
    fireworkColors =DEFAULT_COLORS// 焰火颜色随机取值数组
    particleOptions ={// 粒子配置size:15,// 几块钱的烟花speed:15,// 燃烧的速度gravity:0.08,// 🌍 地球的引力,向下的power:0.93,// 动力,值越大冲越远shrink:0.97,// 燃料消耗的速度jitter:1,// 摇摇晃摇color:'hsla(210, 100%, 50%, 1)',// 颜色}constructor(dom, options ={}){if(!(dom instanceofHTMLElement)){
        options = dom ||{}}if(!dom){
        dom = document.body
      }this.initCanvas(dom)const{ particleOptions ={},...others }= options
      this.particleOptions ={...this.particleOptions,...particleOptions }
      Object.keys(others).forEach(key=>this[key]= others[key])this._useAnimationFrame =this.fps >=60}// 初始化画布initCanvas(dom){let canvas = dom
  
      const isCanvas = canvas.nodeName.toLowerCase()==='canvas'if(!isCanvas){
        canvas = document.createElement('canvas')
        dom.appendChild(canvas)}const{ width, height }= dom.getBoundingClientRect()
      canvas.width = width
      canvas.height = height
      canvas.style.cssText =`width: ${width}px; height: ${height}px;`this.ctx = canvas.getContext('2d')const offScreenCanvas = canvas.cloneNode()this.offScreenCtx = offScreenCanvas.getContext('2d')}// 创建单个焰火createFirework(x, y, color){const{ ctx, particleOptions, fireworkColors }=thisconst{ width, height }= ctx.canvas
      x = x ??random(width *0.1, width *0.9)
      y = y ??random(height *0.1, height *0.9)
      color = color ??random(fireworkColors)const particleCount =random(80,100)const firework =newFirework({ particleOptions, particleCount, x, y, color })this.fireworks.push(firework)}// 焰火燃尽,无情灭之checkFireworks(){this.fireworks =this.fireworks.filter(firework=>!firework.isBurnOff())}// 检查是否需要创建焰火loop(){let interval =this.fireworkInterval *random(0.5,1)this._timer =setTimeout(()=>{this.checkFireworks()if(this.fireworks.length <this.fireworkCount){this.createFirework()}this.loop()}, interval)}// 绘制焰火render(animationFunction, interval){this._animater =animationFunction(()=>{const{ width, height }=this.ctx.canvas
  
        // 通过绘制黑色透明图层,达到尾焰的效果this.ctx.fillStyle ='rgba(0, 0, 0, 0.05)'this.ctx.fillRect(0,0, width, height)this.offScreenCtx.clearRect(0,0, width, height)this.fireworks.forEach(firework=>{
          firework.render(this.offScreenCtx)})this.ctx.save()this.ctx.globalCompositeOperation ='lighter'this.ctx.drawImage(this.offScreenCtx.canvas,0,0, width, height)this.ctx.restore()this.render(animationFunction, interval)}, interval)}// 前进四 !!!start(){this.loop()// 60 帧就用 requestAnimationFrame,否则用 setTimeoutconst animationFunction =this._useAnimationFrame ? requestAnimationFrame : setTimeout
      const interval =16.67*(60/this.fps)this.render(animationFunction, interval)}// 休息一下pause(){this._timer &&clearTimeout(this._timer)this._animater &&(this._useAnimationFrame ?cancelAnimationFrame(this._animater):clearTimeout(this._animater))this._timer =nullthis._animater =null}// 结束吧这个世界stop(){this.pause()this.fireworks.length =0const{ width, height }=this.ctx.canvas()this.ctx.clearRect(0,0, width, height)}}// 焰火类classFirework{
    _status =STATUS.INIT
  
    x =0
    y =0
  
    color ='rgba(255, 255, 255, 1)'
    particleCount =80
    particles =[]
    particleOptions ={}constructor(options ={}){
      Object.keys(options).forEach(key=>this[key]= options[key])this._status =STATUS.INITthis.initParticles()}// 初始化粒子initParticles(){const{ x, y, color, particleOptions }=thisconst{size: baseSize }= particleOptions
  
      for(let index =0; index <this.particleCount; index++){const size =random(-baseSize /2, baseSize /2)+ baseSize
        const particle =newParticle({...particleOptions, x, y, size, color })this.particles.push(particle)}}// 更新粒子updateParticles(){this.particles.forEach(particle=> particle.update())this.particles =this.particles.filter(particle=>!particle.isBurnOff())// 拥有的粒子都燃尽了,自己也就结束了if(this.particles.length ===0){this._status =STATUS.COMPLETED}}// 渲染粒子render(ctx){this.updateParticles()if(this.isBurnOff())returnthis.particles.forEach(particle=>{
        particle.render(ctx)})}isBurnOff(){returnthis._status ===STATUS.COMPLETED}}// 焰火粒子类classParticle{
    size =10
    speed =15
    gravity =0.2
    power =0.92
    shrink =0.93
    jitter =0.08
    color ='hsla(210, 100%, 50%, 1)'
    shadowColor ='hsla(210, 100%, 50%, 0.1)'
  
    x =0// x 坐标位置
    y =0// y 坐标位置
  
    vel ={// 速度x:0,y:0,}constructor(options){
      Object.keys(options).forEach(key=>{this[key]= options[key]})const angle =random(0, Math.PI*2)const speed = Math.cos(random(0, Math.PI/2))*this.speed
      this.vel ={x: Math.cos(angle)* speed,y: Math.sin(angle)* speed,}this.shadowColor =tinycolor(this.color).setAlpha(0.1)}// 移形换位update(){this.vel.x *=this.power
      this.vel.y *=this.power
  
      this.vel.y +=this.gravity
  
      const jitter =random(-1,1)*this.jitter
      this.x +=this.vel.x + jitter
      this.y +=this.vel.y + jitter
  
      this.size *=this.shrink
    }// 绘制单粒子render(ctx){if(this.isBurnOff())return
  
      ctx.save()const{ x, y, size, color, shadowColor }=this// 红里透白,像极了爱情const gradient = ctx.createRadialGradient(x, y,0, x, y, size /2)
      gradient.addColorStop(0.1,'rgba(255, 255, 255, 0.3)')
      gradient.addColorStop(0.6, color)
      gradient.addColorStop(1, shadowColor)
  
      ctx.fillStyle = gradient
  
      // ctx.beginPath()// ctx.arc(x, y, size, 0, Math.PI * 2, true)// ctx.closePath()// ctx.fill()// 绘制矩形性能更好
      ctx.fillRect(x, y, size, size)
  
      ctx.restore()}// 小到看不到isBurnOff(){returnthis.size <1}}

五、总结

圣诞节,玲儿响,温情祝福传递忙;喜盛宴,披红装,圣诞金娃送吉祥;夜月美,心儿醉,吉祥安康永相随;平安夜,送平安,幸福快乐人变美。最后,祝所有和我一样即将考研的人旗开得胜,坚持就是胜利,世上无难事,只要肯攀登。


本文转载自: https://blog.csdn.net/CSDN_anhl/article/details/128437420
版权归原作者 亮点菌 所有, 如有侵权,请联系我们删除。

“程序员过圣诞 | 用HTML写出绽放的烟花”的评论:

还没有评论