@cut-shade/baspark 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # BASpark
2
+
3
+ Blue Archive 风格粒子特效的 Web 移植版。零依赖,纯 Canvas 渲染。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install @cut-shade/baspark
9
+ ```
10
+
11
+ ## 使用
12
+
13
+ ### ESM (推荐)
14
+
15
+ ```typescript
16
+ import { BASpark } from '@cut-shade/baspark'
17
+
18
+ const spark = new BASpark(document.body, {
19
+ color: '45,175,255',
20
+ autoTrack: true,
21
+ })
22
+ ```
23
+
24
+ ### CDN
25
+
26
+ ```html
27
+ <script src="https://unpkg.com/@cut-shade/baspark/dist/index.global.js"></script>
28
+ <script>
29
+ new BASpark.BASpark('#app', { autoTrack: true })
30
+ </script>
31
+ ```
32
+
33
+ ## API
34
+
35
+ | 方法 | 说明 |
36
+ |------|------|
37
+ | `boom(x%, y%)` | 程序化触发点击 (百分比坐标) |
38
+ | `move(x%, y%)` | 拖尾移动 |
39
+ | `up()` | 释放 |
40
+ | `setColor(rgb)` | 设置颜色 `"45,175,255"` |
41
+ | `setScale(n)` | 整体缩放 0.5–3.0 |
42
+ | `setOpacity(n)` | 不透明度 0.1–1.0 |
43
+ | `setSpeed(trail, click?)` | 动画速度 0.2–3.0 |
44
+ | `setTrailWidth(n)` | 拖尾粗细 0.25–4.0 |
45
+ | `setSparkSize(n)` | 迸溅粒子大小 0.25–4.0 |
46
+ | `setClickScale(n)` | 点击波纹大小 0.25–4.0 |
47
+ | `setAlwaysTrail(bool)` | 常驻拖尾 |
48
+ | `updateOptions({...})` | 批量更新 |
49
+ | `destroy()` | 销毁实例 |
50
+
51
+ ## 选项
52
+
53
+ ```typescript
54
+ interface BASparkOptions {
55
+ color?: string // 默认 "45,175,255"
56
+ scale?: number // 默认 1.5
57
+ opacity?: number // 默认 1.0
58
+ trailSpeed?: number // 默认 1.0
59
+ clickSpeed?: number // 默认 1.0
60
+ trailWidth?: number // 默认 1.0
61
+ sparkSize?: number // 默认 1.0
62
+ clickScale?: number // 默认 1.0
63
+ alwaysTrail?: boolean
64
+ autoTrack?: boolean // 默认 true,自动监听鼠标事件
65
+ zIndex?: number // Canvas z-index
66
+ }
67
+ ```
68
+
69
+ ## 开发
70
+
71
+ ```bash
72
+ npm install
73
+ npm run build # 构建
74
+ npm run dev # 监听模式
75
+ ```
76
+
77
+ 打开 `demo/index.html` 预览效果。
78
+
79
+ ## 构建输出
80
+
81
+ | 文件 | 格式 |
82
+ |------|------|
83
+ | `dist/index.js` | ESM |
84
+ | `dist/index.cjs` | CommonJS |
85
+ | `dist/index.global.js` | IIFE (CDN) |
86
+ | `dist/index.d.ts` | TypeScript 声明 |
87
+
88
+ ## 许可证
89
+
90
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";var T=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var Z=(p,t)=>{for(var e in t)T(p,e,{get:t[e],enumerable:!0})},J=(p,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of j(t))!K.call(p,a)&&a!==e&&T(p,a,{get:()=>t[a],enumerable:!(i=q(t,a))||i.enumerable});return p};var Q=p=>J(T({},"__esModule",{value:!0}),p);var tt={};Z(tt,{BASpark:()=>R,MouseSpark:()=>w});module.exports=Q(tt);var P={rAddRate:26,maxLife:16},L={rsList:[0,.08,.1],rRoundRateList:[0,1,1.5,2],len:1.1*Math.PI,maxLife:23,segNum:10,minW:.4,maxW:3.3,lenStopAddPoint:.1,lenStartDimPoint:.4},A={rings:{rsList:[0,.03,.06],rRoundRateList:[0,1,1.5,2],len:1.1*Math.PI},sparksCount:4},O="45,175,255",D=1.5,F=1,C=1,U=2147483647,W=1e3/60,I=100;function B(p){let[t,e,i]=p.split(",").map(Number);return[Math.round((t+510)/3),Math.round((e+510)/3),Math.round((i+510)/3)]}function V(p,t){return Math.hypot(p.x-t.x,p.y-t.y)}var w=class{constructor(t,e={}){this.sparksPool=[];this.wavesPool=[];this.waves=[];this.sparks=[];this.trail=[];this.isDown=!1;this.lastPos=null;this.lastFrameTime=performance.now();this.dpr=1;this.cssWidth=1;this.cssHeight=1;this.previousDirtyRects=[];this.forceFullRedraw=!0;this.ringsStartColor=[250,252,252];this.animFrameId=0;this.inputMode="mouse";this.alwaysTrailEnabled=!1;this.effectiveAlwaysTrail=!1;this.color=e.color??O,this.scale=e.scale??D,this.opacity=e.opacity??F,this.trailSpeed=e.trailSpeed??C,this.clickSpeed=e.clickSpeed??C,this.trailWidth=e.trailWidth??1,this.sparkSize=e.sparkSize??1,this.clickScale=e.clickScale??1,this.maxTrail=e.maxTrail??16,this.alwaysTrailEnabled=e.alwaysTrail??!1,this.ringsEndColor=B(this.color),this.initCanvas(t),this.animFrameId=requestAnimationFrame(i=>this.animationLoops(i))}initCanvas(t){this.mainCanvas=t,this.mainCtx=t.getContext("2d"),this.bufferCanvas=document.createElement("canvas"),this.bufferCtx=this.bufferCanvas.getContext("2d"),this.resize()}resize(){let t=window.devicePixelRatio||1,e=Math.max(1,window.innerWidth),i=Math.max(1,window.innerHeight),a=Math.max(1,Math.floor(e*t)),s=Math.max(1,Math.floor(i*t));this.dpr=t,this.cssWidth=e,this.cssHeight=i,this.mainCanvas.width=a,this.mainCanvas.height=s,this.bufferCanvas.width=a,this.bufferCanvas.height=s,this.previousDirtyRects=[],this.forceFullRedraw=!0,this.bufferCtx.setTransform(t,0,0,t,0,0)}setInputContext(t,e){this.inputMode=t==="touch"?"touch":"mouse",this.alwaysTrailEnabled=!!e,this.effectiveAlwaysTrail=this.inputMode==="mouse"&&this.alwaysTrailEnabled}updateColor(t){this.color=t,this.ringsEndColor=B(t)}setTrailWidth(t){this.trailWidth=Math.max(.25,Math.min(4,Number(t)||1))}setSparkSize(t){this.sparkSize=Math.max(.25,Math.min(4,Number(t)||1))}setClickScale(t){this.clickScale=Math.max(.25,Math.min(4,Number(t)||1))}updateEffectSettings(t,e,i,a){this.scale=Math.max(.5,Math.min(3,Number(t)||D)),this.opacity=Math.max(.1,Math.min(1,Number(e)||F));let s=Number(i);Number.isFinite(s)||(s=C);let n=Number(a);Number.isFinite(n)||(n=s),this.trailSpeed=Math.max(.2,Math.min(3,s)),this.clickSpeed=Math.max(.2,Math.min(3,n))}handleDown(t,e){this.isDown=!0,this.lastPos={x:t,y:e},this.createEffects(t,e)}handleMove(t,e){if(!this.isDown&&!(this.inputMode==="mouse"&&this.alwaysTrailEnabled))return;let i=this.lastPos;if(!i){this.lastPos={x:t,y:e};return}if(V({x:t,y:e},i)>2&&(this.trail.push({x:t,y:e,life:1}),this.trail.length>this.maxTrail&&this.trail.shift(),Math.random()<.3)){let a=Math.random()*Math.PI*2,s=this.scale/1.5;this.sparks.push({x:t+Math.cos(a)*10*this.scale,y:e+Math.sin(a)*10*this.scale,vx:Math.cos(a)*1.3*s,vy:Math.sin(a)*1.3*s,rot:Math.random()*Math.PI*2,rs:.16,s:9*this.scale*this.sparkSize,a:.7,f:.95,fromClick:!1})}this.lastPos={x:t,y:e}}handleUp(){this.isDown=!1}alpha(t){return Math.max(0,Math.min(1,t*this.opacity))}createEffects(t,e){let i=A.rings,a=A.sparksCount,s;this.wavesPool.length>0?s=this.wavesPool.pop():s={ring:{segs:[]}},s.ring||(s.ring={segs:[]}),s.x=t,s.y=e,s.r=0,s.life=0,s.ring.ang=Math.random()*Math.PI*2,s.ring.rs=i.rsList[Math.floor(Math.random()*i.rsList.length)],s.ring.segs[0]={off:0,len:i.len,rRoundRate:i.rRoundRateList[Math.floor(Math.random()*i.rRoundRateList.length)]},s.ring.segs[1]={off:(Math.random()*3-1.5)*Math.PI,len:i.len,rRoundRate:i.rRoundRateList[Math.floor(Math.random()*i.rRoundRateList.length)]},this.waves.push(s);let n=this.scale/1.5;for(let r=0;r<a;r++){let l=Math.random()*Math.PI*2,c=(4.8+Math.random()*2)*n,h;this.sparksPool.length>0?h=this.sparksPool.pop():h={},h.x=t,h.y=e,h.vx=Math.cos(l)*c,h.vy=Math.sin(l)*c,h.rot=Math.random()*Math.PI*2,h.rs=(Math.random()-.5)*.28,h.s=(4+Math.random()*3)*this.scale*this.sparkSize,h.a=1,h.f=.9,h.fromClick=!0,this.sparks.push(h)}}clearBuffer(t){let e=this.bufferCtx;t?e.clearRect(t.x,t.y,t.w,t.h):e.clearRect(0,0,this.cssWidth,this.cssHeight)}clearBufferRects(t){if(!(!t||t.length===0))for(let e of t)this.clearBuffer(e)}updateTrail(t){let e=this.bufferCtx,i=this.trail.length,a;this.inputMode==="mouse"&&this.alwaysTrailEnabled?a=.085*t:a=(this.isDown?.085:.18)*t;let s=.42;for(let o=i-1;o>=0;o--){let u=this.trail[o],d=Math.max(1,i-1),b=1.25-.55*(i>1?o/d:1),M=a*b;M>s&&(M=s),u.life-=M,u.life<=0&&this.trail.splice(o,1)}let n=this.lastPos,r=n&&this.trail.length>0?this.trail.concat([{x:n.x,y:n.y,life:1}]):this.trail.slice();if(r.length<2)return;if(Math.hypot(r[r.length-1].x-r[r.length-2].x,r[r.length-1].y-r[r.length-2].y)<.75&&this.trail.length===1){let o=Math.max(0,this.trail[0].life);e.shadowColor="transparent";let u=(2.5+2*o)*(this.scale/1.5)*this.trailWidth;e.beginPath(),e.arc(r[0].x,r[0].y,u,0,Math.PI*2),e.fillStyle=`rgba(${this.color}, ${o*.85})`,e.fill();return}let c=r.length,h=c-1,g=8*(this.scale/1.5)*this.trailWidth,E=o=>o<.65?Math.pow(o/.65,.6):Math.pow((1-o)/.35,1.8),m=[],v=[];for(let o=0;o<c;o++){let u=o/h,d=Math.max(.25,g*E(u))/2,x,b;o===0?(x=r[1].x-r[0].x,b=r[1].y-r[0].y):o===h?(x=r[o].x-r[o-1].x,b=r[o].y-r[o-1].y):(x=r[o+1].x-r[o-1].x,b=r[o+1].y-r[o-1].y);let M=Math.hypot(x,b);M<.001&&(x=0,b=1,M=1);let y=-b/M,k=x/M;m.push({x:r[o].x+y*d,y:r[o].y+k*d}),v.push({x:r[o].x-y*d,y:r[o].y-k*d})}e.shadowColor=`rgba(${this.color}, 0.6)`,e.shadowBlur=3,e.shadowOffsetX=0,e.shadowOffsetY=0,e.beginPath(),e.moveTo(m[0].x,m[0].y);for(let o=1;o<c;o++)e.lineTo(m[o].x,m[o].y);for(let o=c-1;o>=0;o--)e.lineTo(v[o].x,v[o].y);e.closePath();let f=e.createLinearGradient(r[0].x,r[0].y,r[h].x,r[h].y);f.addColorStop(0,`rgba(${this.color}, 0)`),f.addColorStop(1,`rgba(${this.color}, 1)`),e.fillStyle=f,e.fill(),e.shadowColor="transparent"}strokeRingSegment(t,e,i,a,s,n,r){let l=this.bufferCtx;l.beginPath(),l.arc(t,e,i,a,s),l.lineWidth=n,l.strokeStyle=r,l.stroke()}updateWaves(t){let e=P,i=L,a=this.bufferCtx;for(let s=this.waves.length-1;s>=0;s--){let n=this.waves[s],r=Math.min(n.life/e.maxLife,1),l=Math.min(n.life/i.maxLife,1);{n.life+=t;let c=1-Math.pow(1-r,3);n.r=e.rAddRate*this.scale*this.clickScale*c;let h=Math.max(0,1-r);h>0&&(a.beginPath(),a.arc(n.x,n.y,n.r,0,Math.PI*2),a.fillStyle=`rgba(${this.color},${this.alpha(h)})`,a.fill())}{let c=u=>Math.min(2-Math.abs(4*(u-.5)),1),h=u=>Math.min(1.1-.3*u,1),g=n.ring;g.ang-=g.rs*t;let E=u=>{let d=Math.min(1.2*u,1);return[Math.round(this.ringsStartColor[0]*(1-d)+this.ringsEndColor[0]*d),Math.round(this.ringsStartColor[1]*(1-d)+this.ringsEndColor[1]*d),Math.round(this.ringsStartColor[2]*(1-d)+this.ringsEndColor[2]*d)]},m=0,v=0,f=0,o;for(let u=0;u<2;u++){o=g.segs[u];let d=g.ang+o.off;l<=i.lenStopAddPoint?(f=o.len*(l/i.lenStopAddPoint),v=d+o.len,m=v-f):l>i.lenStartDimPoint?(f=o.len*(1-(l-i.lenStartDimPoint)/(1-i.lenStartDimPoint)),m=d,v=m+f):(f=o.len,m=d,v=m+f);let x=Math.min(-.8*(l-.8)+1,1),[b,M,y]=E(l),k=h(l);for(let S=0;S<i.segNum;S++){let H=S/i.segNum,$=(S+1)/i.segNum,_=m+(v-m)*H,z=m+(v-m)*$;if(Math.abs(z-_)<.01)continue;let N=c(H),G=(i.minW*(1-N)+i.maxW*N)*x,X=`rgba(${b},${M},${y},${k})`,Y=n.r+o.rRoundRate*this.scale*this.clickScale;this.strokeRingSegment(n.x,n.y,Y,_,z,G,X)}}}l>=1&&r>=1&&(this.wavesPool.push(this.waves[s]),this.waves.splice(s,1))}}updateSparks(t,e){let i=this.bufferCtx;for(let a=this.sparks.length-1;a>=0;a--){let s=this.sparks[a],n=s.fromClick?t:e;if(s.x+=s.vx*n,s.y+=s.vy*n,s.vx*=Math.pow(s.f,n),s.vy*=Math.pow(s.f,n),s.rot+=s.rs*n,s.a-=.032*n,s.a<=0){this.sparksPool.push(this.sparks[a]),this.sparks.splice(a,1);continue}i.save(),i.translate(s.x,s.y),i.rotate(s.rot),i.beginPath(),i.moveTo(0,-s.s),i.lineTo(s.s*.6,s.s*.6),i.lineTo(-s.s*.6,s.s*.6),i.fillStyle=`rgba(255,255,255,${this.alpha(s.a)})`,i.fill(),i.restore()}}canvasRect(){return{x:0,y:0,w:this.cssWidth,h:this.cssHeight}}clipRect(t){if(!t)return null;let e=Math.max(0,Math.floor(t.x)),i=Math.max(0,Math.floor(t.y)),a=Math.min(this.cssWidth,Math.ceil(t.x+t.w)),s=Math.min(this.cssHeight,Math.ceil(t.y+t.h));return a<=e||s<=i?null:{x:e,y:i,w:a-e,h:s-i}}pointRect(t,e,i){return{x:t-i,y:e-i,w:i*2,h:i*2}}segmentRect(t,e,i){let a=Math.min(t.x,e.x)-i,s=Math.min(t.y,e.y)-i,n=Math.max(t.x,e.x)+i,r=Math.max(t.y,e.y)+i;return{x:a,y:s,w:n-a,h:r-s}}intersects(t,e){return t.x<=e.x+e.w&&t.x+t.w>=e.x&&t.y<=e.y+e.h&&t.y+t.h>=e.y}unionRect(t,e){let i=Math.min(t.x,e.x),a=Math.min(t.y,e.y),s=Math.max(t.x+t.w,e.x+e.w),n=Math.max(t.y+t.h,e.y+e.h);return{x:i,y:a,w:s-i,h:n-a}}mergeRects(t){let e=[];for(let i of t){let a=this.clipRect(i);if(a){for(let s=0;s<e.length;s++)this.intersects(e[s],a)&&(a=this.unionRect(e[s],a),e.splice(s,1),s=-1);e.push(a)}}return e}getEffectRects(){let t=[],e=18*this.scale*this.trailWidth+12,i=this.lastPos&&this.trail.length>0?this.trail.concat([{x:this.lastPos.x,y:this.lastPos.y,life:1}]):this.trail;if(i.length===1)t.push(this.pointRect(i[0].x,i[0].y,e));else for(let n=0;n<i.length-1;n++)t.push(this.segmentRect(i[n],i[n+1],e));let a=34*this.scale*this.clickScale+L.maxW+16;for(let n of this.waves){let r=Math.max(n.r||0,P.rAddRate*this.scale*this.clickScale)+a;t.push(this.pointRect(n.x,n.y,r))}let s=I/W;for(let n of this.sparks){let r=Math.hypot(n.vx||0,n.vy||0),l=n.fromClick?this.clickSpeed:this.trailSpeed,c=r*s*l,h=Math.max(n.s||0,9*this.scale*this.sparkSize)*2+c+12;t.push(this.pointRect(n.x,n.y,h))}return this.mergeRects(t)}getRenderRects(){return this.forceFullRedraw?[this.canvasRect()]:this.mergeRects(this.previousDirtyRects.concat(this.getEffectRects()))}clipToRects(t,e){t.beginPath();for(let i of e)t.rect(i.x,i.y,i.w,i.h);t.clip()}renderToMain(t){let{mainCtx:e,mainCanvas:i,bufferCanvas:a}=this;if(!t||t.length===0){e.clearRect(0,0,i.width,i.height),e.drawImage(a,0,0);return}let s=this.dpr||1;for(let n of t){let r=Math.max(0,Math.floor(n.x*s)),l=Math.max(0,Math.floor(n.y*s)),c=Math.min(i.width-r,Math.ceil(n.w*s)),h=Math.min(i.height-l,Math.ceil(n.h*s));c<=0||h<=0||(e.clearRect(r,l,c,h),e.drawImage(a,r,l,c,h,r,l,c,h))}}animationLoops(t){if(!(this.waves.length>0||this.sparks.length>0||this.trail.length>0)){this.lastFrameTime=t,this.previousDirtyRects.length>0&&(this.clearBufferRects(this.previousDirtyRects),this.renderToMain(this.previousDirtyRects),this.previousDirtyRects=[]),this.animFrameId=requestAnimationFrame(c=>this.animationLoops(c));return}let i=Math.min(t-this.lastFrameTime,I);this.lastFrameTime=t;let a=i/W,s=a*this.trailSpeed,n=a*this.clickSpeed,r=this.bufferCtx,l=this.getRenderRects();r.save(),this.clipToRects(r,l),r.globalCompositeOperation="lighter",this.clearBufferRects(l),this.updateTrail(s),this.updateWaves(n),this.updateSparks(n,s),r.globalCompositeOperation="source-over",r.restore(),this.renderToMain(l),this.previousDirtyRects=this.getEffectRects(),this.forceFullRedraw=!1,this.animFrameId=requestAnimationFrame(c=>this.animationLoops(c))}destroy(){cancelAnimationFrame(this.animFrameId),this.waves.length=0,this.sparks.length=0,this.trail.length=0,this.sparksPool.length=0,this.wavesPool.length=0,this.previousDirtyRects=[],this.mainCtx.clearRect(0,0,this.mainCanvas.width,this.mainCanvas.height)}};var R=class{constructor(t,e={}){this.autoTrack=e.autoTrack??!0;let i=typeof t=="string"?document.querySelector(t):t;if(!i)throw new Error("BASpark: target element not found");this.canvas=document.createElement("canvas"),this.canvas.id="baspark-canvas",this.canvas.style.cssText=`
2
+ position: fixed;
3
+ left: 0;
4
+ top: 0;
5
+ width: 100%;
6
+ height: 100%;
7
+ pointer-events: none;
8
+ z-index: ${e.zIndex??U};
9
+ `,i.appendChild(this.canvas),this.spark=new w(this.canvas,{color:e.color,scale:e.scale,opacity:e.opacity,trailSpeed:e.trailSpeed,clickSpeed:e.clickSpeed,trailWidth:e.trailWidth,sparkSize:e.sparkSize,clickScale:e.clickScale,alwaysTrail:e.alwaysTrail}),this.boundHandlers={mouseDown:a=>{this.spark.handleDown(a.clientX,a.clientY)},mouseMove:a=>{this.spark.handleMove(a.clientX,a.clientY)},mouseUp:()=>{this.spark.handleUp()},touchStart:a=>{let s=a.touches[0];this.spark.setInputContext("touch",!1),this.spark.handleDown(s.clientX,s.clientY)},touchMove:a=>{let s=a.touches[0];this.spark.handleMove(s.clientX,s.clientY)},touchEnd:()=>{this.spark.setInputContext("mouse",!1),this.spark.handleUp()},resize:()=>{this.spark.resize()}},this.autoTrack&&this.bindEvents()}bindEvents(){window.addEventListener("mousedown",this.boundHandlers.mouseDown),window.addEventListener("mousemove",this.boundHandlers.mouseMove),window.addEventListener("mouseup",this.boundHandlers.mouseUp),window.addEventListener("touchstart",this.boundHandlers.touchStart,{passive:!0}),window.addEventListener("touchmove",this.boundHandlers.touchMove,{passive:!0}),window.addEventListener("touchend",this.boundHandlers.touchEnd),window.addEventListener("resize",this.boundHandlers.resize)}unbindEvents(){window.removeEventListener("mousedown",this.boundHandlers.mouseDown),window.removeEventListener("mousemove",this.boundHandlers.mouseMove),window.removeEventListener("mouseup",this.boundHandlers.mouseUp),window.removeEventListener("touchstart",this.boundHandlers.touchStart),window.removeEventListener("touchmove",this.boundHandlers.touchMove),window.removeEventListener("touchend",this.boundHandlers.touchEnd),window.removeEventListener("resize",this.boundHandlers.resize)}boom(t,e){let i=t*window.innerWidth,a=e*window.innerHeight;this.spark.handleDown(i,a)}move(t,e){let i=t*window.innerWidth,a=e*window.innerHeight;this.spark.handleMove(i,a)}up(){this.spark.handleUp()}boomAt(t,e){this.spark.handleDown(t,e)}moveAt(t,e){this.spark.handleMove(t,e)}setColor(t){this.spark.updateColor(t)}setScale(t){let e=this.spark;e.updateEffectSettings(t,e.opacity,e.trailSpeed,e.clickSpeed)}setOpacity(t){let e=this.spark;e.updateEffectSettings(e.scale,t,e.trailSpeed,e.clickSpeed)}setSpeed(t,e){this.spark.updateEffectSettings(this.spark.scale,this.spark.opacity,t,e??t)}setAlwaysTrail(t){this.spark.setInputContext("mouse",t)}setTrailWidth(t){this.spark.setTrailWidth(t)}setSparkSize(t){this.spark.setSparkSize(t)}setClickScale(t){this.spark.setClickScale(t)}updateOptions(t){t.color!==void 0&&this.setColor(t.color),t.scale!==void 0&&this.setScale(t.scale),t.opacity!==void 0&&this.setOpacity(t.opacity),t.trailSpeed!==void 0&&this.setSpeed(t.trailSpeed,t.clickSpeed),t.trailWidth!==void 0&&this.setTrailWidth(t.trailWidth),t.sparkSize!==void 0&&this.setSparkSize(t.sparkSize),t.clickScale!==void 0&&this.setClickScale(t.clickScale),t.alwaysTrail!==void 0&&this.setAlwaysTrail(t.alwaysTrail),t.autoTrack!==void 0&&t.autoTrack!==this.autoTrack&&(this.autoTrack=t.autoTrack,this.autoTrack?this.bindEvents():this.unbindEvents())}destroy(){this.unbindEvents(),this.spark.destroy(),this.canvas.remove()}};0&&(module.exports={BASpark,MouseSpark});
10
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/constants.ts","../src/core/MouseSpark.ts","../src/BASpark.ts"],"sourcesContent":["export { BASpark } from './BASpark'\nexport { MouseSpark } from './core/MouseSpark'\nexport type { BASparkOptions, InputMode } from './core/types'\n","import type { FilledCircleConfig, RingsAnimConfig, CreateClickConfig } from './types'\n\nexport const FILLED_CIRCLE_CFG: FilledCircleConfig = {\n rAddRate: 26,\n maxLife: 16,\n}\n\nexport const RINGS_ANIM_CFG: RingsAnimConfig = {\n rsList: [0, 0.08, 0.1],\n rRoundRateList: [0, 1, 1.5, 2],\n len: 1.1 * Math.PI,\n maxLife: 23,\n segNum: 10,\n minW: 0.4,\n maxW: 3.3,\n lenStopAddPoint: 0.1,\n lenStartDimPoint: 0.4,\n}\n\nexport const CREATE_CLICK_CFG: CreateClickConfig = {\n rings: {\n rsList: [0, 0.03, 0.06],\n rRoundRateList: [0, 1, 1.5, 2],\n len: 1.1 * Math.PI,\n },\n sparksCount: 4,\n}\n\nexport const DEFAULT_COLOR = '45,175,255'\nexport const DEFAULT_SCALE = 1.5\nexport const DEFAULT_OPACITY = 1.0\nexport const DEFAULT_SPEED = 1.0\nexport const DEFAULT_Z_INDEX = 2147483647\nexport const BASE_FRAME_MS = 1000 / 60\nexport const MAX_DELTA_MS = 100\n","import type { Spark, Wave, TrailPoint, Point, Rect, InputMode } from './types'\nimport {\n FILLED_CIRCLE_CFG,\n RINGS_ANIM_CFG,\n CREATE_CLICK_CFG,\n DEFAULT_COLOR,\n DEFAULT_SCALE,\n DEFAULT_OPACITY,\n DEFAULT_SPEED,\n BASE_FRAME_MS,\n MAX_DELTA_MS,\n} from './constants'\n\nfunction ringsEndColorFromRgb(rgbString: string): [number, number, number] {\n const [r, g, b] = rgbString.split(',').map(Number)\n return [\n Math.round((r + 255 * 2) / 3),\n Math.round((g + 255 * 2) / 3),\n Math.round((b + 255 * 2) / 3),\n ]\n}\n\nfunction dist(a: Point, b: Point): number {\n return Math.hypot(a.x - b.x, a.y - b.y)\n}\n\nexport interface MouseSparkOptions {\n color?: string\n scale?: number\n opacity?: number\n trailSpeed?: number\n clickSpeed?: number\n trailWidth?: number\n sparkSize?: number\n clickScale?: number\n maxTrail?: number\n alwaysTrail?: boolean\n}\n\nexport class MouseSpark {\n color: string\n scale: number\n opacity: number\n trailSpeed: number\n clickSpeed: number\n trailWidth: number\n sparkSize: number\n clickScale: number\n maxTrail: number\n\n private sparksPool: Spark[] = []\n private wavesPool: Wave[] = []\n private waves: Wave[] = []\n private sparks: Spark[] = []\n private trail: TrailPoint[] = []\n isDown = false\n private lastPos: Point | null = null\n private lastFrameTime = performance.now()\n private dpr = 1\n private cssWidth = 1\n private cssHeight = 1\n private previousDirtyRects: Rect[] = []\n private forceFullRedraw = true\n\n private ringsStartColor: [number, number, number] = [250, 252, 252]\n private ringsEndColor: [number, number, number]\n\n private mainCanvas!: HTMLCanvasElement\n private mainCtx!: CanvasRenderingContext2D\n private bufferCanvas!: HTMLCanvasElement\n private bufferCtx!: CanvasRenderingContext2D\n\n private animFrameId = 0\n private inputMode: InputMode = 'mouse'\n private alwaysTrailEnabled = false\n readonly effectiveAlwaysTrail: boolean = false\n\n constructor(canvas: HTMLCanvasElement, opts: MouseSparkOptions = {}) {\n this.color = opts.color ?? DEFAULT_COLOR\n this.scale = opts.scale ?? DEFAULT_SCALE\n this.opacity = opts.opacity ?? DEFAULT_OPACITY\n this.trailSpeed = opts.trailSpeed ?? DEFAULT_SPEED\n this.clickSpeed = opts.clickSpeed ?? DEFAULT_SPEED\n this.trailWidth = opts.trailWidth ?? 1\n this.sparkSize = opts.sparkSize ?? 1\n this.clickScale = opts.clickScale ?? 1\n this.maxTrail = opts.maxTrail ?? 16\n this.alwaysTrailEnabled = opts.alwaysTrail ?? false\n\n this.ringsEndColor = ringsEndColorFromRgb(this.color)\n\n this.initCanvas(canvas)\n this.animFrameId = requestAnimationFrame((now) => this.animationLoops(now))\n }\n\n private initCanvas(canvas: HTMLCanvasElement): void {\n this.mainCanvas = canvas\n this.mainCtx = canvas.getContext('2d')!\n\n this.bufferCanvas = document.createElement('canvas')\n this.bufferCtx = this.bufferCanvas.getContext('2d')!\n\n this.resize()\n }\n\n resize(): void {\n const dpr = window.devicePixelRatio || 1\n const cssWidth = Math.max(1, window.innerWidth)\n const cssHeight = Math.max(1, window.innerHeight)\n const w = Math.max(1, Math.floor(cssWidth * dpr))\n const h = Math.max(1, Math.floor(cssHeight * dpr))\n\n this.dpr = dpr\n this.cssWidth = cssWidth\n this.cssHeight = cssHeight\n this.mainCanvas.width = w\n this.mainCanvas.height = h\n this.bufferCanvas.width = w\n this.bufferCanvas.height = h\n this.previousDirtyRects = []\n this.forceFullRedraw = true\n\n this.bufferCtx.setTransform(dpr, 0, 0, dpr, 0, 0)\n }\n\n setInputContext(mode: InputMode, alwaysTrail: boolean): void {\n this.inputMode = mode === 'touch' ? 'touch' : 'mouse'\n this.alwaysTrailEnabled = Boolean(alwaysTrail)\n ;(this as any).effectiveAlwaysTrail = this.inputMode === 'mouse' && this.alwaysTrailEnabled\n }\n\n updateColor(rgbString: string): void {\n this.color = rgbString\n this.ringsEndColor = ringsEndColorFromRgb(rgbString)\n }\n\n setTrailWidth(v: number): void {\n this.trailWidth = Math.max(0.25, Math.min(4, Number(v) || 1))\n }\n\n setSparkSize(v: number): void {\n this.sparkSize = Math.max(0.25, Math.min(4, Number(v) || 1))\n }\n\n setClickScale(v: number): void {\n this.clickScale = Math.max(0.25, Math.min(4, Number(v) || 1))\n }\n\n updateEffectSettings(scale: number, opacity: number, trailSpeed: number, clickSpeed: number): void {\n this.scale = Math.max(0.5, Math.min(3, Number(scale) || DEFAULT_SCALE))\n this.opacity = Math.max(0.1, Math.min(1, Number(opacity) || DEFAULT_OPACITY))\n let t = Number(trailSpeed)\n if (!Number.isFinite(t)) t = DEFAULT_SPEED\n let c = Number(clickSpeed)\n if (!Number.isFinite(c)) c = t\n this.trailSpeed = Math.max(0.2, Math.min(3, t))\n this.clickSpeed = Math.max(0.2, Math.min(3, c))\n }\n\n handleDown(x: number, y: number): void {\n this.isDown = true\n this.lastPos = { x, y }\n this.createEffects(x, y)\n }\n\n handleMove(x: number, y: number): void {\n if (!this.isDown && !(this.inputMode === 'mouse' && this.alwaysTrailEnabled)) return\n const prev = this.lastPos\n if (!prev) {\n this.lastPos = { x, y }\n return\n }\n if (dist({ x, y }, prev) > 2) {\n this.trail.push({ x, y, life: 1 })\n if (this.trail.length > this.maxTrail) this.trail.shift()\n\n if (Math.random() < 0.3) {\n const a = Math.random() * Math.PI * 2\n const speedAdjust = this.scale / 1.5\n this.sparks.push({\n x: x + Math.cos(a) * 10 * this.scale,\n y: y + Math.sin(a) * 10 * this.scale,\n vx: Math.cos(a) * 1.3 * speedAdjust,\n vy: Math.sin(a) * 1.3 * speedAdjust,\n rot: Math.random() * Math.PI * 2,\n rs: 0.16,\n s: 9 * this.scale * this.sparkSize,\n a: 0.7,\n f: 0.95,\n fromClick: false,\n })\n }\n }\n this.lastPos = { x, y }\n }\n\n handleUp(): void {\n this.isDown = false\n }\n\n private alpha(value: number): number {\n return Math.max(0, Math.min(1, value * this.opacity))\n }\n\n private createEffects(x: number, y: number): void {\n const rc = CREATE_CLICK_CFG.rings\n const sparksCount = CREATE_CLICK_CFG.sparksCount\n\n let wave: Wave\n if (this.wavesPool.length > 0) {\n wave = this.wavesPool.pop()!\n } else {\n wave = { ring: { segs: [] } } as unknown as Wave\n }\n if (!wave.ring) wave.ring = { segs: [] } as any\n\n wave.x = x\n wave.y = y\n wave.r = 0\n wave.life = 0\n wave.ring.ang = Math.random() * Math.PI * 2\n wave.ring.rs = rc.rsList[Math.floor(Math.random() * rc.rsList.length)]\n wave.ring.segs[0] = {\n off: 0,\n len: rc.len,\n rRoundRate: rc.rRoundRateList[Math.floor(Math.random() * rc.rRoundRateList.length)],\n }\n wave.ring.segs[1] = {\n off: (Math.random() * 3 - 1.5) * Math.PI,\n len: rc.len,\n rRoundRate: rc.rRoundRateList[Math.floor(Math.random() * rc.rRoundRateList.length)],\n }\n\n this.waves.push(wave)\n\n const speedAdjust = this.scale / 1.5\n for (let i = 0; i < sparksCount; i++) {\n const a = Math.random() * Math.PI * 2\n const speed = (4.8 + Math.random() * 2) * speedAdjust\n\n let spark: Spark\n if (this.sparksPool.length > 0) {\n spark = this.sparksPool.pop()!\n } else {\n spark = {} as Spark\n }\n\n spark.x = x\n spark.y = y\n spark.vx = Math.cos(a) * speed\n spark.vy = Math.sin(a) * speed\n spark.rot = Math.random() * Math.PI * 2\n spark.rs = (Math.random() - 0.5) * 0.28\n spark.s = (4 + Math.random() * 3) * this.scale * this.sparkSize\n spark.a = 1\n spark.f = 0.9\n spark.fromClick = true\n this.sparks.push(spark)\n }\n }\n\n private clearBuffer(rect?: Rect): void {\n const ctx = this.bufferCtx\n if (rect) {\n ctx.clearRect(rect.x, rect.y, rect.w, rect.h)\n } else {\n ctx.clearRect(0, 0, this.cssWidth, this.cssHeight)\n }\n }\n\n private clearBufferRects(rects: Rect[]): void {\n if (!rects || rects.length === 0) return\n for (const rect of rects) {\n this.clearBuffer(rect)\n }\n }\n\n private updateTrail(frameScale: number): void {\n const ctx = this.bufferCtx\n const n = this.trail.length\n let baseDecay: number\n if (this.inputMode === 'mouse' && this.alwaysTrailEnabled) {\n baseDecay = 0.085 * frameScale\n } else {\n baseDecay = (this.isDown ? 0.085 : 0.18) * frameScale\n }\n const maxStep = 0.42\n for (let i = n - 1; i >= 0; i--) {\n const t = this.trail[i]\n const span = Math.max(1, n - 1)\n const along = n > 1 ? i / span : 1\n const towardCursorBias = 1.25 - 0.55 * along\n let step = baseDecay * towardCursorBias\n if (step > maxStep) step = maxStep\n t.life -= step\n if (t.life <= 0) this.trail.splice(i, 1)\n }\n\n const head = this.lastPos\n const pts: TrailPoint[] =\n head && this.trail.length > 0\n ? this.trail.concat([{ x: head.x, y: head.y, life: 1 }])\n : this.trail.slice()\n\n if (pts.length < 2) return\n\n const gap = Math.hypot(\n pts[pts.length - 1].x - pts[pts.length - 2].x,\n pts[pts.length - 1].y - pts[pts.length - 2].y,\n )\n if (gap < 0.75 && this.trail.length === 1) {\n const fade = Math.max(0, this.trail[0].life)\n ctx.shadowColor = 'transparent'\n const dotSize = (2.5 + 2 * fade) * (this.scale / 1.5) * this.trailWidth\n ctx.beginPath()\n ctx.arc(pts[0].x, pts[0].y, dotSize, 0, Math.PI * 2)\n ctx.fillStyle = `rgba(${this.color}, ${fade * 0.85})`\n ctx.fill()\n return\n }\n\n const numPts = pts.length\n const lastIdx = numPts - 1\n const baseWidth = 8 * (this.scale / 1.5) * this.trailWidth\n\n const lancetWidth = (progress: number): number => {\n if (progress < 0.65) return Math.pow(progress / 0.65, 0.6)\n return Math.pow((1 - progress) / 0.35, 1.8)\n }\n\n // 构建填充多边形的左右边缘点\n const leftEdge: Array<{ x: number; y: number }> = []\n const rightEdge: Array<{ x: number; y: number }> = []\n\n for (let i = 0; i < numPts; i++) {\n const progress = i / lastIdx\n const hw = Math.max(0.25, baseWidth * lancetWidth(progress)) / 2\n\n let dx: number, dy: number\n if (i === 0) {\n dx = pts[1].x - pts[0].x\n dy = pts[1].y - pts[0].y\n } else if (i === lastIdx) {\n dx = pts[i].x - pts[i - 1].x\n dy = pts[i].y - pts[i - 1].y\n } else {\n dx = pts[i + 1].x - pts[i - 1].x\n dy = pts[i + 1].y - pts[i - 1].y\n }\n let len = Math.hypot(dx, dy)\n if (len < 0.001) {\n dx = 0\n dy = 1\n len = 1\n }\n const nx = -dy / len\n const ny = dx / len\n\n leftEdge.push({ x: pts[i].x + nx * hw, y: pts[i].y + ny * hw })\n rightEdge.push({ x: pts[i].x - nx * hw, y: pts[i].y - ny * hw })\n }\n\n // 绘制填充多边形\n ctx.shadowColor = `rgba(${this.color}, 0.6)`\n ctx.shadowBlur = 3\n ctx.shadowOffsetX = 0\n ctx.shadowOffsetY = 0\n\n ctx.beginPath()\n ctx.moveTo(leftEdge[0].x, leftEdge[0].y)\n for (let i = 1; i < numPts; i++) {\n ctx.lineTo(leftEdge[i].x, leftEdge[i].y)\n }\n for (let i = numPts - 1; i >= 0; i--) {\n ctx.lineTo(rightEdge[i].x, rightEdge[i].y)\n }\n ctx.closePath()\n\n const grad = ctx.createLinearGradient(\n pts[0].x, pts[0].y, pts[lastIdx].x, pts[lastIdx].y,\n )\n grad.addColorStop(0, `rgba(${this.color}, 0)`)\n grad.addColorStop(1, `rgba(${this.color}, 1)`)\n\n ctx.fillStyle = grad\n ctx.fill()\n\n ctx.shadowColor = 'transparent'\n }\n\n private strokeRingSegment(\n wx: number, wy: number, radius: number,\n a0: number, a1: number, lineWidth: number, strokeStyle: string,\n ): void {\n const ctx = this.bufferCtx\n ctx.beginPath()\n ctx.arc(wx, wy, radius, a0, a1)\n ctx.lineWidth = lineWidth\n ctx.strokeStyle = strokeStyle\n ctx.stroke()\n }\n\n private updateWaves(clickFrameScale: number): void {\n const filled = FILLED_CIRCLE_CFG\n const rings = RINGS_ANIM_CFG\n const ctx = this.bufferCtx\n\n for (let i = this.waves.length - 1; i >= 0; i--) {\n const w = this.waves[i]\n const waveProg = Math.min(w.life / filled.maxLife, 1)\n const ringProg = Math.min(w.life / rings.maxLife, 1)\n\n // filled circle\n {\n w.life += clickFrameScale\n const ease = 1 - Math.pow(1 - waveProg, 3)\n w.r = filled.rAddRate * this.scale * this.clickScale * ease\n const alpha = Math.max(0, 1 - waveProg)\n if (alpha > 0) {\n ctx.beginPath()\n ctx.arc(w.x, w.y, w.r, 0, Math.PI * 2)\n ctx.fillStyle = `rgba(${this.color},${this.alpha(alpha)})`\n ctx.fill()\n }\n }\n\n // rings\n {\n const getWeightProp = (t: number) => Math.min(2 - Math.abs(4 * (t - 0.5)), 1)\n\n const getAlpha = (rProg: number) => Math.min(1.1 - 0.3 * rProg, 1)\n\n const r = w.ring\n r.ang -= r.rs * clickFrameScale\n\n const ringRgbAt = (rProg: number): [number, number, number] => {\n const t = Math.min(1.2 * rProg, 1)\n return [\n Math.round(this.ringsStartColor[0] * (1 - t) + this.ringsEndColor[0] * t),\n Math.round(this.ringsStartColor[1] * (1 - t) + this.ringsEndColor[1] * t),\n Math.round(this.ringsStartColor[2] * (1 - t) + this.ringsEndColor[2] * t),\n ]\n }\n\n let start = 0\n let end = 0\n let len = 0\n let seg: { off: number; len: number; rRoundRate: number }\n\n for (let j = 0; j < 2; j++) {\n seg = r.segs[j]\n const base = r.ang + seg.off\n\n if (ringProg <= rings.lenStopAddPoint) {\n len = seg.len * (ringProg / rings.lenStopAddPoint)\n end = base + seg.len\n start = end - len\n } else if (ringProg > rings.lenStartDimPoint) {\n len = seg.len * (1 - (ringProg - rings.lenStartDimPoint) / (1 - rings.lenStartDimPoint))\n start = base\n end = start + len\n } else {\n len = seg.len\n start = base\n end = start + len\n }\n\n const lineWidthMul = Math.min(-0.8 * (ringProg - 0.8) + 1, 1)\n const [rr, gg, bb] = ringRgbAt(ringProg)\n const alphaRing = getAlpha(ringProg)\n\n for (let k = 0; k < rings.segNum; k++) {\n const t0 = k / rings.segNum\n const t1 = (k + 1) / rings.segNum\n const a0 = start + (end - start) * t0\n const a1 = start + (end - start) * t1\n\n if (Math.abs(a1 - a0) < 0.01) continue\n\n const wT = getWeightProp(t0)\n const lw = (rings.minW * (1 - wT) + rings.maxW * wT) * lineWidthMul\n const strokeStyle = `rgba(${rr},${gg},${bb},${alphaRing})`\n const radius = w.r + seg.rRoundRate * this.scale * this.clickScale\n this.strokeRingSegment(w.x, w.y, radius, a0, a1, lw, strokeStyle)\n }\n }\n }\n\n if (ringProg >= 1 && waveProg >= 1) {\n this.wavesPool.push(this.waves[i])\n this.waves.splice(i, 1)\n }\n }\n }\n\n private updateSparks(clickFrameScale: number, trailFrameScale: number): void {\n const ctx = this.bufferCtx\n for (let i = this.sparks.length - 1; i >= 0; i--) {\n const s = this.sparks[i]\n const fs = s.fromClick ? clickFrameScale : trailFrameScale\n s.x += s.vx * fs\n s.y += s.vy * fs\n s.vx *= Math.pow(s.f, fs)\n s.vy *= Math.pow(s.f, fs)\n s.rot += s.rs * fs\n s.a -= 0.032 * fs\n if (s.a <= 0) {\n this.sparksPool.push(this.sparks[i])\n this.sparks.splice(i, 1)\n continue\n }\n\n ctx.save()\n ctx.translate(s.x, s.y)\n ctx.rotate(s.rot)\n ctx.beginPath()\n ctx.moveTo(0, -s.s)\n ctx.lineTo(s.s * 0.6, s.s * 0.6)\n ctx.lineTo(-s.s * 0.6, s.s * 0.6)\n ctx.fillStyle = `rgba(255,255,255,${this.alpha(s.a)})`\n ctx.fill()\n ctx.restore()\n }\n }\n\n private canvasRect(): Rect {\n return { x: 0, y: 0, w: this.cssWidth, h: this.cssHeight }\n }\n\n private clipRect(rect: Rect): Rect | null {\n if (!rect) return null\n const x0 = Math.max(0, Math.floor(rect.x))\n const y0 = Math.max(0, Math.floor(rect.y))\n const x1 = Math.min(this.cssWidth, Math.ceil(rect.x + rect.w))\n const y1 = Math.min(this.cssHeight, Math.ceil(rect.y + rect.h))\n if (x1 <= x0 || y1 <= y0) return null\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n }\n\n private pointRect(x: number, y: number, padding: number): Rect {\n return { x: x - padding, y: y - padding, w: padding * 2, h: padding * 2 }\n }\n\n private segmentRect(a: Point, b: Point, padding: number): Rect {\n const x0 = Math.min(a.x, b.x) - padding\n const y0 = Math.min(a.y, b.y) - padding\n const x1 = Math.max(a.x, b.x) + padding\n const y1 = Math.max(a.y, b.y) + padding\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n }\n\n private intersects(a: Rect, b: Rect): boolean {\n return (\n a.x <= b.x + b.w &&\n a.x + a.w >= b.x &&\n a.y <= b.y + b.h &&\n a.y + a.h >= b.y\n )\n }\n\n private unionRect(a: Rect, b: Rect): Rect {\n const x0 = Math.min(a.x, b.x)\n const y0 = Math.min(a.y, b.y)\n const x1 = Math.max(a.x + a.w, b.x + b.w)\n const y1 = Math.max(a.y + a.h, b.y + b.h)\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n }\n\n private mergeRects(rects: Rect[]): Rect[] {\n const merged: Rect[] = []\n for (const raw of rects) {\n let rect = this.clipRect(raw)\n if (!rect) continue\n\n for (let i = 0; i < merged.length; i++) {\n if (this.intersects(merged[i], rect)) {\n rect = this.unionRect(merged[i], rect)\n merged.splice(i, 1)\n i = -1\n }\n }\n\n merged.push(rect)\n }\n return merged\n }\n\n private getEffectRects(): Rect[] {\n const rects: Rect[] = []\n const trailPad = 18 * this.scale * this.trailWidth + 12\n\n const trailPoints: TrailPoint[] =\n this.lastPos && this.trail.length > 0\n ? this.trail.concat([{ x: this.lastPos.x, y: this.lastPos.y, life: 1 }])\n : this.trail\n\n if (trailPoints.length === 1) {\n rects.push(this.pointRect(trailPoints[0].x, trailPoints[0].y, trailPad))\n } else {\n for (let i = 0; i < trailPoints.length - 1; i++) {\n rects.push(this.segmentRect(trailPoints[i], trailPoints[i + 1], trailPad))\n }\n }\n\n const wavePad = 34 * this.scale * this.clickScale + RINGS_ANIM_CFG.maxW + 16\n for (const wave of this.waves) {\n const radius = Math.max(wave.r || 0, FILLED_CIRCLE_CFG.rAddRate * this.scale * this.clickScale) + wavePad\n rects.push(this.pointRect(wave.x, wave.y, radius))\n }\n\n const maxFrameScale = MAX_DELTA_MS / BASE_FRAME_MS\n for (const spark of this.sparks) {\n const speed = Math.hypot(spark.vx || 0, spark.vy || 0)\n const speedScale = spark.fromClick ? this.clickSpeed : this.trailSpeed\n const motionPad = speed * maxFrameScale * speedScale\n const sparkPad = Math.max(spark.s || 0, 9 * this.scale * this.sparkSize) * 2 + motionPad + 12\n rects.push(this.pointRect(spark.x, spark.y, sparkPad))\n }\n\n return this.mergeRects(rects)\n }\n\n private getRenderRects(): Rect[] {\n if (this.forceFullRedraw) {\n return [this.canvasRect()]\n }\n return this.mergeRects(this.previousDirtyRects.concat(this.getEffectRects()))\n }\n\n private clipToRects(ctx: CanvasRenderingContext2D, rects: Rect[]): void {\n ctx.beginPath()\n for (const rect of rects) {\n ctx.rect(rect.x, rect.y, rect.w, rect.h)\n }\n ctx.clip()\n }\n\n private renderToMain(rects: Rect[]): void {\n const { mainCtx, mainCanvas, bufferCanvas } = this\n if (!rects || rects.length === 0) {\n mainCtx.clearRect(0, 0, mainCanvas.width, mainCanvas.height)\n mainCtx.drawImage(bufferCanvas, 0, 0)\n return\n }\n\n const dpr = this.dpr || 1\n for (const rect of rects) {\n const sx = Math.max(0, Math.floor(rect.x * dpr))\n const sy = Math.max(0, Math.floor(rect.y * dpr))\n const sw = Math.min(mainCanvas.width - sx, Math.ceil(rect.w * dpr))\n const sh = Math.min(mainCanvas.height - sy, Math.ceil(rect.h * dpr))\n if (sw <= 0 || sh <= 0) continue\n\n mainCtx.clearRect(sx, sy, sw, sh)\n mainCtx.drawImage(bufferCanvas, sx, sy, sw, sh, sx, sy, sw, sh)\n }\n }\n\n private animationLoops(now: number): void {\n const hasWork =\n this.waves.length > 0 ||\n this.sparks.length > 0 ||\n this.trail.length > 0\n\n if (!hasWork) {\n this.lastFrameTime = now\n if (this.previousDirtyRects.length > 0) {\n this.clearBufferRects(this.previousDirtyRects)\n this.renderToMain(this.previousDirtyRects)\n this.previousDirtyRects = []\n }\n this.animFrameId = requestAnimationFrame((nextNow) => this.animationLoops(nextNow))\n return\n }\n\n const deltaMs = Math.min(now - this.lastFrameTime, MAX_DELTA_MS)\n this.lastFrameTime = now\n const baseScale = deltaMs / BASE_FRAME_MS\n const trailFrameScale = baseScale * this.trailSpeed\n const clickFrameScale = baseScale * this.clickSpeed\n\n const bctx = this.bufferCtx\n const renderRects = this.getRenderRects()\n\n bctx.save()\n this.clipToRects(bctx, renderRects)\n bctx.globalCompositeOperation = 'lighter'\n\n this.clearBufferRects(renderRects)\n this.updateTrail(trailFrameScale)\n this.updateWaves(clickFrameScale)\n this.updateSparks(clickFrameScale, trailFrameScale)\n\n bctx.globalCompositeOperation = 'source-over'\n bctx.restore()\n\n this.renderToMain(renderRects)\n this.previousDirtyRects = this.getEffectRects()\n this.forceFullRedraw = false\n\n this.animFrameId = requestAnimationFrame((nextNow) => this.animationLoops(nextNow))\n }\n\n destroy(): void {\n cancelAnimationFrame(this.animFrameId)\n this.waves.length = 0\n this.sparks.length = 0\n this.trail.length = 0\n this.sparksPool.length = 0\n this.wavesPool.length = 0\n this.previousDirtyRects = []\n const ctx = this.mainCtx\n ctx.clearRect(0, 0, this.mainCanvas.width, this.mainCanvas.height)\n }\n}\n","import { MouseSpark } from './core/MouseSpark'\nimport type { BASparkOptions } from './core/types'\nimport { DEFAULT_Z_INDEX } from './core/constants'\n\nexport class BASpark {\n private canvas: HTMLCanvasElement\n private spark: MouseSpark\n private autoTrack: boolean\n private boundHandlers: {\n mouseDown: (e: MouseEvent) => void\n mouseMove: (e: MouseEvent) => void\n mouseUp: (e: MouseEvent) => void\n touchStart: (e: TouchEvent) => void\n touchMove: (e: TouchEvent) => void\n touchEnd: (e: TouchEvent) => void\n resize: () => void\n }\n\n constructor(element: HTMLElement | string, options: BASparkOptions = {}) {\n this.autoTrack = options.autoTrack ?? true\n\n const target = typeof element === 'string'\n ? document.querySelector<HTMLElement>(element)\n : element\n if (!target) throw new Error('BASpark: target element not found')\n\n this.canvas = document.createElement('canvas')\n this.canvas.id = 'baspark-canvas'\n this.canvas.style.cssText = `\n position: fixed;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: ${options.zIndex ?? DEFAULT_Z_INDEX};\n `\n target.appendChild(this.canvas)\n\n this.spark = new MouseSpark(this.canvas, {\n color: options.color,\n scale: options.scale,\n opacity: options.opacity,\n trailSpeed: options.trailSpeed,\n clickSpeed: options.clickSpeed,\n trailWidth: options.trailWidth,\n sparkSize: options.sparkSize,\n clickScale: options.clickScale,\n alwaysTrail: options.alwaysTrail,\n })\n\n this.boundHandlers = {\n mouseDown: (e: MouseEvent) => {\n this.spark.handleDown(e.clientX, e.clientY)\n },\n mouseMove: (e: MouseEvent) => {\n this.spark.handleMove(e.clientX, e.clientY)\n },\n mouseUp: () => {\n this.spark.handleUp()\n },\n touchStart: (e: TouchEvent) => {\n const t = e.touches[0]\n this.spark.setInputContext('touch', false)\n this.spark.handleDown(t.clientX, t.clientY)\n },\n touchMove: (e: TouchEvent) => {\n const t = e.touches[0]\n this.spark.handleMove(t.clientX, t.clientY)\n },\n touchEnd: () => {\n this.spark.setInputContext('mouse', false)\n this.spark.handleUp()\n },\n resize: () => {\n this.spark.resize()\n },\n }\n\n if (this.autoTrack) {\n this.bindEvents()\n }\n }\n\n private bindEvents(): void {\n window.addEventListener('mousedown', this.boundHandlers.mouseDown)\n window.addEventListener('mousemove', this.boundHandlers.mouseMove)\n window.addEventListener('mouseup', this.boundHandlers.mouseUp)\n window.addEventListener('touchstart', this.boundHandlers.touchStart, { passive: true })\n window.addEventListener('touchmove', this.boundHandlers.touchMove, { passive: true })\n window.addEventListener('touchend', this.boundHandlers.touchEnd)\n window.addEventListener('resize', this.boundHandlers.resize)\n }\n\n private unbindEvents(): void {\n window.removeEventListener('mousedown', this.boundHandlers.mouseDown)\n window.removeEventListener('mousemove', this.boundHandlers.mouseMove)\n window.removeEventListener('mouseup', this.boundHandlers.mouseUp)\n window.removeEventListener('touchstart', this.boundHandlers.touchStart)\n window.removeEventListener('touchmove', this.boundHandlers.touchMove)\n window.removeEventListener('touchend', this.boundHandlers.touchEnd)\n window.removeEventListener('resize', this.boundHandlers.resize)\n }\n\n boom(xPercent: number, yPercent: number): void {\n const cx = xPercent * window.innerWidth\n const cy = yPercent * window.innerHeight\n this.spark.handleDown(cx, cy)\n }\n\n move(xPercent: number, yPercent: number): void {\n const cx = xPercent * window.innerWidth\n const cy = yPercent * window.innerHeight\n this.spark.handleMove(cx, cy)\n }\n\n up(): void {\n this.spark.handleUp()\n }\n\n boomAt(x: number, y: number): void {\n this.spark.handleDown(x, y)\n }\n\n moveAt(x: number, y: number): void {\n this.spark.handleMove(x, y)\n }\n\n setColor(rgb: string): void {\n this.spark.updateColor(rgb)\n }\n\n setScale(scale: number): void {\n const s = this.spark\n s.updateEffectSettings(scale, s.opacity, s.trailSpeed, s.clickSpeed)\n }\n\n setOpacity(opacity: number): void {\n const s = this.spark\n s.updateEffectSettings(s.scale, opacity, s.trailSpeed, s.clickSpeed)\n }\n\n setSpeed(trailSpeed: number, clickSpeed?: number): void {\n this.spark.updateEffectSettings(\n this.spark.scale,\n this.spark.opacity,\n trailSpeed,\n clickSpeed ?? trailSpeed,\n )\n }\n\n setAlwaysTrail(enabled: boolean): void {\n this.spark.setInputContext('mouse', enabled)\n }\n\n setTrailWidth(v: number): void {\n this.spark.setTrailWidth(v)\n }\n\n setSparkSize(v: number): void {\n this.spark.setSparkSize(v)\n }\n\n setClickScale(v: number): void {\n this.spark.setClickScale(v)\n }\n\n updateOptions(options: BASparkOptions): void {\n if (options.color !== undefined) this.setColor(options.color)\n if (options.scale !== undefined) this.setScale(options.scale)\n if (options.opacity !== undefined) this.setOpacity(options.opacity)\n if (options.trailSpeed !== undefined) {\n this.setSpeed(options.trailSpeed, options.clickSpeed)\n }\n if (options.trailWidth !== undefined) this.setTrailWidth(options.trailWidth)\n if (options.sparkSize !== undefined) this.setSparkSize(options.sparkSize)\n if (options.clickScale !== undefined) this.setClickScale(options.clickScale)\n if (options.alwaysTrail !== undefined) this.setAlwaysTrail(options.alwaysTrail)\n if (options.autoTrack !== undefined && options.autoTrack !== this.autoTrack) {\n this.autoTrack = options.autoTrack\n if (this.autoTrack) {\n this.bindEvents()\n } else {\n this.unbindEvents()\n }\n }\n }\n\n destroy(): void {\n this.unbindEvents()\n this.spark.destroy()\n this.canvas.remove()\n }\n}\n"],"mappings":"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","names":["index_exports","__export","BASpark","MouseSpark","__toCommonJS","FILLED_CIRCLE_CFG","RINGS_ANIM_CFG","CREATE_CLICK_CFG","DEFAULT_COLOR","DEFAULT_SCALE","DEFAULT_OPACITY","DEFAULT_SPEED","DEFAULT_Z_INDEX","BASE_FRAME_MS","MAX_DELTA_MS","ringsEndColorFromRgb","rgbString","r","g","b","dist","a","MouseSpark","canvas","opts","DEFAULT_COLOR","DEFAULT_SCALE","DEFAULT_OPACITY","DEFAULT_SPEED","now","dpr","cssWidth","cssHeight","w","h","mode","alwaysTrail","v","scale","opacity","trailSpeed","clickSpeed","t","c","x","y","prev","speedAdjust","value","rc","CREATE_CLICK_CFG","sparksCount","wave","i","speed","spark","rect","ctx","rects","frameScale","n","baseDecay","maxStep","span","towardCursorBias","step","head","pts","fade","dotSize","numPts","lastIdx","baseWidth","lancetWidth","progress","leftEdge","rightEdge","hw","dx","dy","len","nx","ny","grad","wx","wy","radius","a0","a1","lineWidth","strokeStyle","clickFrameScale","filled","FILLED_CIRCLE_CFG","rings","RINGS_ANIM_CFG","waveProg","ringProg","ease","alpha","getWeightProp","getAlpha","rProg","ringRgbAt","start","end","seg","j","base","lineWidthMul","rr","gg","bb","alphaRing","k","t0","t1","wT","lw","trailFrameScale","fs","x0","y0","x1","y1","padding","merged","raw","trailPad","trailPoints","wavePad","maxFrameScale","MAX_DELTA_MS","BASE_FRAME_MS","speedScale","motionPad","sparkPad","mainCtx","mainCanvas","bufferCanvas","sx","sy","sw","sh","nextNow","deltaMs","baseScale","bctx","renderRects","BASpark","element","options","target","DEFAULT_Z_INDEX","MouseSpark","e","t","xPercent","yPercent","cx","cy","x","y","rgb","scale","s","opacity","trailSpeed","clickSpeed","enabled","v"]}
@@ -0,0 +1,121 @@
1
+ interface BASparkOptions {
2
+ color?: string;
3
+ scale?: number;
4
+ opacity?: number;
5
+ trailSpeed?: number;
6
+ clickSpeed?: number;
7
+ trailWidth?: number;
8
+ sparkSize?: number;
9
+ clickScale?: number;
10
+ alwaysTrail?: boolean;
11
+ autoTrack?: boolean;
12
+ zIndex?: number;
13
+ }
14
+ type InputMode = 'mouse' | 'touch';
15
+
16
+ declare class BASpark {
17
+ private canvas;
18
+ private spark;
19
+ private autoTrack;
20
+ private boundHandlers;
21
+ constructor(element: HTMLElement | string, options?: BASparkOptions);
22
+ private bindEvents;
23
+ private unbindEvents;
24
+ boom(xPercent: number, yPercent: number): void;
25
+ move(xPercent: number, yPercent: number): void;
26
+ up(): void;
27
+ boomAt(x: number, y: number): void;
28
+ moveAt(x: number, y: number): void;
29
+ setColor(rgb: string): void;
30
+ setScale(scale: number): void;
31
+ setOpacity(opacity: number): void;
32
+ setSpeed(trailSpeed: number, clickSpeed?: number): void;
33
+ setAlwaysTrail(enabled: boolean): void;
34
+ setTrailWidth(v: number): void;
35
+ setSparkSize(v: number): void;
36
+ setClickScale(v: number): void;
37
+ updateOptions(options: BASparkOptions): void;
38
+ destroy(): void;
39
+ }
40
+
41
+ interface MouseSparkOptions {
42
+ color?: string;
43
+ scale?: number;
44
+ opacity?: number;
45
+ trailSpeed?: number;
46
+ clickSpeed?: number;
47
+ trailWidth?: number;
48
+ sparkSize?: number;
49
+ clickScale?: number;
50
+ maxTrail?: number;
51
+ alwaysTrail?: boolean;
52
+ }
53
+ declare class MouseSpark {
54
+ color: string;
55
+ scale: number;
56
+ opacity: number;
57
+ trailSpeed: number;
58
+ clickSpeed: number;
59
+ trailWidth: number;
60
+ sparkSize: number;
61
+ clickScale: number;
62
+ maxTrail: number;
63
+ private sparksPool;
64
+ private wavesPool;
65
+ private waves;
66
+ private sparks;
67
+ private trail;
68
+ isDown: boolean;
69
+ private lastPos;
70
+ private lastFrameTime;
71
+ private dpr;
72
+ private cssWidth;
73
+ private cssHeight;
74
+ private previousDirtyRects;
75
+ private forceFullRedraw;
76
+ private ringsStartColor;
77
+ private ringsEndColor;
78
+ private mainCanvas;
79
+ private mainCtx;
80
+ private bufferCanvas;
81
+ private bufferCtx;
82
+ private animFrameId;
83
+ private inputMode;
84
+ private alwaysTrailEnabled;
85
+ readonly effectiveAlwaysTrail: boolean;
86
+ constructor(canvas: HTMLCanvasElement, opts?: MouseSparkOptions);
87
+ private initCanvas;
88
+ resize(): void;
89
+ setInputContext(mode: InputMode, alwaysTrail: boolean): void;
90
+ updateColor(rgbString: string): void;
91
+ setTrailWidth(v: number): void;
92
+ setSparkSize(v: number): void;
93
+ setClickScale(v: number): void;
94
+ updateEffectSettings(scale: number, opacity: number, trailSpeed: number, clickSpeed: number): void;
95
+ handleDown(x: number, y: number): void;
96
+ handleMove(x: number, y: number): void;
97
+ handleUp(): void;
98
+ private alpha;
99
+ private createEffects;
100
+ private clearBuffer;
101
+ private clearBufferRects;
102
+ private updateTrail;
103
+ private strokeRingSegment;
104
+ private updateWaves;
105
+ private updateSparks;
106
+ private canvasRect;
107
+ private clipRect;
108
+ private pointRect;
109
+ private segmentRect;
110
+ private intersects;
111
+ private unionRect;
112
+ private mergeRects;
113
+ private getEffectRects;
114
+ private getRenderRects;
115
+ private clipToRects;
116
+ private renderToMain;
117
+ private animationLoops;
118
+ destroy(): void;
119
+ }
120
+
121
+ export { BASpark, type BASparkOptions, type InputMode, MouseSpark };
@@ -0,0 +1,121 @@
1
+ interface BASparkOptions {
2
+ color?: string;
3
+ scale?: number;
4
+ opacity?: number;
5
+ trailSpeed?: number;
6
+ clickSpeed?: number;
7
+ trailWidth?: number;
8
+ sparkSize?: number;
9
+ clickScale?: number;
10
+ alwaysTrail?: boolean;
11
+ autoTrack?: boolean;
12
+ zIndex?: number;
13
+ }
14
+ type InputMode = 'mouse' | 'touch';
15
+
16
+ declare class BASpark {
17
+ private canvas;
18
+ private spark;
19
+ private autoTrack;
20
+ private boundHandlers;
21
+ constructor(element: HTMLElement | string, options?: BASparkOptions);
22
+ private bindEvents;
23
+ private unbindEvents;
24
+ boom(xPercent: number, yPercent: number): void;
25
+ move(xPercent: number, yPercent: number): void;
26
+ up(): void;
27
+ boomAt(x: number, y: number): void;
28
+ moveAt(x: number, y: number): void;
29
+ setColor(rgb: string): void;
30
+ setScale(scale: number): void;
31
+ setOpacity(opacity: number): void;
32
+ setSpeed(trailSpeed: number, clickSpeed?: number): void;
33
+ setAlwaysTrail(enabled: boolean): void;
34
+ setTrailWidth(v: number): void;
35
+ setSparkSize(v: number): void;
36
+ setClickScale(v: number): void;
37
+ updateOptions(options: BASparkOptions): void;
38
+ destroy(): void;
39
+ }
40
+
41
+ interface MouseSparkOptions {
42
+ color?: string;
43
+ scale?: number;
44
+ opacity?: number;
45
+ trailSpeed?: number;
46
+ clickSpeed?: number;
47
+ trailWidth?: number;
48
+ sparkSize?: number;
49
+ clickScale?: number;
50
+ maxTrail?: number;
51
+ alwaysTrail?: boolean;
52
+ }
53
+ declare class MouseSpark {
54
+ color: string;
55
+ scale: number;
56
+ opacity: number;
57
+ trailSpeed: number;
58
+ clickSpeed: number;
59
+ trailWidth: number;
60
+ sparkSize: number;
61
+ clickScale: number;
62
+ maxTrail: number;
63
+ private sparksPool;
64
+ private wavesPool;
65
+ private waves;
66
+ private sparks;
67
+ private trail;
68
+ isDown: boolean;
69
+ private lastPos;
70
+ private lastFrameTime;
71
+ private dpr;
72
+ private cssWidth;
73
+ private cssHeight;
74
+ private previousDirtyRects;
75
+ private forceFullRedraw;
76
+ private ringsStartColor;
77
+ private ringsEndColor;
78
+ private mainCanvas;
79
+ private mainCtx;
80
+ private bufferCanvas;
81
+ private bufferCtx;
82
+ private animFrameId;
83
+ private inputMode;
84
+ private alwaysTrailEnabled;
85
+ readonly effectiveAlwaysTrail: boolean;
86
+ constructor(canvas: HTMLCanvasElement, opts?: MouseSparkOptions);
87
+ private initCanvas;
88
+ resize(): void;
89
+ setInputContext(mode: InputMode, alwaysTrail: boolean): void;
90
+ updateColor(rgbString: string): void;
91
+ setTrailWidth(v: number): void;
92
+ setSparkSize(v: number): void;
93
+ setClickScale(v: number): void;
94
+ updateEffectSettings(scale: number, opacity: number, trailSpeed: number, clickSpeed: number): void;
95
+ handleDown(x: number, y: number): void;
96
+ handleMove(x: number, y: number): void;
97
+ handleUp(): void;
98
+ private alpha;
99
+ private createEffects;
100
+ private clearBuffer;
101
+ private clearBufferRects;
102
+ private updateTrail;
103
+ private strokeRingSegment;
104
+ private updateWaves;
105
+ private updateSparks;
106
+ private canvasRect;
107
+ private clipRect;
108
+ private pointRect;
109
+ private segmentRect;
110
+ private intersects;
111
+ private unionRect;
112
+ private mergeRects;
113
+ private getEffectRects;
114
+ private getRenderRects;
115
+ private clipToRects;
116
+ private renderToMain;
117
+ private animationLoops;
118
+ destroy(): void;
119
+ }
120
+
121
+ export { BASpark, type BASparkOptions, type InputMode, MouseSpark };
@@ -0,0 +1,10 @@
1
+ "use strict";var BASpark=(()=>{var T=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var Z=(p,t)=>{for(var e in t)T(p,e,{get:t[e],enumerable:!0})},J=(p,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of j(t))!K.call(p,a)&&a!==e&&T(p,a,{get:()=>t[a],enumerable:!(i=q(t,a))||i.enumerable});return p};var Q=p=>J(T({},"__esModule",{value:!0}),p);var tt={};Z(tt,{BASpark:()=>R,MouseSpark:()=>w});var P={rAddRate:26,maxLife:16},L={rsList:[0,.08,.1],rRoundRateList:[0,1,1.5,2],len:1.1*Math.PI,maxLife:23,segNum:10,minW:.4,maxW:3.3,lenStopAddPoint:.1,lenStartDimPoint:.4},A={rings:{rsList:[0,.03,.06],rRoundRateList:[0,1,1.5,2],len:1.1*Math.PI},sparksCount:4},O="45,175,255",D=1.5,F=1,C=1,U=2147483647,W=1e3/60,I=100;function B(p){let[t,e,i]=p.split(",").map(Number);return[Math.round((t+510)/3),Math.round((e+510)/3),Math.round((i+510)/3)]}function V(p,t){return Math.hypot(p.x-t.x,p.y-t.y)}var w=class{constructor(t,e={}){this.sparksPool=[];this.wavesPool=[];this.waves=[];this.sparks=[];this.trail=[];this.isDown=!1;this.lastPos=null;this.lastFrameTime=performance.now();this.dpr=1;this.cssWidth=1;this.cssHeight=1;this.previousDirtyRects=[];this.forceFullRedraw=!0;this.ringsStartColor=[250,252,252];this.animFrameId=0;this.inputMode="mouse";this.alwaysTrailEnabled=!1;this.effectiveAlwaysTrail=!1;this.color=e.color??O,this.scale=e.scale??D,this.opacity=e.opacity??F,this.trailSpeed=e.trailSpeed??C,this.clickSpeed=e.clickSpeed??C,this.trailWidth=e.trailWidth??1,this.sparkSize=e.sparkSize??1,this.clickScale=e.clickScale??1,this.maxTrail=e.maxTrail??16,this.alwaysTrailEnabled=e.alwaysTrail??!1,this.ringsEndColor=B(this.color),this.initCanvas(t),this.animFrameId=requestAnimationFrame(i=>this.animationLoops(i))}initCanvas(t){this.mainCanvas=t,this.mainCtx=t.getContext("2d"),this.bufferCanvas=document.createElement("canvas"),this.bufferCtx=this.bufferCanvas.getContext("2d"),this.resize()}resize(){let t=window.devicePixelRatio||1,e=Math.max(1,window.innerWidth),i=Math.max(1,window.innerHeight),a=Math.max(1,Math.floor(e*t)),s=Math.max(1,Math.floor(i*t));this.dpr=t,this.cssWidth=e,this.cssHeight=i,this.mainCanvas.width=a,this.mainCanvas.height=s,this.bufferCanvas.width=a,this.bufferCanvas.height=s,this.previousDirtyRects=[],this.forceFullRedraw=!0,this.bufferCtx.setTransform(t,0,0,t,0,0)}setInputContext(t,e){this.inputMode=t==="touch"?"touch":"mouse",this.alwaysTrailEnabled=!!e,this.effectiveAlwaysTrail=this.inputMode==="mouse"&&this.alwaysTrailEnabled}updateColor(t){this.color=t,this.ringsEndColor=B(t)}setTrailWidth(t){this.trailWidth=Math.max(.25,Math.min(4,Number(t)||1))}setSparkSize(t){this.sparkSize=Math.max(.25,Math.min(4,Number(t)||1))}setClickScale(t){this.clickScale=Math.max(.25,Math.min(4,Number(t)||1))}updateEffectSettings(t,e,i,a){this.scale=Math.max(.5,Math.min(3,Number(t)||D)),this.opacity=Math.max(.1,Math.min(1,Number(e)||F));let s=Number(i);Number.isFinite(s)||(s=C);let n=Number(a);Number.isFinite(n)||(n=s),this.trailSpeed=Math.max(.2,Math.min(3,s)),this.clickSpeed=Math.max(.2,Math.min(3,n))}handleDown(t,e){this.isDown=!0,this.lastPos={x:t,y:e},this.createEffects(t,e)}handleMove(t,e){if(!this.isDown&&!(this.inputMode==="mouse"&&this.alwaysTrailEnabled))return;let i=this.lastPos;if(!i){this.lastPos={x:t,y:e};return}if(V({x:t,y:e},i)>2&&(this.trail.push({x:t,y:e,life:1}),this.trail.length>this.maxTrail&&this.trail.shift(),Math.random()<.3)){let a=Math.random()*Math.PI*2,s=this.scale/1.5;this.sparks.push({x:t+Math.cos(a)*10*this.scale,y:e+Math.sin(a)*10*this.scale,vx:Math.cos(a)*1.3*s,vy:Math.sin(a)*1.3*s,rot:Math.random()*Math.PI*2,rs:.16,s:9*this.scale*this.sparkSize,a:.7,f:.95,fromClick:!1})}this.lastPos={x:t,y:e}}handleUp(){this.isDown=!1}alpha(t){return Math.max(0,Math.min(1,t*this.opacity))}createEffects(t,e){let i=A.rings,a=A.sparksCount,s;this.wavesPool.length>0?s=this.wavesPool.pop():s={ring:{segs:[]}},s.ring||(s.ring={segs:[]}),s.x=t,s.y=e,s.r=0,s.life=0,s.ring.ang=Math.random()*Math.PI*2,s.ring.rs=i.rsList[Math.floor(Math.random()*i.rsList.length)],s.ring.segs[0]={off:0,len:i.len,rRoundRate:i.rRoundRateList[Math.floor(Math.random()*i.rRoundRateList.length)]},s.ring.segs[1]={off:(Math.random()*3-1.5)*Math.PI,len:i.len,rRoundRate:i.rRoundRateList[Math.floor(Math.random()*i.rRoundRateList.length)]},this.waves.push(s);let n=this.scale/1.5;for(let r=0;r<a;r++){let l=Math.random()*Math.PI*2,c=(4.8+Math.random()*2)*n,h;this.sparksPool.length>0?h=this.sparksPool.pop():h={},h.x=t,h.y=e,h.vx=Math.cos(l)*c,h.vy=Math.sin(l)*c,h.rot=Math.random()*Math.PI*2,h.rs=(Math.random()-.5)*.28,h.s=(4+Math.random()*3)*this.scale*this.sparkSize,h.a=1,h.f=.9,h.fromClick=!0,this.sparks.push(h)}}clearBuffer(t){let e=this.bufferCtx;t?e.clearRect(t.x,t.y,t.w,t.h):e.clearRect(0,0,this.cssWidth,this.cssHeight)}clearBufferRects(t){if(!(!t||t.length===0))for(let e of t)this.clearBuffer(e)}updateTrail(t){let e=this.bufferCtx,i=this.trail.length,a;this.inputMode==="mouse"&&this.alwaysTrailEnabled?a=.085*t:a=(this.isDown?.085:.18)*t;let s=.42;for(let o=i-1;o>=0;o--){let u=this.trail[o],d=Math.max(1,i-1),b=1.25-.55*(i>1?o/d:1),M=a*b;M>s&&(M=s),u.life-=M,u.life<=0&&this.trail.splice(o,1)}let n=this.lastPos,r=n&&this.trail.length>0?this.trail.concat([{x:n.x,y:n.y,life:1}]):this.trail.slice();if(r.length<2)return;if(Math.hypot(r[r.length-1].x-r[r.length-2].x,r[r.length-1].y-r[r.length-2].y)<.75&&this.trail.length===1){let o=Math.max(0,this.trail[0].life);e.shadowColor="transparent";let u=(2.5+2*o)*(this.scale/1.5)*this.trailWidth;e.beginPath(),e.arc(r[0].x,r[0].y,u,0,Math.PI*2),e.fillStyle=`rgba(${this.color}, ${o*.85})`,e.fill();return}let c=r.length,h=c-1,g=8*(this.scale/1.5)*this.trailWidth,E=o=>o<.65?Math.pow(o/.65,.6):Math.pow((1-o)/.35,1.8),m=[],v=[];for(let o=0;o<c;o++){let u=o/h,d=Math.max(.25,g*E(u))/2,x,b;o===0?(x=r[1].x-r[0].x,b=r[1].y-r[0].y):o===h?(x=r[o].x-r[o-1].x,b=r[o].y-r[o-1].y):(x=r[o+1].x-r[o-1].x,b=r[o+1].y-r[o-1].y);let M=Math.hypot(x,b);M<.001&&(x=0,b=1,M=1);let y=-b/M,k=x/M;m.push({x:r[o].x+y*d,y:r[o].y+k*d}),v.push({x:r[o].x-y*d,y:r[o].y-k*d})}e.shadowColor=`rgba(${this.color}, 0.6)`,e.shadowBlur=3,e.shadowOffsetX=0,e.shadowOffsetY=0,e.beginPath(),e.moveTo(m[0].x,m[0].y);for(let o=1;o<c;o++)e.lineTo(m[o].x,m[o].y);for(let o=c-1;o>=0;o--)e.lineTo(v[o].x,v[o].y);e.closePath();let f=e.createLinearGradient(r[0].x,r[0].y,r[h].x,r[h].y);f.addColorStop(0,`rgba(${this.color}, 0)`),f.addColorStop(1,`rgba(${this.color}, 1)`),e.fillStyle=f,e.fill(),e.shadowColor="transparent"}strokeRingSegment(t,e,i,a,s,n,r){let l=this.bufferCtx;l.beginPath(),l.arc(t,e,i,a,s),l.lineWidth=n,l.strokeStyle=r,l.stroke()}updateWaves(t){let e=P,i=L,a=this.bufferCtx;for(let s=this.waves.length-1;s>=0;s--){let n=this.waves[s],r=Math.min(n.life/e.maxLife,1),l=Math.min(n.life/i.maxLife,1);{n.life+=t;let c=1-Math.pow(1-r,3);n.r=e.rAddRate*this.scale*this.clickScale*c;let h=Math.max(0,1-r);h>0&&(a.beginPath(),a.arc(n.x,n.y,n.r,0,Math.PI*2),a.fillStyle=`rgba(${this.color},${this.alpha(h)})`,a.fill())}{let c=u=>Math.min(2-Math.abs(4*(u-.5)),1),h=u=>Math.min(1.1-.3*u,1),g=n.ring;g.ang-=g.rs*t;let E=u=>{let d=Math.min(1.2*u,1);return[Math.round(this.ringsStartColor[0]*(1-d)+this.ringsEndColor[0]*d),Math.round(this.ringsStartColor[1]*(1-d)+this.ringsEndColor[1]*d),Math.round(this.ringsStartColor[2]*(1-d)+this.ringsEndColor[2]*d)]},m=0,v=0,f=0,o;for(let u=0;u<2;u++){o=g.segs[u];let d=g.ang+o.off;l<=i.lenStopAddPoint?(f=o.len*(l/i.lenStopAddPoint),v=d+o.len,m=v-f):l>i.lenStartDimPoint?(f=o.len*(1-(l-i.lenStartDimPoint)/(1-i.lenStartDimPoint)),m=d,v=m+f):(f=o.len,m=d,v=m+f);let x=Math.min(-.8*(l-.8)+1,1),[b,M,y]=E(l),k=h(l);for(let S=0;S<i.segNum;S++){let H=S/i.segNum,$=(S+1)/i.segNum,_=m+(v-m)*H,z=m+(v-m)*$;if(Math.abs(z-_)<.01)continue;let N=c(H),G=(i.minW*(1-N)+i.maxW*N)*x,X=`rgba(${b},${M},${y},${k})`,Y=n.r+o.rRoundRate*this.scale*this.clickScale;this.strokeRingSegment(n.x,n.y,Y,_,z,G,X)}}}l>=1&&r>=1&&(this.wavesPool.push(this.waves[s]),this.waves.splice(s,1))}}updateSparks(t,e){let i=this.bufferCtx;for(let a=this.sparks.length-1;a>=0;a--){let s=this.sparks[a],n=s.fromClick?t:e;if(s.x+=s.vx*n,s.y+=s.vy*n,s.vx*=Math.pow(s.f,n),s.vy*=Math.pow(s.f,n),s.rot+=s.rs*n,s.a-=.032*n,s.a<=0){this.sparksPool.push(this.sparks[a]),this.sparks.splice(a,1);continue}i.save(),i.translate(s.x,s.y),i.rotate(s.rot),i.beginPath(),i.moveTo(0,-s.s),i.lineTo(s.s*.6,s.s*.6),i.lineTo(-s.s*.6,s.s*.6),i.fillStyle=`rgba(255,255,255,${this.alpha(s.a)})`,i.fill(),i.restore()}}canvasRect(){return{x:0,y:0,w:this.cssWidth,h:this.cssHeight}}clipRect(t){if(!t)return null;let e=Math.max(0,Math.floor(t.x)),i=Math.max(0,Math.floor(t.y)),a=Math.min(this.cssWidth,Math.ceil(t.x+t.w)),s=Math.min(this.cssHeight,Math.ceil(t.y+t.h));return a<=e||s<=i?null:{x:e,y:i,w:a-e,h:s-i}}pointRect(t,e,i){return{x:t-i,y:e-i,w:i*2,h:i*2}}segmentRect(t,e,i){let a=Math.min(t.x,e.x)-i,s=Math.min(t.y,e.y)-i,n=Math.max(t.x,e.x)+i,r=Math.max(t.y,e.y)+i;return{x:a,y:s,w:n-a,h:r-s}}intersects(t,e){return t.x<=e.x+e.w&&t.x+t.w>=e.x&&t.y<=e.y+e.h&&t.y+t.h>=e.y}unionRect(t,e){let i=Math.min(t.x,e.x),a=Math.min(t.y,e.y),s=Math.max(t.x+t.w,e.x+e.w),n=Math.max(t.y+t.h,e.y+e.h);return{x:i,y:a,w:s-i,h:n-a}}mergeRects(t){let e=[];for(let i of t){let a=this.clipRect(i);if(a){for(let s=0;s<e.length;s++)this.intersects(e[s],a)&&(a=this.unionRect(e[s],a),e.splice(s,1),s=-1);e.push(a)}}return e}getEffectRects(){let t=[],e=18*this.scale*this.trailWidth+12,i=this.lastPos&&this.trail.length>0?this.trail.concat([{x:this.lastPos.x,y:this.lastPos.y,life:1}]):this.trail;if(i.length===1)t.push(this.pointRect(i[0].x,i[0].y,e));else for(let n=0;n<i.length-1;n++)t.push(this.segmentRect(i[n],i[n+1],e));let a=34*this.scale*this.clickScale+L.maxW+16;for(let n of this.waves){let r=Math.max(n.r||0,P.rAddRate*this.scale*this.clickScale)+a;t.push(this.pointRect(n.x,n.y,r))}let s=I/W;for(let n of this.sparks){let r=Math.hypot(n.vx||0,n.vy||0),l=n.fromClick?this.clickSpeed:this.trailSpeed,c=r*s*l,h=Math.max(n.s||0,9*this.scale*this.sparkSize)*2+c+12;t.push(this.pointRect(n.x,n.y,h))}return this.mergeRects(t)}getRenderRects(){return this.forceFullRedraw?[this.canvasRect()]:this.mergeRects(this.previousDirtyRects.concat(this.getEffectRects()))}clipToRects(t,e){t.beginPath();for(let i of e)t.rect(i.x,i.y,i.w,i.h);t.clip()}renderToMain(t){let{mainCtx:e,mainCanvas:i,bufferCanvas:a}=this;if(!t||t.length===0){e.clearRect(0,0,i.width,i.height),e.drawImage(a,0,0);return}let s=this.dpr||1;for(let n of t){let r=Math.max(0,Math.floor(n.x*s)),l=Math.max(0,Math.floor(n.y*s)),c=Math.min(i.width-r,Math.ceil(n.w*s)),h=Math.min(i.height-l,Math.ceil(n.h*s));c<=0||h<=0||(e.clearRect(r,l,c,h),e.drawImage(a,r,l,c,h,r,l,c,h))}}animationLoops(t){if(!(this.waves.length>0||this.sparks.length>0||this.trail.length>0)){this.lastFrameTime=t,this.previousDirtyRects.length>0&&(this.clearBufferRects(this.previousDirtyRects),this.renderToMain(this.previousDirtyRects),this.previousDirtyRects=[]),this.animFrameId=requestAnimationFrame(c=>this.animationLoops(c));return}let i=Math.min(t-this.lastFrameTime,I);this.lastFrameTime=t;let a=i/W,s=a*this.trailSpeed,n=a*this.clickSpeed,r=this.bufferCtx,l=this.getRenderRects();r.save(),this.clipToRects(r,l),r.globalCompositeOperation="lighter",this.clearBufferRects(l),this.updateTrail(s),this.updateWaves(n),this.updateSparks(n,s),r.globalCompositeOperation="source-over",r.restore(),this.renderToMain(l),this.previousDirtyRects=this.getEffectRects(),this.forceFullRedraw=!1,this.animFrameId=requestAnimationFrame(c=>this.animationLoops(c))}destroy(){cancelAnimationFrame(this.animFrameId),this.waves.length=0,this.sparks.length=0,this.trail.length=0,this.sparksPool.length=0,this.wavesPool.length=0,this.previousDirtyRects=[],this.mainCtx.clearRect(0,0,this.mainCanvas.width,this.mainCanvas.height)}};var R=class{constructor(t,e={}){this.autoTrack=e.autoTrack??!0;let i=typeof t=="string"?document.querySelector(t):t;if(!i)throw new Error("BASpark: target element not found");this.canvas=document.createElement("canvas"),this.canvas.id="baspark-canvas",this.canvas.style.cssText=`
2
+ position: fixed;
3
+ left: 0;
4
+ top: 0;
5
+ width: 100%;
6
+ height: 100%;
7
+ pointer-events: none;
8
+ z-index: ${e.zIndex??U};
9
+ `,i.appendChild(this.canvas),this.spark=new w(this.canvas,{color:e.color,scale:e.scale,opacity:e.opacity,trailSpeed:e.trailSpeed,clickSpeed:e.clickSpeed,trailWidth:e.trailWidth,sparkSize:e.sparkSize,clickScale:e.clickScale,alwaysTrail:e.alwaysTrail}),this.boundHandlers={mouseDown:a=>{this.spark.handleDown(a.clientX,a.clientY)},mouseMove:a=>{this.spark.handleMove(a.clientX,a.clientY)},mouseUp:()=>{this.spark.handleUp()},touchStart:a=>{let s=a.touches[0];this.spark.setInputContext("touch",!1),this.spark.handleDown(s.clientX,s.clientY)},touchMove:a=>{let s=a.touches[0];this.spark.handleMove(s.clientX,s.clientY)},touchEnd:()=>{this.spark.setInputContext("mouse",!1),this.spark.handleUp()},resize:()=>{this.spark.resize()}},this.autoTrack&&this.bindEvents()}bindEvents(){window.addEventListener("mousedown",this.boundHandlers.mouseDown),window.addEventListener("mousemove",this.boundHandlers.mouseMove),window.addEventListener("mouseup",this.boundHandlers.mouseUp),window.addEventListener("touchstart",this.boundHandlers.touchStart,{passive:!0}),window.addEventListener("touchmove",this.boundHandlers.touchMove,{passive:!0}),window.addEventListener("touchend",this.boundHandlers.touchEnd),window.addEventListener("resize",this.boundHandlers.resize)}unbindEvents(){window.removeEventListener("mousedown",this.boundHandlers.mouseDown),window.removeEventListener("mousemove",this.boundHandlers.mouseMove),window.removeEventListener("mouseup",this.boundHandlers.mouseUp),window.removeEventListener("touchstart",this.boundHandlers.touchStart),window.removeEventListener("touchmove",this.boundHandlers.touchMove),window.removeEventListener("touchend",this.boundHandlers.touchEnd),window.removeEventListener("resize",this.boundHandlers.resize)}boom(t,e){let i=t*window.innerWidth,a=e*window.innerHeight;this.spark.handleDown(i,a)}move(t,e){let i=t*window.innerWidth,a=e*window.innerHeight;this.spark.handleMove(i,a)}up(){this.spark.handleUp()}boomAt(t,e){this.spark.handleDown(t,e)}moveAt(t,e){this.spark.handleMove(t,e)}setColor(t){this.spark.updateColor(t)}setScale(t){let e=this.spark;e.updateEffectSettings(t,e.opacity,e.trailSpeed,e.clickSpeed)}setOpacity(t){let e=this.spark;e.updateEffectSettings(e.scale,t,e.trailSpeed,e.clickSpeed)}setSpeed(t,e){this.spark.updateEffectSettings(this.spark.scale,this.spark.opacity,t,e??t)}setAlwaysTrail(t){this.spark.setInputContext("mouse",t)}setTrailWidth(t){this.spark.setTrailWidth(t)}setSparkSize(t){this.spark.setSparkSize(t)}setClickScale(t){this.spark.setClickScale(t)}updateOptions(t){t.color!==void 0&&this.setColor(t.color),t.scale!==void 0&&this.setScale(t.scale),t.opacity!==void 0&&this.setOpacity(t.opacity),t.trailSpeed!==void 0&&this.setSpeed(t.trailSpeed,t.clickSpeed),t.trailWidth!==void 0&&this.setTrailWidth(t.trailWidth),t.sparkSize!==void 0&&this.setSparkSize(t.sparkSize),t.clickScale!==void 0&&this.setClickScale(t.clickScale),t.alwaysTrail!==void 0&&this.setAlwaysTrail(t.alwaysTrail),t.autoTrack!==void 0&&t.autoTrack!==this.autoTrack&&(this.autoTrack=t.autoTrack,this.autoTrack?this.bindEvents():this.unbindEvents())}destroy(){this.unbindEvents(),this.spark.destroy(),this.canvas.remove()}};return Q(tt);})();
10
+ //# sourceMappingURL=index.global.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/constants.ts","../src/core/MouseSpark.ts","../src/BASpark.ts"],"sourcesContent":["export { BASpark } from './BASpark'\nexport { MouseSpark } from './core/MouseSpark'\nexport type { BASparkOptions, InputMode } from './core/types'\n","import type { FilledCircleConfig, RingsAnimConfig, CreateClickConfig } from './types'\n\nexport const FILLED_CIRCLE_CFG: FilledCircleConfig = {\n rAddRate: 26,\n maxLife: 16,\n}\n\nexport const RINGS_ANIM_CFG: RingsAnimConfig = {\n rsList: [0, 0.08, 0.1],\n rRoundRateList: [0, 1, 1.5, 2],\n len: 1.1 * Math.PI,\n maxLife: 23,\n segNum: 10,\n minW: 0.4,\n maxW: 3.3,\n lenStopAddPoint: 0.1,\n lenStartDimPoint: 0.4,\n}\n\nexport const CREATE_CLICK_CFG: CreateClickConfig = {\n rings: {\n rsList: [0, 0.03, 0.06],\n rRoundRateList: [0, 1, 1.5, 2],\n len: 1.1 * Math.PI,\n },\n sparksCount: 4,\n}\n\nexport const DEFAULT_COLOR = '45,175,255'\nexport const DEFAULT_SCALE = 1.5\nexport const DEFAULT_OPACITY = 1.0\nexport const DEFAULT_SPEED = 1.0\nexport const DEFAULT_Z_INDEX = 2147483647\nexport const BASE_FRAME_MS = 1000 / 60\nexport const MAX_DELTA_MS = 100\n","import type { Spark, Wave, TrailPoint, Point, Rect, InputMode } from './types'\nimport {\n FILLED_CIRCLE_CFG,\n RINGS_ANIM_CFG,\n CREATE_CLICK_CFG,\n DEFAULT_COLOR,\n DEFAULT_SCALE,\n DEFAULT_OPACITY,\n DEFAULT_SPEED,\n BASE_FRAME_MS,\n MAX_DELTA_MS,\n} from './constants'\n\nfunction ringsEndColorFromRgb(rgbString: string): [number, number, number] {\n const [r, g, b] = rgbString.split(',').map(Number)\n return [\n Math.round((r + 255 * 2) / 3),\n Math.round((g + 255 * 2) / 3),\n Math.round((b + 255 * 2) / 3),\n ]\n}\n\nfunction dist(a: Point, b: Point): number {\n return Math.hypot(a.x - b.x, a.y - b.y)\n}\n\nexport interface MouseSparkOptions {\n color?: string\n scale?: number\n opacity?: number\n trailSpeed?: number\n clickSpeed?: number\n trailWidth?: number\n sparkSize?: number\n clickScale?: number\n maxTrail?: number\n alwaysTrail?: boolean\n}\n\nexport class MouseSpark {\n color: string\n scale: number\n opacity: number\n trailSpeed: number\n clickSpeed: number\n trailWidth: number\n sparkSize: number\n clickScale: number\n maxTrail: number\n\n private sparksPool: Spark[] = []\n private wavesPool: Wave[] = []\n private waves: Wave[] = []\n private sparks: Spark[] = []\n private trail: TrailPoint[] = []\n isDown = false\n private lastPos: Point | null = null\n private lastFrameTime = performance.now()\n private dpr = 1\n private cssWidth = 1\n private cssHeight = 1\n private previousDirtyRects: Rect[] = []\n private forceFullRedraw = true\n\n private ringsStartColor: [number, number, number] = [250, 252, 252]\n private ringsEndColor: [number, number, number]\n\n private mainCanvas!: HTMLCanvasElement\n private mainCtx!: CanvasRenderingContext2D\n private bufferCanvas!: HTMLCanvasElement\n private bufferCtx!: CanvasRenderingContext2D\n\n private animFrameId = 0\n private inputMode: InputMode = 'mouse'\n private alwaysTrailEnabled = false\n readonly effectiveAlwaysTrail: boolean = false\n\n constructor(canvas: HTMLCanvasElement, opts: MouseSparkOptions = {}) {\n this.color = opts.color ?? DEFAULT_COLOR\n this.scale = opts.scale ?? DEFAULT_SCALE\n this.opacity = opts.opacity ?? DEFAULT_OPACITY\n this.trailSpeed = opts.trailSpeed ?? DEFAULT_SPEED\n this.clickSpeed = opts.clickSpeed ?? DEFAULT_SPEED\n this.trailWidth = opts.trailWidth ?? 1\n this.sparkSize = opts.sparkSize ?? 1\n this.clickScale = opts.clickScale ?? 1\n this.maxTrail = opts.maxTrail ?? 16\n this.alwaysTrailEnabled = opts.alwaysTrail ?? false\n\n this.ringsEndColor = ringsEndColorFromRgb(this.color)\n\n this.initCanvas(canvas)\n this.animFrameId = requestAnimationFrame((now) => this.animationLoops(now))\n }\n\n private initCanvas(canvas: HTMLCanvasElement): void {\n this.mainCanvas = canvas\n this.mainCtx = canvas.getContext('2d')!\n\n this.bufferCanvas = document.createElement('canvas')\n this.bufferCtx = this.bufferCanvas.getContext('2d')!\n\n this.resize()\n }\n\n resize(): void {\n const dpr = window.devicePixelRatio || 1\n const cssWidth = Math.max(1, window.innerWidth)\n const cssHeight = Math.max(1, window.innerHeight)\n const w = Math.max(1, Math.floor(cssWidth * dpr))\n const h = Math.max(1, Math.floor(cssHeight * dpr))\n\n this.dpr = dpr\n this.cssWidth = cssWidth\n this.cssHeight = cssHeight\n this.mainCanvas.width = w\n this.mainCanvas.height = h\n this.bufferCanvas.width = w\n this.bufferCanvas.height = h\n this.previousDirtyRects = []\n this.forceFullRedraw = true\n\n this.bufferCtx.setTransform(dpr, 0, 0, dpr, 0, 0)\n }\n\n setInputContext(mode: InputMode, alwaysTrail: boolean): void {\n this.inputMode = mode === 'touch' ? 'touch' : 'mouse'\n this.alwaysTrailEnabled = Boolean(alwaysTrail)\n ;(this as any).effectiveAlwaysTrail = this.inputMode === 'mouse' && this.alwaysTrailEnabled\n }\n\n updateColor(rgbString: string): void {\n this.color = rgbString\n this.ringsEndColor = ringsEndColorFromRgb(rgbString)\n }\n\n setTrailWidth(v: number): void {\n this.trailWidth = Math.max(0.25, Math.min(4, Number(v) || 1))\n }\n\n setSparkSize(v: number): void {\n this.sparkSize = Math.max(0.25, Math.min(4, Number(v) || 1))\n }\n\n setClickScale(v: number): void {\n this.clickScale = Math.max(0.25, Math.min(4, Number(v) || 1))\n }\n\n updateEffectSettings(scale: number, opacity: number, trailSpeed: number, clickSpeed: number): void {\n this.scale = Math.max(0.5, Math.min(3, Number(scale) || DEFAULT_SCALE))\n this.opacity = Math.max(0.1, Math.min(1, Number(opacity) || DEFAULT_OPACITY))\n let t = Number(trailSpeed)\n if (!Number.isFinite(t)) t = DEFAULT_SPEED\n let c = Number(clickSpeed)\n if (!Number.isFinite(c)) c = t\n this.trailSpeed = Math.max(0.2, Math.min(3, t))\n this.clickSpeed = Math.max(0.2, Math.min(3, c))\n }\n\n handleDown(x: number, y: number): void {\n this.isDown = true\n this.lastPos = { x, y }\n this.createEffects(x, y)\n }\n\n handleMove(x: number, y: number): void {\n if (!this.isDown && !(this.inputMode === 'mouse' && this.alwaysTrailEnabled)) return\n const prev = this.lastPos\n if (!prev) {\n this.lastPos = { x, y }\n return\n }\n if (dist({ x, y }, prev) > 2) {\n this.trail.push({ x, y, life: 1 })\n if (this.trail.length > this.maxTrail) this.trail.shift()\n\n if (Math.random() < 0.3) {\n const a = Math.random() * Math.PI * 2\n const speedAdjust = this.scale / 1.5\n this.sparks.push({\n x: x + Math.cos(a) * 10 * this.scale,\n y: y + Math.sin(a) * 10 * this.scale,\n vx: Math.cos(a) * 1.3 * speedAdjust,\n vy: Math.sin(a) * 1.3 * speedAdjust,\n rot: Math.random() * Math.PI * 2,\n rs: 0.16,\n s: 9 * this.scale * this.sparkSize,\n a: 0.7,\n f: 0.95,\n fromClick: false,\n })\n }\n }\n this.lastPos = { x, y }\n }\n\n handleUp(): void {\n this.isDown = false\n }\n\n private alpha(value: number): number {\n return Math.max(0, Math.min(1, value * this.opacity))\n }\n\n private createEffects(x: number, y: number): void {\n const rc = CREATE_CLICK_CFG.rings\n const sparksCount = CREATE_CLICK_CFG.sparksCount\n\n let wave: Wave\n if (this.wavesPool.length > 0) {\n wave = this.wavesPool.pop()!\n } else {\n wave = { ring: { segs: [] } } as unknown as Wave\n }\n if (!wave.ring) wave.ring = { segs: [] } as any\n\n wave.x = x\n wave.y = y\n wave.r = 0\n wave.life = 0\n wave.ring.ang = Math.random() * Math.PI * 2\n wave.ring.rs = rc.rsList[Math.floor(Math.random() * rc.rsList.length)]\n wave.ring.segs[0] = {\n off: 0,\n len: rc.len,\n rRoundRate: rc.rRoundRateList[Math.floor(Math.random() * rc.rRoundRateList.length)],\n }\n wave.ring.segs[1] = {\n off: (Math.random() * 3 - 1.5) * Math.PI,\n len: rc.len,\n rRoundRate: rc.rRoundRateList[Math.floor(Math.random() * rc.rRoundRateList.length)],\n }\n\n this.waves.push(wave)\n\n const speedAdjust = this.scale / 1.5\n for (let i = 0; i < sparksCount; i++) {\n const a = Math.random() * Math.PI * 2\n const speed = (4.8 + Math.random() * 2) * speedAdjust\n\n let spark: Spark\n if (this.sparksPool.length > 0) {\n spark = this.sparksPool.pop()!\n } else {\n spark = {} as Spark\n }\n\n spark.x = x\n spark.y = y\n spark.vx = Math.cos(a) * speed\n spark.vy = Math.sin(a) * speed\n spark.rot = Math.random() * Math.PI * 2\n spark.rs = (Math.random() - 0.5) * 0.28\n spark.s = (4 + Math.random() * 3) * this.scale * this.sparkSize\n spark.a = 1\n spark.f = 0.9\n spark.fromClick = true\n this.sparks.push(spark)\n }\n }\n\n private clearBuffer(rect?: Rect): void {\n const ctx = this.bufferCtx\n if (rect) {\n ctx.clearRect(rect.x, rect.y, rect.w, rect.h)\n } else {\n ctx.clearRect(0, 0, this.cssWidth, this.cssHeight)\n }\n }\n\n private clearBufferRects(rects: Rect[]): void {\n if (!rects || rects.length === 0) return\n for (const rect of rects) {\n this.clearBuffer(rect)\n }\n }\n\n private updateTrail(frameScale: number): void {\n const ctx = this.bufferCtx\n const n = this.trail.length\n let baseDecay: number\n if (this.inputMode === 'mouse' && this.alwaysTrailEnabled) {\n baseDecay = 0.085 * frameScale\n } else {\n baseDecay = (this.isDown ? 0.085 : 0.18) * frameScale\n }\n const maxStep = 0.42\n for (let i = n - 1; i >= 0; i--) {\n const t = this.trail[i]\n const span = Math.max(1, n - 1)\n const along = n > 1 ? i / span : 1\n const towardCursorBias = 1.25 - 0.55 * along\n let step = baseDecay * towardCursorBias\n if (step > maxStep) step = maxStep\n t.life -= step\n if (t.life <= 0) this.trail.splice(i, 1)\n }\n\n const head = this.lastPos\n const pts: TrailPoint[] =\n head && this.trail.length > 0\n ? this.trail.concat([{ x: head.x, y: head.y, life: 1 }])\n : this.trail.slice()\n\n if (pts.length < 2) return\n\n const gap = Math.hypot(\n pts[pts.length - 1].x - pts[pts.length - 2].x,\n pts[pts.length - 1].y - pts[pts.length - 2].y,\n )\n if (gap < 0.75 && this.trail.length === 1) {\n const fade = Math.max(0, this.trail[0].life)\n ctx.shadowColor = 'transparent'\n const dotSize = (2.5 + 2 * fade) * (this.scale / 1.5) * this.trailWidth\n ctx.beginPath()\n ctx.arc(pts[0].x, pts[0].y, dotSize, 0, Math.PI * 2)\n ctx.fillStyle = `rgba(${this.color}, ${fade * 0.85})`\n ctx.fill()\n return\n }\n\n const numPts = pts.length\n const lastIdx = numPts - 1\n const baseWidth = 8 * (this.scale / 1.5) * this.trailWidth\n\n const lancetWidth = (progress: number): number => {\n if (progress < 0.65) return Math.pow(progress / 0.65, 0.6)\n return Math.pow((1 - progress) / 0.35, 1.8)\n }\n\n // 构建填充多边形的左右边缘点\n const leftEdge: Array<{ x: number; y: number }> = []\n const rightEdge: Array<{ x: number; y: number }> = []\n\n for (let i = 0; i < numPts; i++) {\n const progress = i / lastIdx\n const hw = Math.max(0.25, baseWidth * lancetWidth(progress)) / 2\n\n let dx: number, dy: number\n if (i === 0) {\n dx = pts[1].x - pts[0].x\n dy = pts[1].y - pts[0].y\n } else if (i === lastIdx) {\n dx = pts[i].x - pts[i - 1].x\n dy = pts[i].y - pts[i - 1].y\n } else {\n dx = pts[i + 1].x - pts[i - 1].x\n dy = pts[i + 1].y - pts[i - 1].y\n }\n let len = Math.hypot(dx, dy)\n if (len < 0.001) {\n dx = 0\n dy = 1\n len = 1\n }\n const nx = -dy / len\n const ny = dx / len\n\n leftEdge.push({ x: pts[i].x + nx * hw, y: pts[i].y + ny * hw })\n rightEdge.push({ x: pts[i].x - nx * hw, y: pts[i].y - ny * hw })\n }\n\n // 绘制填充多边形\n ctx.shadowColor = `rgba(${this.color}, 0.6)`\n ctx.shadowBlur = 3\n ctx.shadowOffsetX = 0\n ctx.shadowOffsetY = 0\n\n ctx.beginPath()\n ctx.moveTo(leftEdge[0].x, leftEdge[0].y)\n for (let i = 1; i < numPts; i++) {\n ctx.lineTo(leftEdge[i].x, leftEdge[i].y)\n }\n for (let i = numPts - 1; i >= 0; i--) {\n ctx.lineTo(rightEdge[i].x, rightEdge[i].y)\n }\n ctx.closePath()\n\n const grad = ctx.createLinearGradient(\n pts[0].x, pts[0].y, pts[lastIdx].x, pts[lastIdx].y,\n )\n grad.addColorStop(0, `rgba(${this.color}, 0)`)\n grad.addColorStop(1, `rgba(${this.color}, 1)`)\n\n ctx.fillStyle = grad\n ctx.fill()\n\n ctx.shadowColor = 'transparent'\n }\n\n private strokeRingSegment(\n wx: number, wy: number, radius: number,\n a0: number, a1: number, lineWidth: number, strokeStyle: string,\n ): void {\n const ctx = this.bufferCtx\n ctx.beginPath()\n ctx.arc(wx, wy, radius, a0, a1)\n ctx.lineWidth = lineWidth\n ctx.strokeStyle = strokeStyle\n ctx.stroke()\n }\n\n private updateWaves(clickFrameScale: number): void {\n const filled = FILLED_CIRCLE_CFG\n const rings = RINGS_ANIM_CFG\n const ctx = this.bufferCtx\n\n for (let i = this.waves.length - 1; i >= 0; i--) {\n const w = this.waves[i]\n const waveProg = Math.min(w.life / filled.maxLife, 1)\n const ringProg = Math.min(w.life / rings.maxLife, 1)\n\n // filled circle\n {\n w.life += clickFrameScale\n const ease = 1 - Math.pow(1 - waveProg, 3)\n w.r = filled.rAddRate * this.scale * this.clickScale * ease\n const alpha = Math.max(0, 1 - waveProg)\n if (alpha > 0) {\n ctx.beginPath()\n ctx.arc(w.x, w.y, w.r, 0, Math.PI * 2)\n ctx.fillStyle = `rgba(${this.color},${this.alpha(alpha)})`\n ctx.fill()\n }\n }\n\n // rings\n {\n const getWeightProp = (t: number) => Math.min(2 - Math.abs(4 * (t - 0.5)), 1)\n\n const getAlpha = (rProg: number) => Math.min(1.1 - 0.3 * rProg, 1)\n\n const r = w.ring\n r.ang -= r.rs * clickFrameScale\n\n const ringRgbAt = (rProg: number): [number, number, number] => {\n const t = Math.min(1.2 * rProg, 1)\n return [\n Math.round(this.ringsStartColor[0] * (1 - t) + this.ringsEndColor[0] * t),\n Math.round(this.ringsStartColor[1] * (1 - t) + this.ringsEndColor[1] * t),\n Math.round(this.ringsStartColor[2] * (1 - t) + this.ringsEndColor[2] * t),\n ]\n }\n\n let start = 0\n let end = 0\n let len = 0\n let seg: { off: number; len: number; rRoundRate: number }\n\n for (let j = 0; j < 2; j++) {\n seg = r.segs[j]\n const base = r.ang + seg.off\n\n if (ringProg <= rings.lenStopAddPoint) {\n len = seg.len * (ringProg / rings.lenStopAddPoint)\n end = base + seg.len\n start = end - len\n } else if (ringProg > rings.lenStartDimPoint) {\n len = seg.len * (1 - (ringProg - rings.lenStartDimPoint) / (1 - rings.lenStartDimPoint))\n start = base\n end = start + len\n } else {\n len = seg.len\n start = base\n end = start + len\n }\n\n const lineWidthMul = Math.min(-0.8 * (ringProg - 0.8) + 1, 1)\n const [rr, gg, bb] = ringRgbAt(ringProg)\n const alphaRing = getAlpha(ringProg)\n\n for (let k = 0; k < rings.segNum; k++) {\n const t0 = k / rings.segNum\n const t1 = (k + 1) / rings.segNum\n const a0 = start + (end - start) * t0\n const a1 = start + (end - start) * t1\n\n if (Math.abs(a1 - a0) < 0.01) continue\n\n const wT = getWeightProp(t0)\n const lw = (rings.minW * (1 - wT) + rings.maxW * wT) * lineWidthMul\n const strokeStyle = `rgba(${rr},${gg},${bb},${alphaRing})`\n const radius = w.r + seg.rRoundRate * this.scale * this.clickScale\n this.strokeRingSegment(w.x, w.y, radius, a0, a1, lw, strokeStyle)\n }\n }\n }\n\n if (ringProg >= 1 && waveProg >= 1) {\n this.wavesPool.push(this.waves[i])\n this.waves.splice(i, 1)\n }\n }\n }\n\n private updateSparks(clickFrameScale: number, trailFrameScale: number): void {\n const ctx = this.bufferCtx\n for (let i = this.sparks.length - 1; i >= 0; i--) {\n const s = this.sparks[i]\n const fs = s.fromClick ? clickFrameScale : trailFrameScale\n s.x += s.vx * fs\n s.y += s.vy * fs\n s.vx *= Math.pow(s.f, fs)\n s.vy *= Math.pow(s.f, fs)\n s.rot += s.rs * fs\n s.a -= 0.032 * fs\n if (s.a <= 0) {\n this.sparksPool.push(this.sparks[i])\n this.sparks.splice(i, 1)\n continue\n }\n\n ctx.save()\n ctx.translate(s.x, s.y)\n ctx.rotate(s.rot)\n ctx.beginPath()\n ctx.moveTo(0, -s.s)\n ctx.lineTo(s.s * 0.6, s.s * 0.6)\n ctx.lineTo(-s.s * 0.6, s.s * 0.6)\n ctx.fillStyle = `rgba(255,255,255,${this.alpha(s.a)})`\n ctx.fill()\n ctx.restore()\n }\n }\n\n private canvasRect(): Rect {\n return { x: 0, y: 0, w: this.cssWidth, h: this.cssHeight }\n }\n\n private clipRect(rect: Rect): Rect | null {\n if (!rect) return null\n const x0 = Math.max(0, Math.floor(rect.x))\n const y0 = Math.max(0, Math.floor(rect.y))\n const x1 = Math.min(this.cssWidth, Math.ceil(rect.x + rect.w))\n const y1 = Math.min(this.cssHeight, Math.ceil(rect.y + rect.h))\n if (x1 <= x0 || y1 <= y0) return null\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n }\n\n private pointRect(x: number, y: number, padding: number): Rect {\n return { x: x - padding, y: y - padding, w: padding * 2, h: padding * 2 }\n }\n\n private segmentRect(a: Point, b: Point, padding: number): Rect {\n const x0 = Math.min(a.x, b.x) - padding\n const y0 = Math.min(a.y, b.y) - padding\n const x1 = Math.max(a.x, b.x) + padding\n const y1 = Math.max(a.y, b.y) + padding\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n }\n\n private intersects(a: Rect, b: Rect): boolean {\n return (\n a.x <= b.x + b.w &&\n a.x + a.w >= b.x &&\n a.y <= b.y + b.h &&\n a.y + a.h >= b.y\n )\n }\n\n private unionRect(a: Rect, b: Rect): Rect {\n const x0 = Math.min(a.x, b.x)\n const y0 = Math.min(a.y, b.y)\n const x1 = Math.max(a.x + a.w, b.x + b.w)\n const y1 = Math.max(a.y + a.h, b.y + b.h)\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n }\n\n private mergeRects(rects: Rect[]): Rect[] {\n const merged: Rect[] = []\n for (const raw of rects) {\n let rect = this.clipRect(raw)\n if (!rect) continue\n\n for (let i = 0; i < merged.length; i++) {\n if (this.intersects(merged[i], rect)) {\n rect = this.unionRect(merged[i], rect)\n merged.splice(i, 1)\n i = -1\n }\n }\n\n merged.push(rect)\n }\n return merged\n }\n\n private getEffectRects(): Rect[] {\n const rects: Rect[] = []\n const trailPad = 18 * this.scale * this.trailWidth + 12\n\n const trailPoints: TrailPoint[] =\n this.lastPos && this.trail.length > 0\n ? this.trail.concat([{ x: this.lastPos.x, y: this.lastPos.y, life: 1 }])\n : this.trail\n\n if (trailPoints.length === 1) {\n rects.push(this.pointRect(trailPoints[0].x, trailPoints[0].y, trailPad))\n } else {\n for (let i = 0; i < trailPoints.length - 1; i++) {\n rects.push(this.segmentRect(trailPoints[i], trailPoints[i + 1], trailPad))\n }\n }\n\n const wavePad = 34 * this.scale * this.clickScale + RINGS_ANIM_CFG.maxW + 16\n for (const wave of this.waves) {\n const radius = Math.max(wave.r || 0, FILLED_CIRCLE_CFG.rAddRate * this.scale * this.clickScale) + wavePad\n rects.push(this.pointRect(wave.x, wave.y, radius))\n }\n\n const maxFrameScale = MAX_DELTA_MS / BASE_FRAME_MS\n for (const spark of this.sparks) {\n const speed = Math.hypot(spark.vx || 0, spark.vy || 0)\n const speedScale = spark.fromClick ? this.clickSpeed : this.trailSpeed\n const motionPad = speed * maxFrameScale * speedScale\n const sparkPad = Math.max(spark.s || 0, 9 * this.scale * this.sparkSize) * 2 + motionPad + 12\n rects.push(this.pointRect(spark.x, spark.y, sparkPad))\n }\n\n return this.mergeRects(rects)\n }\n\n private getRenderRects(): Rect[] {\n if (this.forceFullRedraw) {\n return [this.canvasRect()]\n }\n return this.mergeRects(this.previousDirtyRects.concat(this.getEffectRects()))\n }\n\n private clipToRects(ctx: CanvasRenderingContext2D, rects: Rect[]): void {\n ctx.beginPath()\n for (const rect of rects) {\n ctx.rect(rect.x, rect.y, rect.w, rect.h)\n }\n ctx.clip()\n }\n\n private renderToMain(rects: Rect[]): void {\n const { mainCtx, mainCanvas, bufferCanvas } = this\n if (!rects || rects.length === 0) {\n mainCtx.clearRect(0, 0, mainCanvas.width, mainCanvas.height)\n mainCtx.drawImage(bufferCanvas, 0, 0)\n return\n }\n\n const dpr = this.dpr || 1\n for (const rect of rects) {\n const sx = Math.max(0, Math.floor(rect.x * dpr))\n const sy = Math.max(0, Math.floor(rect.y * dpr))\n const sw = Math.min(mainCanvas.width - sx, Math.ceil(rect.w * dpr))\n const sh = Math.min(mainCanvas.height - sy, Math.ceil(rect.h * dpr))\n if (sw <= 0 || sh <= 0) continue\n\n mainCtx.clearRect(sx, sy, sw, sh)\n mainCtx.drawImage(bufferCanvas, sx, sy, sw, sh, sx, sy, sw, sh)\n }\n }\n\n private animationLoops(now: number): void {\n const hasWork =\n this.waves.length > 0 ||\n this.sparks.length > 0 ||\n this.trail.length > 0\n\n if (!hasWork) {\n this.lastFrameTime = now\n if (this.previousDirtyRects.length > 0) {\n this.clearBufferRects(this.previousDirtyRects)\n this.renderToMain(this.previousDirtyRects)\n this.previousDirtyRects = []\n }\n this.animFrameId = requestAnimationFrame((nextNow) => this.animationLoops(nextNow))\n return\n }\n\n const deltaMs = Math.min(now - this.lastFrameTime, MAX_DELTA_MS)\n this.lastFrameTime = now\n const baseScale = deltaMs / BASE_FRAME_MS\n const trailFrameScale = baseScale * this.trailSpeed\n const clickFrameScale = baseScale * this.clickSpeed\n\n const bctx = this.bufferCtx\n const renderRects = this.getRenderRects()\n\n bctx.save()\n this.clipToRects(bctx, renderRects)\n bctx.globalCompositeOperation = 'lighter'\n\n this.clearBufferRects(renderRects)\n this.updateTrail(trailFrameScale)\n this.updateWaves(clickFrameScale)\n this.updateSparks(clickFrameScale, trailFrameScale)\n\n bctx.globalCompositeOperation = 'source-over'\n bctx.restore()\n\n this.renderToMain(renderRects)\n this.previousDirtyRects = this.getEffectRects()\n this.forceFullRedraw = false\n\n this.animFrameId = requestAnimationFrame((nextNow) => this.animationLoops(nextNow))\n }\n\n destroy(): void {\n cancelAnimationFrame(this.animFrameId)\n this.waves.length = 0\n this.sparks.length = 0\n this.trail.length = 0\n this.sparksPool.length = 0\n this.wavesPool.length = 0\n this.previousDirtyRects = []\n const ctx = this.mainCtx\n ctx.clearRect(0, 0, this.mainCanvas.width, this.mainCanvas.height)\n }\n}\n","import { MouseSpark } from './core/MouseSpark'\nimport type { BASparkOptions } from './core/types'\nimport { DEFAULT_Z_INDEX } from './core/constants'\n\nexport class BASpark {\n private canvas: HTMLCanvasElement\n private spark: MouseSpark\n private autoTrack: boolean\n private boundHandlers: {\n mouseDown: (e: MouseEvent) => void\n mouseMove: (e: MouseEvent) => void\n mouseUp: (e: MouseEvent) => void\n touchStart: (e: TouchEvent) => void\n touchMove: (e: TouchEvent) => void\n touchEnd: (e: TouchEvent) => void\n resize: () => void\n }\n\n constructor(element: HTMLElement | string, options: BASparkOptions = {}) {\n this.autoTrack = options.autoTrack ?? true\n\n const target = typeof element === 'string'\n ? document.querySelector<HTMLElement>(element)\n : element\n if (!target) throw new Error('BASpark: target element not found')\n\n this.canvas = document.createElement('canvas')\n this.canvas.id = 'baspark-canvas'\n this.canvas.style.cssText = `\n position: fixed;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: ${options.zIndex ?? DEFAULT_Z_INDEX};\n `\n target.appendChild(this.canvas)\n\n this.spark = new MouseSpark(this.canvas, {\n color: options.color,\n scale: options.scale,\n opacity: options.opacity,\n trailSpeed: options.trailSpeed,\n clickSpeed: options.clickSpeed,\n trailWidth: options.trailWidth,\n sparkSize: options.sparkSize,\n clickScale: options.clickScale,\n alwaysTrail: options.alwaysTrail,\n })\n\n this.boundHandlers = {\n mouseDown: (e: MouseEvent) => {\n this.spark.handleDown(e.clientX, e.clientY)\n },\n mouseMove: (e: MouseEvent) => {\n this.spark.handleMove(e.clientX, e.clientY)\n },\n mouseUp: () => {\n this.spark.handleUp()\n },\n touchStart: (e: TouchEvent) => {\n const t = e.touches[0]\n this.spark.setInputContext('touch', false)\n this.spark.handleDown(t.clientX, t.clientY)\n },\n touchMove: (e: TouchEvent) => {\n const t = e.touches[0]\n this.spark.handleMove(t.clientX, t.clientY)\n },\n touchEnd: () => {\n this.spark.setInputContext('mouse', false)\n this.spark.handleUp()\n },\n resize: () => {\n this.spark.resize()\n },\n }\n\n if (this.autoTrack) {\n this.bindEvents()\n }\n }\n\n private bindEvents(): void {\n window.addEventListener('mousedown', this.boundHandlers.mouseDown)\n window.addEventListener('mousemove', this.boundHandlers.mouseMove)\n window.addEventListener('mouseup', this.boundHandlers.mouseUp)\n window.addEventListener('touchstart', this.boundHandlers.touchStart, { passive: true })\n window.addEventListener('touchmove', this.boundHandlers.touchMove, { passive: true })\n window.addEventListener('touchend', this.boundHandlers.touchEnd)\n window.addEventListener('resize', this.boundHandlers.resize)\n }\n\n private unbindEvents(): void {\n window.removeEventListener('mousedown', this.boundHandlers.mouseDown)\n window.removeEventListener('mousemove', this.boundHandlers.mouseMove)\n window.removeEventListener('mouseup', this.boundHandlers.mouseUp)\n window.removeEventListener('touchstart', this.boundHandlers.touchStart)\n window.removeEventListener('touchmove', this.boundHandlers.touchMove)\n window.removeEventListener('touchend', this.boundHandlers.touchEnd)\n window.removeEventListener('resize', this.boundHandlers.resize)\n }\n\n boom(xPercent: number, yPercent: number): void {\n const cx = xPercent * window.innerWidth\n const cy = yPercent * window.innerHeight\n this.spark.handleDown(cx, cy)\n }\n\n move(xPercent: number, yPercent: number): void {\n const cx = xPercent * window.innerWidth\n const cy = yPercent * window.innerHeight\n this.spark.handleMove(cx, cy)\n }\n\n up(): void {\n this.spark.handleUp()\n }\n\n boomAt(x: number, y: number): void {\n this.spark.handleDown(x, y)\n }\n\n moveAt(x: number, y: number): void {\n this.spark.handleMove(x, y)\n }\n\n setColor(rgb: string): void {\n this.spark.updateColor(rgb)\n }\n\n setScale(scale: number): void {\n const s = this.spark\n s.updateEffectSettings(scale, s.opacity, s.trailSpeed, s.clickSpeed)\n }\n\n setOpacity(opacity: number): void {\n const s = this.spark\n s.updateEffectSettings(s.scale, opacity, s.trailSpeed, s.clickSpeed)\n }\n\n setSpeed(trailSpeed: number, clickSpeed?: number): void {\n this.spark.updateEffectSettings(\n this.spark.scale,\n this.spark.opacity,\n trailSpeed,\n clickSpeed ?? trailSpeed,\n )\n }\n\n setAlwaysTrail(enabled: boolean): void {\n this.spark.setInputContext('mouse', enabled)\n }\n\n setTrailWidth(v: number): void {\n this.spark.setTrailWidth(v)\n }\n\n setSparkSize(v: number): void {\n this.spark.setSparkSize(v)\n }\n\n setClickScale(v: number): void {\n this.spark.setClickScale(v)\n }\n\n updateOptions(options: BASparkOptions): void {\n if (options.color !== undefined) this.setColor(options.color)\n if (options.scale !== undefined) this.setScale(options.scale)\n if (options.opacity !== undefined) this.setOpacity(options.opacity)\n if (options.trailSpeed !== undefined) {\n this.setSpeed(options.trailSpeed, options.clickSpeed)\n }\n if (options.trailWidth !== undefined) this.setTrailWidth(options.trailWidth)\n if (options.sparkSize !== undefined) this.setSparkSize(options.sparkSize)\n if (options.clickScale !== undefined) this.setClickScale(options.clickScale)\n if (options.alwaysTrail !== undefined) this.setAlwaysTrail(options.alwaysTrail)\n if (options.autoTrack !== undefined && options.autoTrack !== this.autoTrack) {\n this.autoTrack = options.autoTrack\n if (this.autoTrack) {\n this.bindEvents()\n } else {\n this.unbindEvents()\n }\n }\n }\n\n destroy(): void {\n this.unbindEvents()\n this.spark.destroy()\n this.canvas.remove()\n }\n}\n"],"mappings":"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","names":["index_exports","__export","BASpark","MouseSpark","FILLED_CIRCLE_CFG","RINGS_ANIM_CFG","CREATE_CLICK_CFG","DEFAULT_COLOR","DEFAULT_SCALE","DEFAULT_OPACITY","DEFAULT_SPEED","DEFAULT_Z_INDEX","BASE_FRAME_MS","MAX_DELTA_MS","ringsEndColorFromRgb","rgbString","r","g","b","dist","a","MouseSpark","canvas","opts","DEFAULT_COLOR","DEFAULT_SCALE","DEFAULT_OPACITY","DEFAULT_SPEED","now","dpr","cssWidth","cssHeight","w","h","mode","alwaysTrail","v","scale","opacity","trailSpeed","clickSpeed","t","c","x","y","prev","speedAdjust","value","rc","CREATE_CLICK_CFG","sparksCount","wave","i","speed","spark","rect","ctx","rects","frameScale","n","baseDecay","maxStep","span","towardCursorBias","step","head","pts","fade","dotSize","numPts","lastIdx","baseWidth","lancetWidth","progress","leftEdge","rightEdge","hw","dx","dy","len","nx","ny","grad","wx","wy","radius","a0","a1","lineWidth","strokeStyle","clickFrameScale","filled","FILLED_CIRCLE_CFG","rings","RINGS_ANIM_CFG","waveProg","ringProg","ease","alpha","getWeightProp","getAlpha","rProg","ringRgbAt","start","end","seg","j","base","lineWidthMul","rr","gg","bb","alphaRing","k","t0","t1","wT","lw","trailFrameScale","fs","x0","y0","x1","y1","padding","merged","raw","trailPad","trailPoints","wavePad","maxFrameScale","MAX_DELTA_MS","BASE_FRAME_MS","speedScale","motionPad","sparkPad","mainCtx","mainCanvas","bufferCanvas","sx","sy","sw","sh","nextNow","deltaMs","baseScale","bctx","renderRects","BASpark","element","options","target","DEFAULT_Z_INDEX","MouseSpark","e","t","xPercent","yPercent","cx","cy","x","y","rgb","scale","s","opacity","trailSpeed","clickSpeed","enabled","v"]}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ var E={rAddRate:26,maxLife:16},T={rsList:[0,.08,.1],rRoundRateList:[0,1,1.5,2],len:1.1*Math.PI,maxLife:23,segNum:10,minW:.4,maxW:3.3,lenStopAddPoint:.1,lenStartDimPoint:.4},P={rings:{rsList:[0,.03,.06],rRoundRateList:[0,1,1.5,2],len:1.1*Math.PI},sparksCount:4},N="45,175,255",L=1.5,A=1,C=1,O=2147483647,D=1e3/60,F=100;function U(x){let[t,e,i]=x.split(",").map(Number);return[Math.round((t+510)/3),Math.round((e+510)/3),Math.round((i+510)/3)]}function Y(x,t){return Math.hypot(x.x-t.x,x.y-t.y)}var w=class{constructor(t,e={}){this.sparksPool=[];this.wavesPool=[];this.waves=[];this.sparks=[];this.trail=[];this.isDown=!1;this.lastPos=null;this.lastFrameTime=performance.now();this.dpr=1;this.cssWidth=1;this.cssHeight=1;this.previousDirtyRects=[];this.forceFullRedraw=!0;this.ringsStartColor=[250,252,252];this.animFrameId=0;this.inputMode="mouse";this.alwaysTrailEnabled=!1;this.effectiveAlwaysTrail=!1;this.color=e.color??N,this.scale=e.scale??L,this.opacity=e.opacity??A,this.trailSpeed=e.trailSpeed??C,this.clickSpeed=e.clickSpeed??C,this.trailWidth=e.trailWidth??1,this.sparkSize=e.sparkSize??1,this.clickScale=e.clickScale??1,this.maxTrail=e.maxTrail??16,this.alwaysTrailEnabled=e.alwaysTrail??!1,this.ringsEndColor=U(this.color),this.initCanvas(t),this.animFrameId=requestAnimationFrame(i=>this.animationLoops(i))}initCanvas(t){this.mainCanvas=t,this.mainCtx=t.getContext("2d"),this.bufferCanvas=document.createElement("canvas"),this.bufferCtx=this.bufferCanvas.getContext("2d"),this.resize()}resize(){let t=window.devicePixelRatio||1,e=Math.max(1,window.innerWidth),i=Math.max(1,window.innerHeight),a=Math.max(1,Math.floor(e*t)),s=Math.max(1,Math.floor(i*t));this.dpr=t,this.cssWidth=e,this.cssHeight=i,this.mainCanvas.width=a,this.mainCanvas.height=s,this.bufferCanvas.width=a,this.bufferCanvas.height=s,this.previousDirtyRects=[],this.forceFullRedraw=!0,this.bufferCtx.setTransform(t,0,0,t,0,0)}setInputContext(t,e){this.inputMode=t==="touch"?"touch":"mouse",this.alwaysTrailEnabled=!!e,this.effectiveAlwaysTrail=this.inputMode==="mouse"&&this.alwaysTrailEnabled}updateColor(t){this.color=t,this.ringsEndColor=U(t)}setTrailWidth(t){this.trailWidth=Math.max(.25,Math.min(4,Number(t)||1))}setSparkSize(t){this.sparkSize=Math.max(.25,Math.min(4,Number(t)||1))}setClickScale(t){this.clickScale=Math.max(.25,Math.min(4,Number(t)||1))}updateEffectSettings(t,e,i,a){this.scale=Math.max(.5,Math.min(3,Number(t)||L)),this.opacity=Math.max(.1,Math.min(1,Number(e)||A));let s=Number(i);Number.isFinite(s)||(s=C);let n=Number(a);Number.isFinite(n)||(n=s),this.trailSpeed=Math.max(.2,Math.min(3,s)),this.clickSpeed=Math.max(.2,Math.min(3,n))}handleDown(t,e){this.isDown=!0,this.lastPos={x:t,y:e},this.createEffects(t,e)}handleMove(t,e){if(!this.isDown&&!(this.inputMode==="mouse"&&this.alwaysTrailEnabled))return;let i=this.lastPos;if(!i){this.lastPos={x:t,y:e};return}if(Y({x:t,y:e},i)>2&&(this.trail.push({x:t,y:e,life:1}),this.trail.length>this.maxTrail&&this.trail.shift(),Math.random()<.3)){let a=Math.random()*Math.PI*2,s=this.scale/1.5;this.sparks.push({x:t+Math.cos(a)*10*this.scale,y:e+Math.sin(a)*10*this.scale,vx:Math.cos(a)*1.3*s,vy:Math.sin(a)*1.3*s,rot:Math.random()*Math.PI*2,rs:.16,s:9*this.scale*this.sparkSize,a:.7,f:.95,fromClick:!1})}this.lastPos={x:t,y:e}}handleUp(){this.isDown=!1}alpha(t){return Math.max(0,Math.min(1,t*this.opacity))}createEffects(t,e){let i=P.rings,a=P.sparksCount,s;this.wavesPool.length>0?s=this.wavesPool.pop():s={ring:{segs:[]}},s.ring||(s.ring={segs:[]}),s.x=t,s.y=e,s.r=0,s.life=0,s.ring.ang=Math.random()*Math.PI*2,s.ring.rs=i.rsList[Math.floor(Math.random()*i.rsList.length)],s.ring.segs[0]={off:0,len:i.len,rRoundRate:i.rRoundRateList[Math.floor(Math.random()*i.rRoundRateList.length)]},s.ring.segs[1]={off:(Math.random()*3-1.5)*Math.PI,len:i.len,rRoundRate:i.rRoundRateList[Math.floor(Math.random()*i.rRoundRateList.length)]},this.waves.push(s);let n=this.scale/1.5;for(let r=0;r<a;r++){let l=Math.random()*Math.PI*2,c=(4.8+Math.random()*2)*n,h;this.sparksPool.length>0?h=this.sparksPool.pop():h={},h.x=t,h.y=e,h.vx=Math.cos(l)*c,h.vy=Math.sin(l)*c,h.rot=Math.random()*Math.PI*2,h.rs=(Math.random()-.5)*.28,h.s=(4+Math.random()*3)*this.scale*this.sparkSize,h.a=1,h.f=.9,h.fromClick=!0,this.sparks.push(h)}}clearBuffer(t){let e=this.bufferCtx;t?e.clearRect(t.x,t.y,t.w,t.h):e.clearRect(0,0,this.cssWidth,this.cssHeight)}clearBufferRects(t){if(!(!t||t.length===0))for(let e of t)this.clearBuffer(e)}updateTrail(t){let e=this.bufferCtx,i=this.trail.length,a;this.inputMode==="mouse"&&this.alwaysTrailEnabled?a=.085*t:a=(this.isDown?.085:.18)*t;let s=.42;for(let o=i-1;o>=0;o--){let u=this.trail[o],d=Math.max(1,i-1),f=1.25-.55*(i>1?o/d:1),b=a*f;b>s&&(b=s),u.life-=b,u.life<=0&&this.trail.splice(o,1)}let n=this.lastPos,r=n&&this.trail.length>0?this.trail.concat([{x:n.x,y:n.y,life:1}]):this.trail.slice();if(r.length<2)return;if(Math.hypot(r[r.length-1].x-r[r.length-2].x,r[r.length-1].y-r[r.length-2].y)<.75&&this.trail.length===1){let o=Math.max(0,this.trail[0].life);e.shadowColor="transparent";let u=(2.5+2*o)*(this.scale/1.5)*this.trailWidth;e.beginPath(),e.arc(r[0].x,r[0].y,u,0,Math.PI*2),e.fillStyle=`rgba(${this.color}, ${o*.85})`,e.fill();return}let c=r.length,h=c-1,g=8*(this.scale/1.5)*this.trailWidth,R=o=>o<.65?Math.pow(o/.65,.6):Math.pow((1-o)/.35,1.8),m=[],p=[];for(let o=0;o<c;o++){let u=o/h,d=Math.max(.25,g*R(u))/2,M,f;o===0?(M=r[1].x-r[0].x,f=r[1].y-r[0].y):o===h?(M=r[o].x-r[o-1].x,f=r[o].y-r[o-1].y):(M=r[o+1].x-r[o-1].x,f=r[o+1].y-r[o-1].y);let b=Math.hypot(M,f);b<.001&&(M=0,f=1,b=1);let y=-f/b,k=M/b;m.push({x:r[o].x+y*d,y:r[o].y+k*d}),p.push({x:r[o].x-y*d,y:r[o].y-k*d})}e.shadowColor=`rgba(${this.color}, 0.6)`,e.shadowBlur=3,e.shadowOffsetX=0,e.shadowOffsetY=0,e.beginPath(),e.moveTo(m[0].x,m[0].y);for(let o=1;o<c;o++)e.lineTo(m[o].x,m[o].y);for(let o=c-1;o>=0;o--)e.lineTo(p[o].x,p[o].y);e.closePath();let v=e.createLinearGradient(r[0].x,r[0].y,r[h].x,r[h].y);v.addColorStop(0,`rgba(${this.color}, 0)`),v.addColorStop(1,`rgba(${this.color}, 1)`),e.fillStyle=v,e.fill(),e.shadowColor="transparent"}strokeRingSegment(t,e,i,a,s,n,r){let l=this.bufferCtx;l.beginPath(),l.arc(t,e,i,a,s),l.lineWidth=n,l.strokeStyle=r,l.stroke()}updateWaves(t){let e=E,i=T,a=this.bufferCtx;for(let s=this.waves.length-1;s>=0;s--){let n=this.waves[s],r=Math.min(n.life/e.maxLife,1),l=Math.min(n.life/i.maxLife,1);{n.life+=t;let c=1-Math.pow(1-r,3);n.r=e.rAddRate*this.scale*this.clickScale*c;let h=Math.max(0,1-r);h>0&&(a.beginPath(),a.arc(n.x,n.y,n.r,0,Math.PI*2),a.fillStyle=`rgba(${this.color},${this.alpha(h)})`,a.fill())}{let c=u=>Math.min(2-Math.abs(4*(u-.5)),1),h=u=>Math.min(1.1-.3*u,1),g=n.ring;g.ang-=g.rs*t;let R=u=>{let d=Math.min(1.2*u,1);return[Math.round(this.ringsStartColor[0]*(1-d)+this.ringsEndColor[0]*d),Math.round(this.ringsStartColor[1]*(1-d)+this.ringsEndColor[1]*d),Math.round(this.ringsStartColor[2]*(1-d)+this.ringsEndColor[2]*d)]},m=0,p=0,v=0,o;for(let u=0;u<2;u++){o=g.segs[u];let d=g.ang+o.off;l<=i.lenStopAddPoint?(v=o.len*(l/i.lenStopAddPoint),p=d+o.len,m=p-v):l>i.lenStartDimPoint?(v=o.len*(1-(l-i.lenStartDimPoint)/(1-i.lenStartDimPoint)),m=d,p=m+v):(v=o.len,m=d,p=m+v);let M=Math.min(-.8*(l-.8)+1,1),[f,b,y]=R(l),k=h(l);for(let S=0;S<i.segNum;S++){let I=S/i.segNum,B=(S+1)/i.segNum,H=m+(p-m)*I,_=m+(p-m)*B;if(Math.abs(_-H)<.01)continue;let z=c(I),$=(i.minW*(1-z)+i.maxW*z)*M,G=`rgba(${f},${b},${y},${k})`,X=n.r+o.rRoundRate*this.scale*this.clickScale;this.strokeRingSegment(n.x,n.y,X,H,_,$,G)}}}l>=1&&r>=1&&(this.wavesPool.push(this.waves[s]),this.waves.splice(s,1))}}updateSparks(t,e){let i=this.bufferCtx;for(let a=this.sparks.length-1;a>=0;a--){let s=this.sparks[a],n=s.fromClick?t:e;if(s.x+=s.vx*n,s.y+=s.vy*n,s.vx*=Math.pow(s.f,n),s.vy*=Math.pow(s.f,n),s.rot+=s.rs*n,s.a-=.032*n,s.a<=0){this.sparksPool.push(this.sparks[a]),this.sparks.splice(a,1);continue}i.save(),i.translate(s.x,s.y),i.rotate(s.rot),i.beginPath(),i.moveTo(0,-s.s),i.lineTo(s.s*.6,s.s*.6),i.lineTo(-s.s*.6,s.s*.6),i.fillStyle=`rgba(255,255,255,${this.alpha(s.a)})`,i.fill(),i.restore()}}canvasRect(){return{x:0,y:0,w:this.cssWidth,h:this.cssHeight}}clipRect(t){if(!t)return null;let e=Math.max(0,Math.floor(t.x)),i=Math.max(0,Math.floor(t.y)),a=Math.min(this.cssWidth,Math.ceil(t.x+t.w)),s=Math.min(this.cssHeight,Math.ceil(t.y+t.h));return a<=e||s<=i?null:{x:e,y:i,w:a-e,h:s-i}}pointRect(t,e,i){return{x:t-i,y:e-i,w:i*2,h:i*2}}segmentRect(t,e,i){let a=Math.min(t.x,e.x)-i,s=Math.min(t.y,e.y)-i,n=Math.max(t.x,e.x)+i,r=Math.max(t.y,e.y)+i;return{x:a,y:s,w:n-a,h:r-s}}intersects(t,e){return t.x<=e.x+e.w&&t.x+t.w>=e.x&&t.y<=e.y+e.h&&t.y+t.h>=e.y}unionRect(t,e){let i=Math.min(t.x,e.x),a=Math.min(t.y,e.y),s=Math.max(t.x+t.w,e.x+e.w),n=Math.max(t.y+t.h,e.y+e.h);return{x:i,y:a,w:s-i,h:n-a}}mergeRects(t){let e=[];for(let i of t){let a=this.clipRect(i);if(a){for(let s=0;s<e.length;s++)this.intersects(e[s],a)&&(a=this.unionRect(e[s],a),e.splice(s,1),s=-1);e.push(a)}}return e}getEffectRects(){let t=[],e=18*this.scale*this.trailWidth+12,i=this.lastPos&&this.trail.length>0?this.trail.concat([{x:this.lastPos.x,y:this.lastPos.y,life:1}]):this.trail;if(i.length===1)t.push(this.pointRect(i[0].x,i[0].y,e));else for(let n=0;n<i.length-1;n++)t.push(this.segmentRect(i[n],i[n+1],e));let a=34*this.scale*this.clickScale+T.maxW+16;for(let n of this.waves){let r=Math.max(n.r||0,E.rAddRate*this.scale*this.clickScale)+a;t.push(this.pointRect(n.x,n.y,r))}let s=F/D;for(let n of this.sparks){let r=Math.hypot(n.vx||0,n.vy||0),l=n.fromClick?this.clickSpeed:this.trailSpeed,c=r*s*l,h=Math.max(n.s||0,9*this.scale*this.sparkSize)*2+c+12;t.push(this.pointRect(n.x,n.y,h))}return this.mergeRects(t)}getRenderRects(){return this.forceFullRedraw?[this.canvasRect()]:this.mergeRects(this.previousDirtyRects.concat(this.getEffectRects()))}clipToRects(t,e){t.beginPath();for(let i of e)t.rect(i.x,i.y,i.w,i.h);t.clip()}renderToMain(t){let{mainCtx:e,mainCanvas:i,bufferCanvas:a}=this;if(!t||t.length===0){e.clearRect(0,0,i.width,i.height),e.drawImage(a,0,0);return}let s=this.dpr||1;for(let n of t){let r=Math.max(0,Math.floor(n.x*s)),l=Math.max(0,Math.floor(n.y*s)),c=Math.min(i.width-r,Math.ceil(n.w*s)),h=Math.min(i.height-l,Math.ceil(n.h*s));c<=0||h<=0||(e.clearRect(r,l,c,h),e.drawImage(a,r,l,c,h,r,l,c,h))}}animationLoops(t){if(!(this.waves.length>0||this.sparks.length>0||this.trail.length>0)){this.lastFrameTime=t,this.previousDirtyRects.length>0&&(this.clearBufferRects(this.previousDirtyRects),this.renderToMain(this.previousDirtyRects),this.previousDirtyRects=[]),this.animFrameId=requestAnimationFrame(c=>this.animationLoops(c));return}let i=Math.min(t-this.lastFrameTime,F);this.lastFrameTime=t;let a=i/D,s=a*this.trailSpeed,n=a*this.clickSpeed,r=this.bufferCtx,l=this.getRenderRects();r.save(),this.clipToRects(r,l),r.globalCompositeOperation="lighter",this.clearBufferRects(l),this.updateTrail(s),this.updateWaves(n),this.updateSparks(n,s),r.globalCompositeOperation="source-over",r.restore(),this.renderToMain(l),this.previousDirtyRects=this.getEffectRects(),this.forceFullRedraw=!1,this.animFrameId=requestAnimationFrame(c=>this.animationLoops(c))}destroy(){cancelAnimationFrame(this.animFrameId),this.waves.length=0,this.sparks.length=0,this.trail.length=0,this.sparksPool.length=0,this.wavesPool.length=0,this.previousDirtyRects=[],this.mainCtx.clearRect(0,0,this.mainCanvas.width,this.mainCanvas.height)}};var W=class{constructor(t,e={}){this.autoTrack=e.autoTrack??!0;let i=typeof t=="string"?document.querySelector(t):t;if(!i)throw new Error("BASpark: target element not found");this.canvas=document.createElement("canvas"),this.canvas.id="baspark-canvas",this.canvas.style.cssText=`
2
+ position: fixed;
3
+ left: 0;
4
+ top: 0;
5
+ width: 100%;
6
+ height: 100%;
7
+ pointer-events: none;
8
+ z-index: ${e.zIndex??O};
9
+ `,i.appendChild(this.canvas),this.spark=new w(this.canvas,{color:e.color,scale:e.scale,opacity:e.opacity,trailSpeed:e.trailSpeed,clickSpeed:e.clickSpeed,trailWidth:e.trailWidth,sparkSize:e.sparkSize,clickScale:e.clickScale,alwaysTrail:e.alwaysTrail}),this.boundHandlers={mouseDown:a=>{this.spark.handleDown(a.clientX,a.clientY)},mouseMove:a=>{this.spark.handleMove(a.clientX,a.clientY)},mouseUp:()=>{this.spark.handleUp()},touchStart:a=>{let s=a.touches[0];this.spark.setInputContext("touch",!1),this.spark.handleDown(s.clientX,s.clientY)},touchMove:a=>{let s=a.touches[0];this.spark.handleMove(s.clientX,s.clientY)},touchEnd:()=>{this.spark.setInputContext("mouse",!1),this.spark.handleUp()},resize:()=>{this.spark.resize()}},this.autoTrack&&this.bindEvents()}bindEvents(){window.addEventListener("mousedown",this.boundHandlers.mouseDown),window.addEventListener("mousemove",this.boundHandlers.mouseMove),window.addEventListener("mouseup",this.boundHandlers.mouseUp),window.addEventListener("touchstart",this.boundHandlers.touchStart,{passive:!0}),window.addEventListener("touchmove",this.boundHandlers.touchMove,{passive:!0}),window.addEventListener("touchend",this.boundHandlers.touchEnd),window.addEventListener("resize",this.boundHandlers.resize)}unbindEvents(){window.removeEventListener("mousedown",this.boundHandlers.mouseDown),window.removeEventListener("mousemove",this.boundHandlers.mouseMove),window.removeEventListener("mouseup",this.boundHandlers.mouseUp),window.removeEventListener("touchstart",this.boundHandlers.touchStart),window.removeEventListener("touchmove",this.boundHandlers.touchMove),window.removeEventListener("touchend",this.boundHandlers.touchEnd),window.removeEventListener("resize",this.boundHandlers.resize)}boom(t,e){let i=t*window.innerWidth,a=e*window.innerHeight;this.spark.handleDown(i,a)}move(t,e){let i=t*window.innerWidth,a=e*window.innerHeight;this.spark.handleMove(i,a)}up(){this.spark.handleUp()}boomAt(t,e){this.spark.handleDown(t,e)}moveAt(t,e){this.spark.handleMove(t,e)}setColor(t){this.spark.updateColor(t)}setScale(t){let e=this.spark;e.updateEffectSettings(t,e.opacity,e.trailSpeed,e.clickSpeed)}setOpacity(t){let e=this.spark;e.updateEffectSettings(e.scale,t,e.trailSpeed,e.clickSpeed)}setSpeed(t,e){this.spark.updateEffectSettings(this.spark.scale,this.spark.opacity,t,e??t)}setAlwaysTrail(t){this.spark.setInputContext("mouse",t)}setTrailWidth(t){this.spark.setTrailWidth(t)}setSparkSize(t){this.spark.setSparkSize(t)}setClickScale(t){this.spark.setClickScale(t)}updateOptions(t){t.color!==void 0&&this.setColor(t.color),t.scale!==void 0&&this.setScale(t.scale),t.opacity!==void 0&&this.setOpacity(t.opacity),t.trailSpeed!==void 0&&this.setSpeed(t.trailSpeed,t.clickSpeed),t.trailWidth!==void 0&&this.setTrailWidth(t.trailWidth),t.sparkSize!==void 0&&this.setSparkSize(t.sparkSize),t.clickScale!==void 0&&this.setClickScale(t.clickScale),t.alwaysTrail!==void 0&&this.setAlwaysTrail(t.alwaysTrail),t.autoTrack!==void 0&&t.autoTrack!==this.autoTrack&&(this.autoTrack=t.autoTrack,this.autoTrack?this.bindEvents():this.unbindEvents())}destroy(){this.unbindEvents(),this.spark.destroy(),this.canvas.remove()}};export{W as BASpark,w as MouseSpark};
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/constants.ts","../src/core/MouseSpark.ts","../src/BASpark.ts"],"sourcesContent":["import type { FilledCircleConfig, RingsAnimConfig, CreateClickConfig } from './types'\n\nexport const FILLED_CIRCLE_CFG: FilledCircleConfig = {\n rAddRate: 26,\n maxLife: 16,\n}\n\nexport const RINGS_ANIM_CFG: RingsAnimConfig = {\n rsList: [0, 0.08, 0.1],\n rRoundRateList: [0, 1, 1.5, 2],\n len: 1.1 * Math.PI,\n maxLife: 23,\n segNum: 10,\n minW: 0.4,\n maxW: 3.3,\n lenStopAddPoint: 0.1,\n lenStartDimPoint: 0.4,\n}\n\nexport const CREATE_CLICK_CFG: CreateClickConfig = {\n rings: {\n rsList: [0, 0.03, 0.06],\n rRoundRateList: [0, 1, 1.5, 2],\n len: 1.1 * Math.PI,\n },\n sparksCount: 4,\n}\n\nexport const DEFAULT_COLOR = '45,175,255'\nexport const DEFAULT_SCALE = 1.5\nexport const DEFAULT_OPACITY = 1.0\nexport const DEFAULT_SPEED = 1.0\nexport const DEFAULT_Z_INDEX = 2147483647\nexport const BASE_FRAME_MS = 1000 / 60\nexport const MAX_DELTA_MS = 100\n","import type { Spark, Wave, TrailPoint, Point, Rect, InputMode } from './types'\nimport {\n FILLED_CIRCLE_CFG,\n RINGS_ANIM_CFG,\n CREATE_CLICK_CFG,\n DEFAULT_COLOR,\n DEFAULT_SCALE,\n DEFAULT_OPACITY,\n DEFAULT_SPEED,\n BASE_FRAME_MS,\n MAX_DELTA_MS,\n} from './constants'\n\nfunction ringsEndColorFromRgb(rgbString: string): [number, number, number] {\n const [r, g, b] = rgbString.split(',').map(Number)\n return [\n Math.round((r + 255 * 2) / 3),\n Math.round((g + 255 * 2) / 3),\n Math.round((b + 255 * 2) / 3),\n ]\n}\n\nfunction dist(a: Point, b: Point): number {\n return Math.hypot(a.x - b.x, a.y - b.y)\n}\n\nexport interface MouseSparkOptions {\n color?: string\n scale?: number\n opacity?: number\n trailSpeed?: number\n clickSpeed?: number\n trailWidth?: number\n sparkSize?: number\n clickScale?: number\n maxTrail?: number\n alwaysTrail?: boolean\n}\n\nexport class MouseSpark {\n color: string\n scale: number\n opacity: number\n trailSpeed: number\n clickSpeed: number\n trailWidth: number\n sparkSize: number\n clickScale: number\n maxTrail: number\n\n private sparksPool: Spark[] = []\n private wavesPool: Wave[] = []\n private waves: Wave[] = []\n private sparks: Spark[] = []\n private trail: TrailPoint[] = []\n isDown = false\n private lastPos: Point | null = null\n private lastFrameTime = performance.now()\n private dpr = 1\n private cssWidth = 1\n private cssHeight = 1\n private previousDirtyRects: Rect[] = []\n private forceFullRedraw = true\n\n private ringsStartColor: [number, number, number] = [250, 252, 252]\n private ringsEndColor: [number, number, number]\n\n private mainCanvas!: HTMLCanvasElement\n private mainCtx!: CanvasRenderingContext2D\n private bufferCanvas!: HTMLCanvasElement\n private bufferCtx!: CanvasRenderingContext2D\n\n private animFrameId = 0\n private inputMode: InputMode = 'mouse'\n private alwaysTrailEnabled = false\n readonly effectiveAlwaysTrail: boolean = false\n\n constructor(canvas: HTMLCanvasElement, opts: MouseSparkOptions = {}) {\n this.color = opts.color ?? DEFAULT_COLOR\n this.scale = opts.scale ?? DEFAULT_SCALE\n this.opacity = opts.opacity ?? DEFAULT_OPACITY\n this.trailSpeed = opts.trailSpeed ?? DEFAULT_SPEED\n this.clickSpeed = opts.clickSpeed ?? DEFAULT_SPEED\n this.trailWidth = opts.trailWidth ?? 1\n this.sparkSize = opts.sparkSize ?? 1\n this.clickScale = opts.clickScale ?? 1\n this.maxTrail = opts.maxTrail ?? 16\n this.alwaysTrailEnabled = opts.alwaysTrail ?? false\n\n this.ringsEndColor = ringsEndColorFromRgb(this.color)\n\n this.initCanvas(canvas)\n this.animFrameId = requestAnimationFrame((now) => this.animationLoops(now))\n }\n\n private initCanvas(canvas: HTMLCanvasElement): void {\n this.mainCanvas = canvas\n this.mainCtx = canvas.getContext('2d')!\n\n this.bufferCanvas = document.createElement('canvas')\n this.bufferCtx = this.bufferCanvas.getContext('2d')!\n\n this.resize()\n }\n\n resize(): void {\n const dpr = window.devicePixelRatio || 1\n const cssWidth = Math.max(1, window.innerWidth)\n const cssHeight = Math.max(1, window.innerHeight)\n const w = Math.max(1, Math.floor(cssWidth * dpr))\n const h = Math.max(1, Math.floor(cssHeight * dpr))\n\n this.dpr = dpr\n this.cssWidth = cssWidth\n this.cssHeight = cssHeight\n this.mainCanvas.width = w\n this.mainCanvas.height = h\n this.bufferCanvas.width = w\n this.bufferCanvas.height = h\n this.previousDirtyRects = []\n this.forceFullRedraw = true\n\n this.bufferCtx.setTransform(dpr, 0, 0, dpr, 0, 0)\n }\n\n setInputContext(mode: InputMode, alwaysTrail: boolean): void {\n this.inputMode = mode === 'touch' ? 'touch' : 'mouse'\n this.alwaysTrailEnabled = Boolean(alwaysTrail)\n ;(this as any).effectiveAlwaysTrail = this.inputMode === 'mouse' && this.alwaysTrailEnabled\n }\n\n updateColor(rgbString: string): void {\n this.color = rgbString\n this.ringsEndColor = ringsEndColorFromRgb(rgbString)\n }\n\n setTrailWidth(v: number): void {\n this.trailWidth = Math.max(0.25, Math.min(4, Number(v) || 1))\n }\n\n setSparkSize(v: number): void {\n this.sparkSize = Math.max(0.25, Math.min(4, Number(v) || 1))\n }\n\n setClickScale(v: number): void {\n this.clickScale = Math.max(0.25, Math.min(4, Number(v) || 1))\n }\n\n updateEffectSettings(scale: number, opacity: number, trailSpeed: number, clickSpeed: number): void {\n this.scale = Math.max(0.5, Math.min(3, Number(scale) || DEFAULT_SCALE))\n this.opacity = Math.max(0.1, Math.min(1, Number(opacity) || DEFAULT_OPACITY))\n let t = Number(trailSpeed)\n if (!Number.isFinite(t)) t = DEFAULT_SPEED\n let c = Number(clickSpeed)\n if (!Number.isFinite(c)) c = t\n this.trailSpeed = Math.max(0.2, Math.min(3, t))\n this.clickSpeed = Math.max(0.2, Math.min(3, c))\n }\n\n handleDown(x: number, y: number): void {\n this.isDown = true\n this.lastPos = { x, y }\n this.createEffects(x, y)\n }\n\n handleMove(x: number, y: number): void {\n if (!this.isDown && !(this.inputMode === 'mouse' && this.alwaysTrailEnabled)) return\n const prev = this.lastPos\n if (!prev) {\n this.lastPos = { x, y }\n return\n }\n if (dist({ x, y }, prev) > 2) {\n this.trail.push({ x, y, life: 1 })\n if (this.trail.length > this.maxTrail) this.trail.shift()\n\n if (Math.random() < 0.3) {\n const a = Math.random() * Math.PI * 2\n const speedAdjust = this.scale / 1.5\n this.sparks.push({\n x: x + Math.cos(a) * 10 * this.scale,\n y: y + Math.sin(a) * 10 * this.scale,\n vx: Math.cos(a) * 1.3 * speedAdjust,\n vy: Math.sin(a) * 1.3 * speedAdjust,\n rot: Math.random() * Math.PI * 2,\n rs: 0.16,\n s: 9 * this.scale * this.sparkSize,\n a: 0.7,\n f: 0.95,\n fromClick: false,\n })\n }\n }\n this.lastPos = { x, y }\n }\n\n handleUp(): void {\n this.isDown = false\n }\n\n private alpha(value: number): number {\n return Math.max(0, Math.min(1, value * this.opacity))\n }\n\n private createEffects(x: number, y: number): void {\n const rc = CREATE_CLICK_CFG.rings\n const sparksCount = CREATE_CLICK_CFG.sparksCount\n\n let wave: Wave\n if (this.wavesPool.length > 0) {\n wave = this.wavesPool.pop()!\n } else {\n wave = { ring: { segs: [] } } as unknown as Wave\n }\n if (!wave.ring) wave.ring = { segs: [] } as any\n\n wave.x = x\n wave.y = y\n wave.r = 0\n wave.life = 0\n wave.ring.ang = Math.random() * Math.PI * 2\n wave.ring.rs = rc.rsList[Math.floor(Math.random() * rc.rsList.length)]\n wave.ring.segs[0] = {\n off: 0,\n len: rc.len,\n rRoundRate: rc.rRoundRateList[Math.floor(Math.random() * rc.rRoundRateList.length)],\n }\n wave.ring.segs[1] = {\n off: (Math.random() * 3 - 1.5) * Math.PI,\n len: rc.len,\n rRoundRate: rc.rRoundRateList[Math.floor(Math.random() * rc.rRoundRateList.length)],\n }\n\n this.waves.push(wave)\n\n const speedAdjust = this.scale / 1.5\n for (let i = 0; i < sparksCount; i++) {\n const a = Math.random() * Math.PI * 2\n const speed = (4.8 + Math.random() * 2) * speedAdjust\n\n let spark: Spark\n if (this.sparksPool.length > 0) {\n spark = this.sparksPool.pop()!\n } else {\n spark = {} as Spark\n }\n\n spark.x = x\n spark.y = y\n spark.vx = Math.cos(a) * speed\n spark.vy = Math.sin(a) * speed\n spark.rot = Math.random() * Math.PI * 2\n spark.rs = (Math.random() - 0.5) * 0.28\n spark.s = (4 + Math.random() * 3) * this.scale * this.sparkSize\n spark.a = 1\n spark.f = 0.9\n spark.fromClick = true\n this.sparks.push(spark)\n }\n }\n\n private clearBuffer(rect?: Rect): void {\n const ctx = this.bufferCtx\n if (rect) {\n ctx.clearRect(rect.x, rect.y, rect.w, rect.h)\n } else {\n ctx.clearRect(0, 0, this.cssWidth, this.cssHeight)\n }\n }\n\n private clearBufferRects(rects: Rect[]): void {\n if (!rects || rects.length === 0) return\n for (const rect of rects) {\n this.clearBuffer(rect)\n }\n }\n\n private updateTrail(frameScale: number): void {\n const ctx = this.bufferCtx\n const n = this.trail.length\n let baseDecay: number\n if (this.inputMode === 'mouse' && this.alwaysTrailEnabled) {\n baseDecay = 0.085 * frameScale\n } else {\n baseDecay = (this.isDown ? 0.085 : 0.18) * frameScale\n }\n const maxStep = 0.42\n for (let i = n - 1; i >= 0; i--) {\n const t = this.trail[i]\n const span = Math.max(1, n - 1)\n const along = n > 1 ? i / span : 1\n const towardCursorBias = 1.25 - 0.55 * along\n let step = baseDecay * towardCursorBias\n if (step > maxStep) step = maxStep\n t.life -= step\n if (t.life <= 0) this.trail.splice(i, 1)\n }\n\n const head = this.lastPos\n const pts: TrailPoint[] =\n head && this.trail.length > 0\n ? this.trail.concat([{ x: head.x, y: head.y, life: 1 }])\n : this.trail.slice()\n\n if (pts.length < 2) return\n\n const gap = Math.hypot(\n pts[pts.length - 1].x - pts[pts.length - 2].x,\n pts[pts.length - 1].y - pts[pts.length - 2].y,\n )\n if (gap < 0.75 && this.trail.length === 1) {\n const fade = Math.max(0, this.trail[0].life)\n ctx.shadowColor = 'transparent'\n const dotSize = (2.5 + 2 * fade) * (this.scale / 1.5) * this.trailWidth\n ctx.beginPath()\n ctx.arc(pts[0].x, pts[0].y, dotSize, 0, Math.PI * 2)\n ctx.fillStyle = `rgba(${this.color}, ${fade * 0.85})`\n ctx.fill()\n return\n }\n\n const numPts = pts.length\n const lastIdx = numPts - 1\n const baseWidth = 8 * (this.scale / 1.5) * this.trailWidth\n\n const lancetWidth = (progress: number): number => {\n if (progress < 0.65) return Math.pow(progress / 0.65, 0.6)\n return Math.pow((1 - progress) / 0.35, 1.8)\n }\n\n // 构建填充多边形的左右边缘点\n const leftEdge: Array<{ x: number; y: number }> = []\n const rightEdge: Array<{ x: number; y: number }> = []\n\n for (let i = 0; i < numPts; i++) {\n const progress = i / lastIdx\n const hw = Math.max(0.25, baseWidth * lancetWidth(progress)) / 2\n\n let dx: number, dy: number\n if (i === 0) {\n dx = pts[1].x - pts[0].x\n dy = pts[1].y - pts[0].y\n } else if (i === lastIdx) {\n dx = pts[i].x - pts[i - 1].x\n dy = pts[i].y - pts[i - 1].y\n } else {\n dx = pts[i + 1].x - pts[i - 1].x\n dy = pts[i + 1].y - pts[i - 1].y\n }\n let len = Math.hypot(dx, dy)\n if (len < 0.001) {\n dx = 0\n dy = 1\n len = 1\n }\n const nx = -dy / len\n const ny = dx / len\n\n leftEdge.push({ x: pts[i].x + nx * hw, y: pts[i].y + ny * hw })\n rightEdge.push({ x: pts[i].x - nx * hw, y: pts[i].y - ny * hw })\n }\n\n // 绘制填充多边形\n ctx.shadowColor = `rgba(${this.color}, 0.6)`\n ctx.shadowBlur = 3\n ctx.shadowOffsetX = 0\n ctx.shadowOffsetY = 0\n\n ctx.beginPath()\n ctx.moveTo(leftEdge[0].x, leftEdge[0].y)\n for (let i = 1; i < numPts; i++) {\n ctx.lineTo(leftEdge[i].x, leftEdge[i].y)\n }\n for (let i = numPts - 1; i >= 0; i--) {\n ctx.lineTo(rightEdge[i].x, rightEdge[i].y)\n }\n ctx.closePath()\n\n const grad = ctx.createLinearGradient(\n pts[0].x, pts[0].y, pts[lastIdx].x, pts[lastIdx].y,\n )\n grad.addColorStop(0, `rgba(${this.color}, 0)`)\n grad.addColorStop(1, `rgba(${this.color}, 1)`)\n\n ctx.fillStyle = grad\n ctx.fill()\n\n ctx.shadowColor = 'transparent'\n }\n\n private strokeRingSegment(\n wx: number, wy: number, radius: number,\n a0: number, a1: number, lineWidth: number, strokeStyle: string,\n ): void {\n const ctx = this.bufferCtx\n ctx.beginPath()\n ctx.arc(wx, wy, radius, a0, a1)\n ctx.lineWidth = lineWidth\n ctx.strokeStyle = strokeStyle\n ctx.stroke()\n }\n\n private updateWaves(clickFrameScale: number): void {\n const filled = FILLED_CIRCLE_CFG\n const rings = RINGS_ANIM_CFG\n const ctx = this.bufferCtx\n\n for (let i = this.waves.length - 1; i >= 0; i--) {\n const w = this.waves[i]\n const waveProg = Math.min(w.life / filled.maxLife, 1)\n const ringProg = Math.min(w.life / rings.maxLife, 1)\n\n // filled circle\n {\n w.life += clickFrameScale\n const ease = 1 - Math.pow(1 - waveProg, 3)\n w.r = filled.rAddRate * this.scale * this.clickScale * ease\n const alpha = Math.max(0, 1 - waveProg)\n if (alpha > 0) {\n ctx.beginPath()\n ctx.arc(w.x, w.y, w.r, 0, Math.PI * 2)\n ctx.fillStyle = `rgba(${this.color},${this.alpha(alpha)})`\n ctx.fill()\n }\n }\n\n // rings\n {\n const getWeightProp = (t: number) => Math.min(2 - Math.abs(4 * (t - 0.5)), 1)\n\n const getAlpha = (rProg: number) => Math.min(1.1 - 0.3 * rProg, 1)\n\n const r = w.ring\n r.ang -= r.rs * clickFrameScale\n\n const ringRgbAt = (rProg: number): [number, number, number] => {\n const t = Math.min(1.2 * rProg, 1)\n return [\n Math.round(this.ringsStartColor[0] * (1 - t) + this.ringsEndColor[0] * t),\n Math.round(this.ringsStartColor[1] * (1 - t) + this.ringsEndColor[1] * t),\n Math.round(this.ringsStartColor[2] * (1 - t) + this.ringsEndColor[2] * t),\n ]\n }\n\n let start = 0\n let end = 0\n let len = 0\n let seg: { off: number; len: number; rRoundRate: number }\n\n for (let j = 0; j < 2; j++) {\n seg = r.segs[j]\n const base = r.ang + seg.off\n\n if (ringProg <= rings.lenStopAddPoint) {\n len = seg.len * (ringProg / rings.lenStopAddPoint)\n end = base + seg.len\n start = end - len\n } else if (ringProg > rings.lenStartDimPoint) {\n len = seg.len * (1 - (ringProg - rings.lenStartDimPoint) / (1 - rings.lenStartDimPoint))\n start = base\n end = start + len\n } else {\n len = seg.len\n start = base\n end = start + len\n }\n\n const lineWidthMul = Math.min(-0.8 * (ringProg - 0.8) + 1, 1)\n const [rr, gg, bb] = ringRgbAt(ringProg)\n const alphaRing = getAlpha(ringProg)\n\n for (let k = 0; k < rings.segNum; k++) {\n const t0 = k / rings.segNum\n const t1 = (k + 1) / rings.segNum\n const a0 = start + (end - start) * t0\n const a1 = start + (end - start) * t1\n\n if (Math.abs(a1 - a0) < 0.01) continue\n\n const wT = getWeightProp(t0)\n const lw = (rings.minW * (1 - wT) + rings.maxW * wT) * lineWidthMul\n const strokeStyle = `rgba(${rr},${gg},${bb},${alphaRing})`\n const radius = w.r + seg.rRoundRate * this.scale * this.clickScale\n this.strokeRingSegment(w.x, w.y, radius, a0, a1, lw, strokeStyle)\n }\n }\n }\n\n if (ringProg >= 1 && waveProg >= 1) {\n this.wavesPool.push(this.waves[i])\n this.waves.splice(i, 1)\n }\n }\n }\n\n private updateSparks(clickFrameScale: number, trailFrameScale: number): void {\n const ctx = this.bufferCtx\n for (let i = this.sparks.length - 1; i >= 0; i--) {\n const s = this.sparks[i]\n const fs = s.fromClick ? clickFrameScale : trailFrameScale\n s.x += s.vx * fs\n s.y += s.vy * fs\n s.vx *= Math.pow(s.f, fs)\n s.vy *= Math.pow(s.f, fs)\n s.rot += s.rs * fs\n s.a -= 0.032 * fs\n if (s.a <= 0) {\n this.sparksPool.push(this.sparks[i])\n this.sparks.splice(i, 1)\n continue\n }\n\n ctx.save()\n ctx.translate(s.x, s.y)\n ctx.rotate(s.rot)\n ctx.beginPath()\n ctx.moveTo(0, -s.s)\n ctx.lineTo(s.s * 0.6, s.s * 0.6)\n ctx.lineTo(-s.s * 0.6, s.s * 0.6)\n ctx.fillStyle = `rgba(255,255,255,${this.alpha(s.a)})`\n ctx.fill()\n ctx.restore()\n }\n }\n\n private canvasRect(): Rect {\n return { x: 0, y: 0, w: this.cssWidth, h: this.cssHeight }\n }\n\n private clipRect(rect: Rect): Rect | null {\n if (!rect) return null\n const x0 = Math.max(0, Math.floor(rect.x))\n const y0 = Math.max(0, Math.floor(rect.y))\n const x1 = Math.min(this.cssWidth, Math.ceil(rect.x + rect.w))\n const y1 = Math.min(this.cssHeight, Math.ceil(rect.y + rect.h))\n if (x1 <= x0 || y1 <= y0) return null\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n }\n\n private pointRect(x: number, y: number, padding: number): Rect {\n return { x: x - padding, y: y - padding, w: padding * 2, h: padding * 2 }\n }\n\n private segmentRect(a: Point, b: Point, padding: number): Rect {\n const x0 = Math.min(a.x, b.x) - padding\n const y0 = Math.min(a.y, b.y) - padding\n const x1 = Math.max(a.x, b.x) + padding\n const y1 = Math.max(a.y, b.y) + padding\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n }\n\n private intersects(a: Rect, b: Rect): boolean {\n return (\n a.x <= b.x + b.w &&\n a.x + a.w >= b.x &&\n a.y <= b.y + b.h &&\n a.y + a.h >= b.y\n )\n }\n\n private unionRect(a: Rect, b: Rect): Rect {\n const x0 = Math.min(a.x, b.x)\n const y0 = Math.min(a.y, b.y)\n const x1 = Math.max(a.x + a.w, b.x + b.w)\n const y1 = Math.max(a.y + a.h, b.y + b.h)\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 }\n }\n\n private mergeRects(rects: Rect[]): Rect[] {\n const merged: Rect[] = []\n for (const raw of rects) {\n let rect = this.clipRect(raw)\n if (!rect) continue\n\n for (let i = 0; i < merged.length; i++) {\n if (this.intersects(merged[i], rect)) {\n rect = this.unionRect(merged[i], rect)\n merged.splice(i, 1)\n i = -1\n }\n }\n\n merged.push(rect)\n }\n return merged\n }\n\n private getEffectRects(): Rect[] {\n const rects: Rect[] = []\n const trailPad = 18 * this.scale * this.trailWidth + 12\n\n const trailPoints: TrailPoint[] =\n this.lastPos && this.trail.length > 0\n ? this.trail.concat([{ x: this.lastPos.x, y: this.lastPos.y, life: 1 }])\n : this.trail\n\n if (trailPoints.length === 1) {\n rects.push(this.pointRect(trailPoints[0].x, trailPoints[0].y, trailPad))\n } else {\n for (let i = 0; i < trailPoints.length - 1; i++) {\n rects.push(this.segmentRect(trailPoints[i], trailPoints[i + 1], trailPad))\n }\n }\n\n const wavePad = 34 * this.scale * this.clickScale + RINGS_ANIM_CFG.maxW + 16\n for (const wave of this.waves) {\n const radius = Math.max(wave.r || 0, FILLED_CIRCLE_CFG.rAddRate * this.scale * this.clickScale) + wavePad\n rects.push(this.pointRect(wave.x, wave.y, radius))\n }\n\n const maxFrameScale = MAX_DELTA_MS / BASE_FRAME_MS\n for (const spark of this.sparks) {\n const speed = Math.hypot(spark.vx || 0, spark.vy || 0)\n const speedScale = spark.fromClick ? this.clickSpeed : this.trailSpeed\n const motionPad = speed * maxFrameScale * speedScale\n const sparkPad = Math.max(spark.s || 0, 9 * this.scale * this.sparkSize) * 2 + motionPad + 12\n rects.push(this.pointRect(spark.x, spark.y, sparkPad))\n }\n\n return this.mergeRects(rects)\n }\n\n private getRenderRects(): Rect[] {\n if (this.forceFullRedraw) {\n return [this.canvasRect()]\n }\n return this.mergeRects(this.previousDirtyRects.concat(this.getEffectRects()))\n }\n\n private clipToRects(ctx: CanvasRenderingContext2D, rects: Rect[]): void {\n ctx.beginPath()\n for (const rect of rects) {\n ctx.rect(rect.x, rect.y, rect.w, rect.h)\n }\n ctx.clip()\n }\n\n private renderToMain(rects: Rect[]): void {\n const { mainCtx, mainCanvas, bufferCanvas } = this\n if (!rects || rects.length === 0) {\n mainCtx.clearRect(0, 0, mainCanvas.width, mainCanvas.height)\n mainCtx.drawImage(bufferCanvas, 0, 0)\n return\n }\n\n const dpr = this.dpr || 1\n for (const rect of rects) {\n const sx = Math.max(0, Math.floor(rect.x * dpr))\n const sy = Math.max(0, Math.floor(rect.y * dpr))\n const sw = Math.min(mainCanvas.width - sx, Math.ceil(rect.w * dpr))\n const sh = Math.min(mainCanvas.height - sy, Math.ceil(rect.h * dpr))\n if (sw <= 0 || sh <= 0) continue\n\n mainCtx.clearRect(sx, sy, sw, sh)\n mainCtx.drawImage(bufferCanvas, sx, sy, sw, sh, sx, sy, sw, sh)\n }\n }\n\n private animationLoops(now: number): void {\n const hasWork =\n this.waves.length > 0 ||\n this.sparks.length > 0 ||\n this.trail.length > 0\n\n if (!hasWork) {\n this.lastFrameTime = now\n if (this.previousDirtyRects.length > 0) {\n this.clearBufferRects(this.previousDirtyRects)\n this.renderToMain(this.previousDirtyRects)\n this.previousDirtyRects = []\n }\n this.animFrameId = requestAnimationFrame((nextNow) => this.animationLoops(nextNow))\n return\n }\n\n const deltaMs = Math.min(now - this.lastFrameTime, MAX_DELTA_MS)\n this.lastFrameTime = now\n const baseScale = deltaMs / BASE_FRAME_MS\n const trailFrameScale = baseScale * this.trailSpeed\n const clickFrameScale = baseScale * this.clickSpeed\n\n const bctx = this.bufferCtx\n const renderRects = this.getRenderRects()\n\n bctx.save()\n this.clipToRects(bctx, renderRects)\n bctx.globalCompositeOperation = 'lighter'\n\n this.clearBufferRects(renderRects)\n this.updateTrail(trailFrameScale)\n this.updateWaves(clickFrameScale)\n this.updateSparks(clickFrameScale, trailFrameScale)\n\n bctx.globalCompositeOperation = 'source-over'\n bctx.restore()\n\n this.renderToMain(renderRects)\n this.previousDirtyRects = this.getEffectRects()\n this.forceFullRedraw = false\n\n this.animFrameId = requestAnimationFrame((nextNow) => this.animationLoops(nextNow))\n }\n\n destroy(): void {\n cancelAnimationFrame(this.animFrameId)\n this.waves.length = 0\n this.sparks.length = 0\n this.trail.length = 0\n this.sparksPool.length = 0\n this.wavesPool.length = 0\n this.previousDirtyRects = []\n const ctx = this.mainCtx\n ctx.clearRect(0, 0, this.mainCanvas.width, this.mainCanvas.height)\n }\n}\n","import { MouseSpark } from './core/MouseSpark'\nimport type { BASparkOptions } from './core/types'\nimport { DEFAULT_Z_INDEX } from './core/constants'\n\nexport class BASpark {\n private canvas: HTMLCanvasElement\n private spark: MouseSpark\n private autoTrack: boolean\n private boundHandlers: {\n mouseDown: (e: MouseEvent) => void\n mouseMove: (e: MouseEvent) => void\n mouseUp: (e: MouseEvent) => void\n touchStart: (e: TouchEvent) => void\n touchMove: (e: TouchEvent) => void\n touchEnd: (e: TouchEvent) => void\n resize: () => void\n }\n\n constructor(element: HTMLElement | string, options: BASparkOptions = {}) {\n this.autoTrack = options.autoTrack ?? true\n\n const target = typeof element === 'string'\n ? document.querySelector<HTMLElement>(element)\n : element\n if (!target) throw new Error('BASpark: target element not found')\n\n this.canvas = document.createElement('canvas')\n this.canvas.id = 'baspark-canvas'\n this.canvas.style.cssText = `\n position: fixed;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: ${options.zIndex ?? DEFAULT_Z_INDEX};\n `\n target.appendChild(this.canvas)\n\n this.spark = new MouseSpark(this.canvas, {\n color: options.color,\n scale: options.scale,\n opacity: options.opacity,\n trailSpeed: options.trailSpeed,\n clickSpeed: options.clickSpeed,\n trailWidth: options.trailWidth,\n sparkSize: options.sparkSize,\n clickScale: options.clickScale,\n alwaysTrail: options.alwaysTrail,\n })\n\n this.boundHandlers = {\n mouseDown: (e: MouseEvent) => {\n this.spark.handleDown(e.clientX, e.clientY)\n },\n mouseMove: (e: MouseEvent) => {\n this.spark.handleMove(e.clientX, e.clientY)\n },\n mouseUp: () => {\n this.spark.handleUp()\n },\n touchStart: (e: TouchEvent) => {\n const t = e.touches[0]\n this.spark.setInputContext('touch', false)\n this.spark.handleDown(t.clientX, t.clientY)\n },\n touchMove: (e: TouchEvent) => {\n const t = e.touches[0]\n this.spark.handleMove(t.clientX, t.clientY)\n },\n touchEnd: () => {\n this.spark.setInputContext('mouse', false)\n this.spark.handleUp()\n },\n resize: () => {\n this.spark.resize()\n },\n }\n\n if (this.autoTrack) {\n this.bindEvents()\n }\n }\n\n private bindEvents(): void {\n window.addEventListener('mousedown', this.boundHandlers.mouseDown)\n window.addEventListener('mousemove', this.boundHandlers.mouseMove)\n window.addEventListener('mouseup', this.boundHandlers.mouseUp)\n window.addEventListener('touchstart', this.boundHandlers.touchStart, { passive: true })\n window.addEventListener('touchmove', this.boundHandlers.touchMove, { passive: true })\n window.addEventListener('touchend', this.boundHandlers.touchEnd)\n window.addEventListener('resize', this.boundHandlers.resize)\n }\n\n private unbindEvents(): void {\n window.removeEventListener('mousedown', this.boundHandlers.mouseDown)\n window.removeEventListener('mousemove', this.boundHandlers.mouseMove)\n window.removeEventListener('mouseup', this.boundHandlers.mouseUp)\n window.removeEventListener('touchstart', this.boundHandlers.touchStart)\n window.removeEventListener('touchmove', this.boundHandlers.touchMove)\n window.removeEventListener('touchend', this.boundHandlers.touchEnd)\n window.removeEventListener('resize', this.boundHandlers.resize)\n }\n\n boom(xPercent: number, yPercent: number): void {\n const cx = xPercent * window.innerWidth\n const cy = yPercent * window.innerHeight\n this.spark.handleDown(cx, cy)\n }\n\n move(xPercent: number, yPercent: number): void {\n const cx = xPercent * window.innerWidth\n const cy = yPercent * window.innerHeight\n this.spark.handleMove(cx, cy)\n }\n\n up(): void {\n this.spark.handleUp()\n }\n\n boomAt(x: number, y: number): void {\n this.spark.handleDown(x, y)\n }\n\n moveAt(x: number, y: number): void {\n this.spark.handleMove(x, y)\n }\n\n setColor(rgb: string): void {\n this.spark.updateColor(rgb)\n }\n\n setScale(scale: number): void {\n const s = this.spark\n s.updateEffectSettings(scale, s.opacity, s.trailSpeed, s.clickSpeed)\n }\n\n setOpacity(opacity: number): void {\n const s = this.spark\n s.updateEffectSettings(s.scale, opacity, s.trailSpeed, s.clickSpeed)\n }\n\n setSpeed(trailSpeed: number, clickSpeed?: number): void {\n this.spark.updateEffectSettings(\n this.spark.scale,\n this.spark.opacity,\n trailSpeed,\n clickSpeed ?? trailSpeed,\n )\n }\n\n setAlwaysTrail(enabled: boolean): void {\n this.spark.setInputContext('mouse', enabled)\n }\n\n setTrailWidth(v: number): void {\n this.spark.setTrailWidth(v)\n }\n\n setSparkSize(v: number): void {\n this.spark.setSparkSize(v)\n }\n\n setClickScale(v: number): void {\n this.spark.setClickScale(v)\n }\n\n updateOptions(options: BASparkOptions): void {\n if (options.color !== undefined) this.setColor(options.color)\n if (options.scale !== undefined) this.setScale(options.scale)\n if (options.opacity !== undefined) this.setOpacity(options.opacity)\n if (options.trailSpeed !== undefined) {\n this.setSpeed(options.trailSpeed, options.clickSpeed)\n }\n if (options.trailWidth !== undefined) this.setTrailWidth(options.trailWidth)\n if (options.sparkSize !== undefined) this.setSparkSize(options.sparkSize)\n if (options.clickScale !== undefined) this.setClickScale(options.clickScale)\n if (options.alwaysTrail !== undefined) this.setAlwaysTrail(options.alwaysTrail)\n if (options.autoTrack !== undefined && options.autoTrack !== this.autoTrack) {\n this.autoTrack = options.autoTrack\n if (this.autoTrack) {\n this.bindEvents()\n } else {\n this.unbindEvents()\n }\n }\n }\n\n destroy(): void {\n this.unbindEvents()\n this.spark.destroy()\n this.canvas.remove()\n }\n}\n"],"mappings":"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","names":["FILLED_CIRCLE_CFG","RINGS_ANIM_CFG","CREATE_CLICK_CFG","DEFAULT_COLOR","DEFAULT_SCALE","DEFAULT_OPACITY","DEFAULT_SPEED","DEFAULT_Z_INDEX","BASE_FRAME_MS","MAX_DELTA_MS","ringsEndColorFromRgb","rgbString","r","g","b","dist","a","MouseSpark","canvas","opts","DEFAULT_COLOR","DEFAULT_SCALE","DEFAULT_OPACITY","DEFAULT_SPEED","now","dpr","cssWidth","cssHeight","w","h","mode","alwaysTrail","v","scale","opacity","trailSpeed","clickSpeed","t","c","x","y","prev","speedAdjust","value","rc","CREATE_CLICK_CFG","sparksCount","wave","i","speed","spark","rect","ctx","rects","frameScale","n","baseDecay","maxStep","span","towardCursorBias","step","head","pts","fade","dotSize","numPts","lastIdx","baseWidth","lancetWidth","progress","leftEdge","rightEdge","hw","dx","dy","len","nx","ny","grad","wx","wy","radius","a0","a1","lineWidth","strokeStyle","clickFrameScale","filled","FILLED_CIRCLE_CFG","rings","RINGS_ANIM_CFG","waveProg","ringProg","ease","alpha","getWeightProp","getAlpha","rProg","ringRgbAt","start","end","seg","j","base","lineWidthMul","rr","gg","bb","alphaRing","k","t0","t1","wT","lw","trailFrameScale","fs","x0","y0","x1","y1","padding","merged","raw","trailPad","trailPoints","wavePad","maxFrameScale","MAX_DELTA_MS","BASE_FRAME_MS","speedScale","motionPad","sparkPad","mainCtx","mainCanvas","bufferCanvas","sx","sy","sw","sh","nextNow","deltaMs","baseScale","bctx","renderRects","BASpark","element","options","target","DEFAULT_Z_INDEX","MouseSpark","e","t","xPercent","yPercent","cx","cy","x","y","rgb","scale","s","opacity","trailSpeed","clickSpeed","enabled","v"]}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@cut-shade/baspark",
3
+ "version": "1.6.0",
4
+ "description": "Blue Archive style particle effects — portable web library (Canvas)",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "unpkg": "./dist/index.global.js",
17
+ "jsdelivr": "./dist/index.global.js",
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsup",
23
+ "dev": "tsup --watch",
24
+ "prepublishOnly": "npm run build",
25
+ "prepublish": "npm run build"
26
+ },
27
+ "keywords": [
28
+ "blue-archive",
29
+ "particle-effects",
30
+ "canvas",
31
+ "spark",
32
+ "mouse-trail",
33
+ "click-effect",
34
+ "web"
35
+ ],
36
+ "license": "MIT",
37
+ "author": "BASpark contributors",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/DoomVoss/BASpark.git"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/DoomVoss/BASpark/issues"
44
+ },
45
+ "homepage": "https://github.com/DoomVoss/BASpark",
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "devDependencies": {
50
+ "tsup": "^8.4.0",
51
+ "typescript": "^5.7.0"
52
+ }
53
+ }