UNPKG

@9am/fire-flame

Version:
22 lines (21 loc) 7.5 kB
"use strict";var q=Object.defineProperty;var z=(m,e,t)=>e in m?q(m,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):m[e]=t;var n=(m,e,t)=>(z(m,typeof e!="symbol"?e+"":e,t),t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class h{constructor(e){n(this,"x",0);n(this,"y",0);this.set(e)}static add(e,t){return new h({x:e.x+t.x,y:e.y+t.y})}static subtract(e,t){return new h({x:e.x-t.x,y:e.y-t.y})}set(e){if("d"in e){const{d:t,m:i}=e;this.x=Math.cos(t)*i,this.y=Math.sin(t)*i}else this.x=e.x,this.y=e.y;return this}add(e){return this.set({x:this.x+e.x,y:this.y+e.y})}subtract(e){return this.set({x:this.x-e.x,y:this.y-e.y})}multiply(e){return this.set({x:this.x*e,y:this.y*e})}dot(e){return this.x*e.x+this.y*e.y}set m(e){this.set({m:e,d:this.d})}set d(e){this.set({m:this.m,d:e})}get m(){return Math.sqrt(this.dot(this))}get d(){return Math.atan2(this.y,this.x)}}new h({x:0,y:0});class F extends h{constructor({x:t=0,y:i=0,v:o=new h({x:0,y:0}),size:p=1}){super({x:t,y:i});n(this,"v");n(this,"link");n(this,"size");this.v=o,this.size=p,this.link=new h({x:0,y:0})}update(){this.add(this.v)}}class v{constructor(){n(this,"dom");n(this,"ctx");this.dom=v.getTemplate().content.firstElementChild.cloneNode(!0),this.ctx=this.dom.getContext("2d")}static getTemplate(){const e=document.createElement("template");return e.innerHTML='<canvas width="" height=""></canvas>',e}updateSize({w:e,h:t}){this.dom.setAttribute("width",e+""),this.dom.setAttribute("height",t+"")}draw(e,t){const{x:i,y:o,particleNum:p,particleDistance:c,innerColor:l,outerColor:r}=t,a=new Path2D;e.forEach(([d,u])=>{a.quadraticCurveTo(d.x,d.y,u.x,u.y)}),a.closePath(),this.ctx.clearRect(0,0,this.dom.width,this.dom.height);const s=this.ctx.createRadialGradient(i,o,Math.random()*5,i,o,p*c*.5);s.addColorStop(0,l),s.addColorStop(1,r),this.ctx.save(),this.ctx.fillStyle=s,this.ctx.strokeStyle=s,this.ctx.fill(a),this.ctx.filter="blur(4px)",this.ctx.lineWidth=4,this.ctx.stroke(a),this.ctx.restore()}}class M{constructor(){n(this,"dom");n(this,"pathStroke");n(this,"pathFill");n(this,"gradient");n(this,"stopInner");n(this,"stopOuter");this.dom=M.getTemplate().content.firstElementChild.cloneNode(!0),this.pathStroke=this.dom.querySelector(".ff-stroke"),this.pathFill=this.dom.querySelector(".ff-fill"),this.gradient=this.dom.querySelector("#ff-gradient"),this.stopInner=this.dom.querySelector("#stop-inner"),this.stopOuter=this.dom.querySelector("#stop-outer")}static getTemplate(){const e=document.createElement("template");return e.innerHTML=` <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"> <defs> <radialGradient id="ff-gradient" fx="0" gradientTransform=""> <stop id="stop-inner" offset="10%" stop-color="blue" /> <stop id="stop-outer" offset="75%" stop-color="blueviolet" /> </radialGradient> </defs> <g fill="url('#ff-gradient')"> <path class="ff-fill" d="" /> </g> <g stroke="url('#ff-gradient')" stroke-width="4" fill="none" style="filter: blur(4px)" > <path class="ff-stroke" d="" /> </g> </svg> `,e}updateSize({w:e,h:t}){this.dom.setAttribute("width",e+""),this.dom.setAttribute("height",t+"")}draw(e,t){const{innerColor:i,outerColor:o,wind:p}=t;this.stopInner.setAttribute("stop-color",i),this.stopOuter.setAttribute("stop-color",o),console.log(p.d*180/Math.PI),this.gradient.setAttribute("gradientTransform",`rotate(${p.d*180/Math.PI} 0.5 0.5)`);const[c]=e,l=e.map(([a,s])=>`Q ${Math.ceil(a.x)},${Math.ceil(a.y)} ${Math.ceil(s.x)},${Math.ceil(s.y)}`).join(" "),r=`M ${c==null?void 0:c[0].x},${c==null?void 0:c[0].y} ${l} Z`;this.pathStroke.setAttribute("d",r),this.pathFill.setAttribute("d",r)}}const b=Math.PI*2,w=Math.PI*.5,S=(m,e)=>{let t=0,i=1e3/e,o=0;const p=s=>{if(s-t<i){o=requestAnimationFrame(p);return}t=s,m(),o=requestAnimationFrame(p)},c=()=>o!==0,l=s=>{i=1e3/s},r=()=>{cancelAnimationFrame(o),o=0},a=()=>{c()||(t=0,o=requestAnimationFrame(p))};return a(),{start:a,stop:r,setFPS:l,isRunning:c}},f=new h({x:0,y:0}),g=class extends h{constructor(t,i={}){super({x:i.x||0,y:i.y||0});n(this,"painter");n(this,"pIndex",1);n(this,"particles",new Map);n(this,"spawnAnimation");n(this,"renderAnimation");n(this,"spawn",()=>{const{particleNum:t}=this.option,i=new F({x:this.x,y:this.y,v:new h({m:Math.random()*2,d:Math.random()*b})});this.particles.set(this.pIndex,i),this.pIndex>t&&this.particles.delete(this.pIndex-t),this.pIndex++});n(this,"render",()=>{this.updateParticles();const t=this.getPath(),i={...this.option,x:this.x,y:this.y};this.painter.draw(t,i)});n(this,"onMove",t=>{this.set({x:t.offsetX,y:t.offsetY})});this.container=t,this.option=i;const o={...g.getDefaultOption(),...i};this.preparePainter(o.painterType),this.setOption(o)}static getDefaultOption(){return{x:0,y:0,mousemove:!0,w:400,h:400,fps:60,wind:new h({x:0,y:-.8}),friction:.98,particleNum:15,particleDistance:10,particleFPS:10,sizeCurveFn:(t,i)=>t>.7?Math.sqrt(1-t)*50:Math.pow(t-1,2)*-30+30,innerColor:"blue",outerColor:"blueviolet",painterType:"canvas"}}preparePainter(t){var i;this.painter=new g.painterMap[t],(i=this.container)==null||i.appendChild(this.painter.dom)}start(){var t,i;(t=this.spawnAnimation)==null||t.start(),(i=this.renderAnimation)==null||i.start()}stop(){var t,i;(t=this.spawnAnimation)==null||t.stop(),(i=this.renderAnimation)==null||i.stop()}setOption(t){var a,s,d,u;const{mousemove:i,fps:o,w:p,h:c,particleFPS:l,particleNum:r}=this.option;if(this.option={...this.option,...t},(this.option.w!==p||this.option.h!==c)&&this.painter.updateSize({w:this.option.w,h:this.option.h}),this.option.particleNum!==r&&(this.particles.clear(),this.pIndex=1),this.option.mousemove!==i){this.container.addEventListener;const x=this.option.mousemove?(a=this.container)==null?void 0:a.addEventListener:(s=this.container)==null?void 0:s.removeEventListener;x==null||x.call(this.container,"mousemove",this.onMove,!0)}this.option.particleFPS!==l&&((d=this.spawnAnimation)==null||d.stop(),this.spawnAnimation=S(this.spawn,this.option.particleFPS)),this.option.fps!==o&&((u=this.renderAnimation)==null||u.stop(),this.renderAnimation=S(this.render,this.option.fps))}updateParticles(){var r;const{wind:t,friction:i,sizeCurveFn:o,particleNum:p,particleDistance:c}=this.option;let l=0;for(const[a,s]of this.particles){const d=(r=this.particles.get(a+1))!=null?r:s;if(f.set({m:.1,d:b*Math.random()}),s.v.add(h.add(t,f)).multiply(i),s.size=o(l++/(p-1),s.size),s.update(),s.link=h.subtract(s,d),s.link.m>c){const u=s.x,x=s.y;s.link.m=c,s.set({x:d.x+s.link.x,y:d.y+s.link.y}),s.v.add(f.set({x:s.x-u,y:s.y-x}).multiply(.05))}}}getPath(){var p,c;const t=[],i=[],o=new Path2D;for(const[l,r]of this.particles){const a=(p=this.particles.get(l+1))!=null?p:r,s=(c=this.particles.get(l-1))!=null?c:r;if(a===r&&s===r){o.moveTo(r.x,r.y);continue}const d=r.link.d+w,u=a.link.d+w,x=s.link.d+w,k=h.subtract(s,f.set({m:s.size,d:x})),A=h.add(r,f.set({m:r.size,d})),P=h.subtract(r,f),C=h.add(a,f.set({m:a.size,d:u})),I=h.add(C,A).multiply(.5),T=h.add(k,P).multiply(.5);t.push([A,I]),i.unshift([P,T])}return[...t,...i]}destroy(){this.stop(),this.particles.clear()}};let y=g;n(y,"painterMap",{canvas:v,svg:M});exports.FireFlame=y;exports.Vector=h;