particle-canvas-pro 1.3.0 → 1.3.2
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 +3 -0
- package/dist/bundle.cjs.js +1 -1
- package/dist/bundle.esm.js +1 -1
- package/dist/bundle.js +1 -1
- package/dist/types/ParticleCanvas.d.ts +118 -118
- package/dist/types/index.d.ts +5 -5
- package/dist/types/types.d.ts +56 -56
- package/package.json +58 -54
package/README.md
CHANGED
package/dist/bundle.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});class i{constructor(i={}){this.MAX_PARTICLE_NUMBER=800,this.MAX_PARTICLE_SPEED=3,this.MAX_PARTICLE_SIZE=10,this.MAX_LINK_DISTANCE=300,this.MAX_LINE_WIDTH=5,this.MAX_LINE_OPACITY=1,this.MAX_TRAIL_VALUE=1,this.MAX_PARTICLE_BLUR=5,this.MAX_TRAIL_INTENSITY=5;const t=this.validateAndLimitOptions(i);this.config={canvasContainer:t.canvasContainer||document.body,isBackground:void 0===t.isBackground||t.isBackground,canvasBackgroundColor:t.canvasBackgroundColor||"rgb(10, 10, 25)",particleNumber:t.particleNumber||150,particleSpeed:t.particleSpeed||1,particleSize:t.particleSize||5,particleColor:t.particleColor||"rgba(156, 74, 255, 0.6)",particleBlur:void 0!==t.particleBlur?t.particleBlur:2,lineWidth:t.lineWidth||1,lineColor:t.lineColor||"#ffffff",lineOpacity:t.lineOpacity||.3,linkDistance:t.linkDistance||120,showLine:void 0===t.showLine||t.showLine,canvasSize:t.canvasSize||[800,600],showTrail:void 0===t.showTrail||t.showTrail,trailIntensity:t.trailIntensity||2},this.particles=[],this.animationId=null,this.isRunning=!1,this.lastTime=0,this.fps=60,this.fpsInterval=1e3/60,this.then=Date.now(),this.frameCount=0,this.lastFpsUpdate=Date.now(),this.resizeTimer=null,this.wasRunningBeforeHide=!1,this.lastFrameTime=performance.now(),this.init()}validateAndLimitOptions(i){const t=Object.assign({},i);return void 0!==i.particleNumber&&(i.particleNumber>this.MAX_PARTICLE_NUMBER?(console.warn(`Warning: particleNumber (${i.particleNumber}) exceeds maximum allowed value (${this.MAX_PARTICLE_NUMBER}). Using maximum value instead.`),t.particleNumber=this.MAX_PARTICLE_NUMBER):i.particleNumber<1&&(console.warn(`Warning: particleNumber (${i.particleNumber}) is below minimum value (1). Using default value instead.`),t.particleNumber=150)),void 0!==i.particleSpeed&&(i.particleSpeed>this.MAX_PARTICLE_SPEED?(console.warn(`Warning: particleSpeed (${i.particleSpeed}) exceeds maximum allowed value (${this.MAX_PARTICLE_SPEED}). Using maximum value instead.`),t.particleSpeed=this.MAX_PARTICLE_SPEED):i.particleSpeed<0&&(console.warn(`Warning: particleSpeed (${i.particleSpeed}) is below minimum value (0). Using default value instead.`),t.particleSpeed=1)),void 0!==i.particleSize&&(i.particleSize>this.MAX_PARTICLE_SIZE?(console.warn(`Warning: particleSize (${i.particleSize}) exceeds maximum allowed value (${this.MAX_PARTICLE_SIZE}). Using maximum value instead.`),t.particleSize=this.MAX_PARTICLE_SIZE):i.particleSize<1&&(console.warn(`Warning: particleSize (${i.particleSize}) is below minimum value (1). Using default value instead.`),t.particleSize=3)),void 0!==i.particleBlur&&(i.particleBlur>this.MAX_PARTICLE_BLUR?(console.warn(`Warning: particleBlur (${i.particleBlur}) exceeds maximum allowed value (${this.MAX_PARTICLE_BLUR}). Using maximum value instead.`),t.particleBlur=this.MAX_PARTICLE_BLUR):i.particleBlur<0&&(console.warn(`Warning: particleBlur (${i.particleBlur}) is below minimum value (0). Using default value instead.`),t.particleBlur=2)),void 0!==i.linkDistance&&(i.linkDistance>this.MAX_LINK_DISTANCE?(console.warn(`Warning: linkDistance (${i.linkDistance}) exceeds maximum allowed value (${this.MAX_LINK_DISTANCE}). Using maximum value instead.`),t.linkDistance=this.MAX_LINK_DISTANCE):i.linkDistance<10&&(console.warn(`Warning: linkDistance (${i.linkDistance}) is below minimum value (10). Using default value instead.`),t.linkDistance=120)),void 0!==i.lineWidth&&(i.lineWidth>this.MAX_LINE_WIDTH?(console.warn(`Warning: lineWidth (${i.lineWidth}) exceeds maximum allowed value (${this.MAX_LINE_WIDTH}). Using maximum value instead.`),t.lineWidth=this.MAX_LINE_WIDTH):i.lineWidth<0&&(console.warn(`Warning: lineWidth (${i.lineWidth}) is below minimum value (0). Using default value instead.`),t.lineWidth=1)),void 0!==i.lineOpacity&&(i.lineOpacity>this.MAX_LINE_OPACITY?(console.warn(`Warning: lineOpacity (${i.lineOpacity}) exceeds maximum allowed value (${this.MAX_LINE_OPACITY}). Using maximum value instead.`),t.lineOpacity=this.MAX_LINE_OPACITY):i.lineOpacity<0&&(console.warn(`Warning: lineOpacity (${i.lineOpacity}) is below minimum value (0). Using default value instead.`),t.lineOpacity=.3)),void 0!==i.trailIntensity&&(i.trailIntensity>this.MAX_TRAIL_INTENSITY?(console.warn(`Warning: trailIntensity (${i.trailIntensity}) exceeds maximum allowed value (${this.MAX_TRAIL_INTENSITY}). Using maximum value instead.`),t.trailIntensity=this.MAX_TRAIL_INTENSITY):i.trailIntensity<1&&(console.warn(`Warning: trailIntensity (${i.trailIntensity}) is below minimum value (1). Using default value instead.`),t.trailIntensity=2)),t}init(){this.canvas=document.createElement("canvas");const i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get 2D context from canvas");if(this.ctx=i,"string"==typeof this.config.canvasContainer){const i=document.querySelector(this.config.canvasContainer);if(!i)throw new Error(`Canvas container not found: ${this.config.canvasContainer}`);this.container=i}else this.container=this.config.canvasContainer;this.container?(this.container.appendChild(this.canvas),this.setupCanvas(),this.createParticles(),this.bindEvents()):console.error("Canvas container not found")}setupCanvas(){if(this.config.isBackground)this.canvas.style.position="fixed",this.canvas.style.top="0",this.canvas.style.left="0",this.canvas.style.width="100%",this.canvas.style.height="100%",this.canvas.style.zIndex="-1",this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight;else{this.canvas.style.display="block";const[i,t]=this.config.canvasSize;this.canvas.width=i,this.canvas.height=t,this.canvas.style.width=i+"px",this.canvas.style.height=t+"px"}this.canvas.style.pointerEvents="none"}createParticles(){this.particles=[];const i=Array.isArray(this.config.particleColor);for(let t=0;t<this.config.particleNumber;t++){let t;if(i){const i=this.config.particleColor;t=i[Math.floor(Math.random()*i.length)]}else t=this.config.particleColor;this.particles.push({x:Math.random()*this.canvas.width,y:Math.random()*this.canvas.height,vx:2*(Math.random()-.5)*this.config.particleSpeed,vy:2*(Math.random()-.5)*this.config.particleSpeed,size:this.config.particleSize,color:t,originalColor:t,pulse:0,pulseSpeed:.05*Math.random()+.02,trailPositions:[]})}}updateParticles(i){const t=i/16.67;for(const i of this.particles)i.pulse+=i.pulseSpeed*t,i.pulse>2*Math.PI&&(i.pulse=0),this.config.showTrail&&(i.trailPositions.unshift({x:i.x,y:i.y}),i.trailPositions.length>10*this.config.trailIntensity&&(i.trailPositions.length=10*this.config.trailIntensity)),i.x+=i.vx*t,i.y+=i.vy*t,(i.x<0||i.x>this.canvas.width)&&(i.vx*=-1),(i.y<0||i.y>this.canvas.height)&&(i.vy*=-1),i.x=Math.max(0,Math.min(this.canvas.width,i.x)),i.y=Math.max(0,Math.min(this.canvas.height,i.y))}drawTrailEffect(){if(this.config.showTrail){this.ctx.save();for(const i of this.particles){if(i.trailPositions.length<2)continue;this.ctx.beginPath(),this.ctx.moveTo(i.trailPositions[0].x,i.trailPositions[0].y);for(let t=1;t<i.trailPositions.length;t++)this.ctx.lineTo(i.trailPositions[t].x,i.trailPositions[t].y);const t=1.2*i.size;this.ctx.lineWidth=t,this.ctx.lineCap="round",this.ctx.lineJoin="round";const s=i.trailPositions[0],e=i.trailPositions[i.trailPositions.length-1],a=this.ctx.createLinearGradient(s.x,s.y,e.x,e.y),n=this.parseColor(i.color),r=.35;a.addColorStop(0,`rgba(${n.r}, ${n.g}, ${n.b}, ${r})`),a.addColorStop(.3,`rgba(${n.r}, ${n.g}, ${n.b}, ${.6*r})`),a.addColorStop(.7,`rgba(${n.r}, ${n.g}, ${n.b}, ${.2*r})`),a.addColorStop(1,`rgba(${n.r}, ${n.g}, ${n.b}, 0)`),this.ctx.strokeStyle=a,this.ctx.stroke()}this.ctx.restore()}}parseColor(i){if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3]),a:parseFloat(t[4])}}else if(i.startsWith("rgb")){const t=i.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3])}}else if(i.startsWith("#")){let t,s,e,a=i.replace("#","");if(3===a.length)t=parseInt(a[0]+a[0],16),s=parseInt(a[1]+a[1],16),e=parseInt(a[2]+a[2],16);else{if(6!==a.length)return{r:255,g:255,b:255};t=parseInt(a.substring(0,2),16),s=parseInt(a.substring(2,4),16),e=parseInt(a.substring(4,6),16)}return{r:t,g:s,b:e}}return{r:255,g:255,b:255}}drawParticles(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);let i=this.config.canvasBackgroundColor;if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t){const s=t[1],e=t[2],a=t[3];parseFloat(t[4])<1&&(i=`rgb(${s}, ${e}, ${a})`)}}if(this.ctx.fillStyle=i,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.drawTrailEffect(),this.config.showLine)for(let i=0;i<this.particles.length;i++)for(let t=i+1;t<this.particles.length;t++){const s=this.particles[i].x-this.particles[t].x,e=this.particles[i].y-this.particles[t].y,a=Math.sqrt(s*s+e*e);if(a<this.config.linkDistance){const s=this.config.lineOpacity*(1-a/this.config.linkDistance);this.ctx.strokeStyle=this.config.lineColor,this.ctx.globalAlpha=s,this.ctx.lineWidth=this.config.lineWidth,this.ctx.beginPath(),this.ctx.moveTo(this.particles[i].x,this.particles[i].y),this.ctx.lineTo(this.particles[t].x,this.particles[t].y),this.ctx.stroke()}}this.ctx.globalAlpha=1;for(const i of this.particles){const t=i.size*(1+.2*Math.sin(i.pulse));this.config.particleBlur>0&&(this.ctx.shadowColor=i.color,this.ctx.shadowBlur=4*this.config.particleBlur),this.ctx.beginPath(),this.ctx.arc(i.x,i.y,t,0,2*Math.PI),this.ctx.fillStyle=i.color,this.ctx.fill(),this.ctx.shadowBlur=0}}updateFPS(){this.frameCount++;const i=Date.now(),t=i-this.lastFpsUpdate;t>=1e3&&(this.fps=Math.round(1e3*this.frameCount/t),this.frameCount=0,this.lastFpsUpdate=i)}animate(){if(!this.isRunning)return;const i=performance.now(),t=i-this.lastFrameTime,s=Math.min(Math.max(t,1),100);this.updateParticles(s),this.drawParticles(),this.updateFPS(),this.lastFrameTime=i,this.animationId=requestAnimationFrame(()=>this.animate())}start(){this.isRunning||(this.isRunning=!0,this.lastFrameTime=performance.now(),this.animate())}pause(){this.isRunning=!1,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null)}reset(){const i=this.isRunning;i&&this.pause(),this.createParticles(),i?this.start():this.drawParticles()}resize(){if(this.config.isBackground){const i=this.canvas.width,t=this.canvas.height,s=window.innerWidth,e=window.innerHeight;if(this.canvas.width=s,this.canvas.height=e,this.particles.length>0){const a=s/i,n=e/t;for(const i of this.particles)if(i.x*=a,i.y*=n,i.x=Math.max(0,Math.min(s,i.x)),i.y=Math.max(0,Math.min(e,i.y)),(i.x<=0||i.x>=s)&&(i.vx*=-1),(i.y<=0||i.y>=e)&&(i.vy*=-1),this.config.showTrail)for(let t=0;t<i.trailPositions.length;t++){const r=i.trailPositions[t];r.x*=a,r.y*=n,r.x=Math.max(0,Math.min(s,r.x)),r.y=Math.max(0,Math.min(e,r.y))}this.drawParticles()}else this.createParticles(),this.drawParticles()}}destroy(){this.pause(),this.canvas&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)}bindEvents(){window.addEventListener("resize",()=>{this.config.isBackground&&(this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=window.setTimeout(()=>{this.resize()},150))}),document.addEventListener("visibilitychange",()=>{document.hidden?(this.wasRunningBeforeHide=this.isRunning,this.isRunning&&this.pause()):(this.wasRunningBeforeHide&&this.start(),this.wasRunningBeforeHide=!1)})}}const t=i;exports.ParticleCanvas=i,exports.default=t;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});class i{constructor(i={}){this.MAX_PARTICLE_NUMBER=800,this.MAX_PARTICLE_SPEED=3,this.MAX_PARTICLE_SIZE=10,this.MAX_LINK_DISTANCE=300,this.MAX_LINE_WIDTH=5,this.MAX_LINE_OPACITY=1,this.MAX_TRAIL_VALUE=1,this.MAX_PARTICLE_BLUR=5,this.MAX_TRAIL_INTENSITY=5;const t=this.validateAndLimitOptions(i);this.config={canvasContainer:t.canvasContainer||document.body,isBackground:void 0===t.isBackground||t.isBackground,canvasBackgroundColor:t.canvasBackgroundColor||"rgb(10, 10, 25)",particleNumber:t.particleNumber||150,particleSpeed:t.particleSpeed||1,particleSize:t.particleSize||5,particleColor:t.particleColor||"rgba(156, 74, 255, 0.6)",particleBlur:void 0!==t.particleBlur?t.particleBlur:2,lineWidth:t.lineWidth||1,lineColor:t.lineColor||"#ffffff",lineOpacity:t.lineOpacity||.3,linkDistance:t.linkDistance||120,showLine:void 0===t.showLine||t.showLine,canvasSize:t.canvasSize||[800,600],showTrail:void 0===t.showTrail||t.showTrail,trailIntensity:t.trailIntensity||2},this.particles=[],this.animationId=null,this.isRunning=!1,this.lastTime=0,this.fps=60,this.fpsInterval=1e3/60,this.then=Date.now(),this.frameCount=0,this.lastFpsUpdate=Date.now(),this.resizeTimer=null,this.wasRunningBeforeHide=!1,this.lastFrameTime=performance.now(),this.init()}validateAndLimitOptions(i){const t=Object.assign({},i);return void 0!==i.particleNumber&&(i.particleNumber>this.MAX_PARTICLE_NUMBER?(console.warn(`Warning: particleNumber (${i.particleNumber}) exceeds maximum allowed value (${this.MAX_PARTICLE_NUMBER}). Using maximum value instead.`),t.particleNumber=this.MAX_PARTICLE_NUMBER):i.particleNumber<1&&(console.warn(`Warning: particleNumber (${i.particleNumber}) is below minimum value (1). Using default value instead.`),t.particleNumber=150)),void 0!==i.particleSpeed&&(i.particleSpeed>this.MAX_PARTICLE_SPEED?(console.warn(`Warning: particleSpeed (${i.particleSpeed}) exceeds maximum allowed value (${this.MAX_PARTICLE_SPEED}). Using maximum value instead.`),t.particleSpeed=this.MAX_PARTICLE_SPEED):i.particleSpeed<0&&(console.warn(`Warning: particleSpeed (${i.particleSpeed}) is below minimum value (0). Using default value instead.`),t.particleSpeed=1)),void 0!==i.particleSize&&(i.particleSize>this.MAX_PARTICLE_SIZE?(console.warn(`Warning: particleSize (${i.particleSize}) exceeds maximum allowed value (${this.MAX_PARTICLE_SIZE}). Using maximum value instead.`),t.particleSize=this.MAX_PARTICLE_SIZE):i.particleSize<1&&(console.warn(`Warning: particleSize (${i.particleSize}) is below minimum value (1). Using default value instead.`),t.particleSize=3)),void 0!==i.particleBlur&&(i.particleBlur>this.MAX_PARTICLE_BLUR?(console.warn(`Warning: particleBlur (${i.particleBlur}) exceeds maximum allowed value (${this.MAX_PARTICLE_BLUR}). Using maximum value instead.`),t.particleBlur=this.MAX_PARTICLE_BLUR):i.particleBlur<0&&(console.warn(`Warning: particleBlur (${i.particleBlur}) is below minimum value (0). Using default value instead.`),t.particleBlur=2)),void 0!==i.linkDistance&&(i.linkDistance>this.MAX_LINK_DISTANCE?(console.warn(`Warning: linkDistance (${i.linkDistance}) exceeds maximum allowed value (${this.MAX_LINK_DISTANCE}). Using maximum value instead.`),t.linkDistance=this.MAX_LINK_DISTANCE):i.linkDistance<10&&(console.warn(`Warning: linkDistance (${i.linkDistance}) is below minimum value (10). Using default value instead.`),t.linkDistance=120)),void 0!==i.lineWidth&&(i.lineWidth>this.MAX_LINE_WIDTH?(console.warn(`Warning: lineWidth (${i.lineWidth}) exceeds maximum allowed value (${this.MAX_LINE_WIDTH}). Using maximum value instead.`),t.lineWidth=this.MAX_LINE_WIDTH):i.lineWidth<0&&(console.warn(`Warning: lineWidth (${i.lineWidth}) is below minimum value (0). Using default value instead.`),t.lineWidth=1)),void 0!==i.lineOpacity&&(i.lineOpacity>this.MAX_LINE_OPACITY?(console.warn(`Warning: lineOpacity (${i.lineOpacity}) exceeds maximum allowed value (${this.MAX_LINE_OPACITY}). Using maximum value instead.`),t.lineOpacity=this.MAX_LINE_OPACITY):i.lineOpacity<0&&(console.warn(`Warning: lineOpacity (${i.lineOpacity}) is below minimum value (0). Using default value instead.`),t.lineOpacity=.3)),void 0!==i.trailIntensity&&(i.trailIntensity>this.MAX_TRAIL_INTENSITY?(console.warn(`Warning: trailIntensity (${i.trailIntensity}) exceeds maximum allowed value (${this.MAX_TRAIL_INTENSITY}). Using maximum value instead.`),t.trailIntensity=this.MAX_TRAIL_INTENSITY):i.trailIntensity<1&&(console.warn(`Warning: trailIntensity (${i.trailIntensity}) is below minimum value (1). Using default value instead.`),t.trailIntensity=2)),t}init(){this.canvas=document.createElement("canvas");const i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get 2D context from canvas");if(this.ctx=i,"string"==typeof this.config.canvasContainer){const i=document.querySelector(this.config.canvasContainer);if(!i)throw new Error(`Canvas container not found: ${this.config.canvasContainer}`);this.container=i}else this.container=this.config.canvasContainer;this.container?(this.container.appendChild(this.canvas),this.setupCanvas(),this.createParticles(),this.bindEvents()):console.error("Canvas container not found")}setupCanvas(){if(this.config.isBackground)this.canvas.style.position="fixed",this.canvas.style.top="0",this.canvas.style.left="0",this.canvas.style.width="100%",this.canvas.style.height="100%",this.canvas.style.zIndex="-1",this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight;else{this.canvas.style.display="block";const[i,t]=this.config.canvasSize;this.canvas.width=i,this.canvas.height=t,this.canvas.style.width=i+"px",this.canvas.style.height=t+"px"}this.canvas.style.pointerEvents="none"}createParticles(){this.particles=[];const i=Array.isArray(this.config.particleColor);for(let t=0;t<this.config.particleNumber;t++){let t;if(i){const i=this.config.particleColor;t=i[Math.floor(Math.random()*i.length)]}else t=this.config.particleColor;this.particles.push({x:Math.random()*this.canvas.width,y:Math.random()*this.canvas.height,vx:2*(Math.random()-.5)*this.config.particleSpeed,vy:2*(Math.random()-.5)*this.config.particleSpeed,size:this.config.particleSize,color:t,originalColor:t,pulse:0,pulseSpeed:.05*Math.random()+.02,trailPositions:[]})}}updateParticles(i){const t=i/16.67;for(const i of this.particles)i.pulse+=i.pulseSpeed*t,i.pulse>2*Math.PI&&(i.pulse=0),this.config.showTrail&&(i.trailPositions.unshift({x:i.x,y:i.y}),i.trailPositions.length>10*this.config.trailIntensity&&(i.trailPositions.length=10*this.config.trailIntensity)),i.x+=i.vx*t,i.y+=i.vy*t,(i.x<0||i.x>this.canvas.width)&&(i.vx*=-1),(i.y<0||i.y>this.canvas.height)&&(i.vy*=-1),i.x=Math.max(0,Math.min(this.canvas.width,i.x)),i.y=Math.max(0,Math.min(this.canvas.height,i.y))}drawTrailEffect(){if(this.config.showTrail){this.ctx.save();for(const i of this.particles){if(i.trailPositions.length<2)continue;this.ctx.beginPath(),this.ctx.moveTo(i.trailPositions[0].x,i.trailPositions[0].y);for(let t=1;t<i.trailPositions.length;t++)this.ctx.lineTo(i.trailPositions[t].x,i.trailPositions[t].y);const t=1.2*i.size;this.ctx.lineWidth=t,this.ctx.lineCap="round",this.ctx.lineJoin="round";const s=i.trailPositions[0],e=i.trailPositions[i.trailPositions.length-1],a=this.ctx.createLinearGradient(s.x,s.y,e.x,e.y),n=this.parseColor(i.color),r=.35;a.addColorStop(0,`rgba(${n.r}, ${n.g}, ${n.b}, ${r})`),a.addColorStop(.3,`rgba(${n.r}, ${n.g}, ${n.b}, ${.6*r})`),a.addColorStop(.7,`rgba(${n.r}, ${n.g}, ${n.b}, ${.2*r})`),a.addColorStop(1,`rgba(${n.r}, ${n.g}, ${n.b}, 0)`),this.ctx.strokeStyle=a,this.ctx.stroke()}this.ctx.restore()}}parseColor(i){if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3]),a:parseFloat(t[4])}}else if(i.startsWith("rgb")){const t=i.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3])}}else if(i.startsWith("#")){let t,s,e,a=i.replace("#","");if(3===a.length)t=parseInt(a[0]+a[0],16),s=parseInt(a[1]+a[1],16),e=parseInt(a[2]+a[2],16);else{if(6!==a.length)return{r:255,g:255,b:255};t=parseInt(a.substring(0,2),16),s=parseInt(a.substring(2,4),16),e=parseInt(a.substring(4,6),16)}return{r:t,g:s,b:e}}return{r:255,g:255,b:255}}drawParticles(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);let i=this.config.canvasBackgroundColor;if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t){const s=t[1],e=t[2],a=t[3];parseFloat(t[4])<1&&(i=`rgb(${s}, ${e}, ${a})`)}}if(this.ctx.fillStyle=i,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.drawTrailEffect(),this.config.showLine)for(let i=0;i<this.particles.length;i++)for(let t=i+1;t<this.particles.length;t++){const s=this.particles[i].x-this.particles[t].x,e=this.particles[i].y-this.particles[t].y,a=Math.sqrt(s*s+e*e);if(a<this.config.linkDistance){const s=this.config.lineOpacity*(1-a/this.config.linkDistance);this.ctx.strokeStyle=this.config.lineColor,this.ctx.globalAlpha=s,this.ctx.lineWidth=this.config.lineWidth,this.ctx.beginPath(),this.ctx.moveTo(this.particles[i].x,this.particles[i].y),this.ctx.lineTo(this.particles[t].x,this.particles[t].y),this.ctx.stroke()}}this.ctx.globalAlpha=1;for(const i of this.particles){const t=i.size*(1+.2*Math.sin(i.pulse));this.config.particleBlur>0&&(this.ctx.shadowColor=i.color,this.ctx.shadowBlur=4*this.config.particleBlur),this.ctx.beginPath(),this.ctx.arc(i.x,i.y,t,0,2*Math.PI),this.ctx.fillStyle=i.color,this.ctx.fill(),this.ctx.shadowBlur=0}}updateFPS(){this.frameCount++;const i=Date.now(),t=i-this.lastFpsUpdate;t>=1e3&&(this.fps=Math.round(1e3*this.frameCount/t),this.frameCount=0,this.lastFpsUpdate=i)}animate(){if(!this.isRunning)return;const i=performance.now(),t=i-this.lastFrameTime,s=Math.min(Math.max(t,1),100);this.updateParticles(s),this.drawParticles(),this.updateFPS(),this.lastFrameTime=i,this.animationId=requestAnimationFrame(()=>this.animate())}start(){this.isRunning||(this.isRunning=!0,this.lastFrameTime=performance.now(),this.animate())}pause(){this.isRunning=!1,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null)}reset(){const i=this.isRunning;i&&this.pause(),this.createParticles(),i?this.start():this.drawParticles()}resize(){if(this.config.isBackground){const i=this.canvas.width,t=this.canvas.height,s=window.innerWidth,e=window.innerHeight;if(this.canvas.width=s,this.canvas.height=e,this.particles.length>0){const a=s/i,n=e/t;for(const i of this.particles)if(i.x*=a,i.y*=n,i.x=Math.max(0,Math.min(s,i.x)),i.y=Math.max(0,Math.min(e,i.y)),(i.x<=0||i.x>=s)&&(i.vx*=-1),(i.y<=0||i.y>=e)&&(i.vy*=-1),this.config.showTrail)for(let t=0;t<i.trailPositions.length;t++){const r=i.trailPositions[t];r.x*=a,r.y*=n,r.x=Math.max(0,Math.min(s,r.x)),r.y=Math.max(0,Math.min(e,r.y))}this.drawParticles()}else this.createParticles(),this.drawParticles()}}destroy(){this.pause(),this.canvas&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)}bindEvents(){window.addEventListener("resize",()=>{this.config.isBackground&&(this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=window.setTimeout(()=>{this.resize()},150))}),document.addEventListener("visibilitychange",()=>{document.hidden?(this.wasRunningBeforeHide=this.isRunning,this.isRunning&&this.pause()):(this.wasRunningBeforeHide&&this.start(),this.wasRunningBeforeHide=!1)})}}const t=i;exports.ParticleCanvas=i,exports.default=t;
|
package/dist/bundle.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class i{constructor(i={}){this.MAX_PARTICLE_NUMBER=800,this.MAX_PARTICLE_SPEED=3,this.MAX_PARTICLE_SIZE=10,this.MAX_LINK_DISTANCE=300,this.MAX_LINE_WIDTH=5,this.MAX_LINE_OPACITY=1,this.MAX_TRAIL_VALUE=1,this.MAX_PARTICLE_BLUR=5,this.MAX_TRAIL_INTENSITY=5;const t=this.validateAndLimitOptions(i);this.config={canvasContainer:t.canvasContainer||document.body,isBackground:void 0===t.isBackground||t.isBackground,canvasBackgroundColor:t.canvasBackgroundColor||"rgb(10, 10, 25)",particleNumber:t.particleNumber||150,particleSpeed:t.particleSpeed||1,particleSize:t.particleSize||5,particleColor:t.particleColor||"rgba(156, 74, 255, 0.6)",particleBlur:void 0!==t.particleBlur?t.particleBlur:2,lineWidth:t.lineWidth||1,lineColor:t.lineColor||"#ffffff",lineOpacity:t.lineOpacity||.3,linkDistance:t.linkDistance||120,showLine:void 0===t.showLine||t.showLine,canvasSize:t.canvasSize||[800,600],showTrail:void 0===t.showTrail||t.showTrail,trailIntensity:t.trailIntensity||2},this.particles=[],this.animationId=null,this.isRunning=!1,this.lastTime=0,this.fps=60,this.fpsInterval=1e3/60,this.then=Date.now(),this.frameCount=0,this.lastFpsUpdate=Date.now(),this.resizeTimer=null,this.wasRunningBeforeHide=!1,this.lastFrameTime=performance.now(),this.init()}validateAndLimitOptions(i){const t=Object.assign({},i);return void 0!==i.particleNumber&&(i.particleNumber>this.MAX_PARTICLE_NUMBER?(console.warn(`Warning: particleNumber (${i.particleNumber}) exceeds maximum allowed value (${this.MAX_PARTICLE_NUMBER}). Using maximum value instead.`),t.particleNumber=this.MAX_PARTICLE_NUMBER):i.particleNumber<1&&(console.warn(`Warning: particleNumber (${i.particleNumber}) is below minimum value (1). Using default value instead.`),t.particleNumber=150)),void 0!==i.particleSpeed&&(i.particleSpeed>this.MAX_PARTICLE_SPEED?(console.warn(`Warning: particleSpeed (${i.particleSpeed}) exceeds maximum allowed value (${this.MAX_PARTICLE_SPEED}). Using maximum value instead.`),t.particleSpeed=this.MAX_PARTICLE_SPEED):i.particleSpeed<0&&(console.warn(`Warning: particleSpeed (${i.particleSpeed}) is below minimum value (0). Using default value instead.`),t.particleSpeed=1)),void 0!==i.particleSize&&(i.particleSize>this.MAX_PARTICLE_SIZE?(console.warn(`Warning: particleSize (${i.particleSize}) exceeds maximum allowed value (${this.MAX_PARTICLE_SIZE}). Using maximum value instead.`),t.particleSize=this.MAX_PARTICLE_SIZE):i.particleSize<1&&(console.warn(`Warning: particleSize (${i.particleSize}) is below minimum value (1). Using default value instead.`),t.particleSize=3)),void 0!==i.particleBlur&&(i.particleBlur>this.MAX_PARTICLE_BLUR?(console.warn(`Warning: particleBlur (${i.particleBlur}) exceeds maximum allowed value (${this.MAX_PARTICLE_BLUR}). Using maximum value instead.`),t.particleBlur=this.MAX_PARTICLE_BLUR):i.particleBlur<0&&(console.warn(`Warning: particleBlur (${i.particleBlur}) is below minimum value (0). Using default value instead.`),t.particleBlur=2)),void 0!==i.linkDistance&&(i.linkDistance>this.MAX_LINK_DISTANCE?(console.warn(`Warning: linkDistance (${i.linkDistance}) exceeds maximum allowed value (${this.MAX_LINK_DISTANCE}). Using maximum value instead.`),t.linkDistance=this.MAX_LINK_DISTANCE):i.linkDistance<10&&(console.warn(`Warning: linkDistance (${i.linkDistance}) is below minimum value (10). Using default value instead.`),t.linkDistance=120)),void 0!==i.lineWidth&&(i.lineWidth>this.MAX_LINE_WIDTH?(console.warn(`Warning: lineWidth (${i.lineWidth}) exceeds maximum allowed value (${this.MAX_LINE_WIDTH}). Using maximum value instead.`),t.lineWidth=this.MAX_LINE_WIDTH):i.lineWidth<0&&(console.warn(`Warning: lineWidth (${i.lineWidth}) is below minimum value (0). Using default value instead.`),t.lineWidth=1)),void 0!==i.lineOpacity&&(i.lineOpacity>this.MAX_LINE_OPACITY?(console.warn(`Warning: lineOpacity (${i.lineOpacity}) exceeds maximum allowed value (${this.MAX_LINE_OPACITY}). Using maximum value instead.`),t.lineOpacity=this.MAX_LINE_OPACITY):i.lineOpacity<0&&(console.warn(`Warning: lineOpacity (${i.lineOpacity}) is below minimum value (0). Using default value instead.`),t.lineOpacity=.3)),void 0!==i.trailIntensity&&(i.trailIntensity>this.MAX_TRAIL_INTENSITY?(console.warn(`Warning: trailIntensity (${i.trailIntensity}) exceeds maximum allowed value (${this.MAX_TRAIL_INTENSITY}). Using maximum value instead.`),t.trailIntensity=this.MAX_TRAIL_INTENSITY):i.trailIntensity<1&&(console.warn(`Warning: trailIntensity (${i.trailIntensity}) is below minimum value (1). Using default value instead.`),t.trailIntensity=2)),t}init(){this.canvas=document.createElement("canvas");const i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get 2D context from canvas");if(this.ctx=i,"string"==typeof this.config.canvasContainer){const i=document.querySelector(this.config.canvasContainer);if(!i)throw new Error(`Canvas container not found: ${this.config.canvasContainer}`);this.container=i}else this.container=this.config.canvasContainer;this.container?(this.container.appendChild(this.canvas),this.setupCanvas(),this.createParticles(),this.bindEvents()):console.error("Canvas container not found")}setupCanvas(){if(this.config.isBackground)this.canvas.style.position="fixed",this.canvas.style.top="0",this.canvas.style.left="0",this.canvas.style.width="100%",this.canvas.style.height="100%",this.canvas.style.zIndex="-1",this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight;else{this.canvas.style.display="block";const[i,t]=this.config.canvasSize;this.canvas.width=i,this.canvas.height=t,this.canvas.style.width=i+"px",this.canvas.style.height=t+"px"}this.canvas.style.pointerEvents="none"}createParticles(){this.particles=[];const i=Array.isArray(this.config.particleColor);for(let t=0;t<this.config.particleNumber;t++){let t;if(i){const i=this.config.particleColor;t=i[Math.floor(Math.random()*i.length)]}else t=this.config.particleColor;this.particles.push({x:Math.random()*this.canvas.width,y:Math.random()*this.canvas.height,vx:2*(Math.random()-.5)*this.config.particleSpeed,vy:2*(Math.random()-.5)*this.config.particleSpeed,size:this.config.particleSize,color:t,originalColor:t,pulse:0,pulseSpeed:.05*Math.random()+.02,trailPositions:[]})}}updateParticles(i){const t=i/16.67;for(const i of this.particles)i.pulse+=i.pulseSpeed*t,i.pulse>2*Math.PI&&(i.pulse=0),this.config.showTrail&&(i.trailPositions.unshift({x:i.x,y:i.y}),i.trailPositions.length>10*this.config.trailIntensity&&(i.trailPositions.length=10*this.config.trailIntensity)),i.x+=i.vx*t,i.y+=i.vy*t,(i.x<0||i.x>this.canvas.width)&&(i.vx*=-1),(i.y<0||i.y>this.canvas.height)&&(i.vy*=-1),i.x=Math.max(0,Math.min(this.canvas.width,i.x)),i.y=Math.max(0,Math.min(this.canvas.height,i.y))}drawTrailEffect(){if(this.config.showTrail){this.ctx.save();for(const i of this.particles){if(i.trailPositions.length<2)continue;this.ctx.beginPath(),this.ctx.moveTo(i.trailPositions[0].x,i.trailPositions[0].y);for(let t=1;t<i.trailPositions.length;t++)this.ctx.lineTo(i.trailPositions[t].x,i.trailPositions[t].y);const t=1.2*i.size;this.ctx.lineWidth=t,this.ctx.lineCap="round",this.ctx.lineJoin="round";const s=i.trailPositions[0],e=i.trailPositions[i.trailPositions.length-1],a=this.ctx.createLinearGradient(s.x,s.y,e.x,e.y),n=this.parseColor(i.color),r=.35;a.addColorStop(0,`rgba(${n.r}, ${n.g}, ${n.b}, ${r})`),a.addColorStop(.3,`rgba(${n.r}, ${n.g}, ${n.b}, ${.6*r})`),a.addColorStop(.7,`rgba(${n.r}, ${n.g}, ${n.b}, ${.2*r})`),a.addColorStop(1,`rgba(${n.r}, ${n.g}, ${n.b}, 0)`),this.ctx.strokeStyle=a,this.ctx.stroke()}this.ctx.restore()}}parseColor(i){if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3]),a:parseFloat(t[4])}}else if(i.startsWith("rgb")){const t=i.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3])}}else if(i.startsWith("#")){let t,s,e,a=i.replace("#","");if(3===a.length)t=parseInt(a[0]+a[0],16),s=parseInt(a[1]+a[1],16),e=parseInt(a[2]+a[2],16);else{if(6!==a.length)return{r:255,g:255,b:255};t=parseInt(a.substring(0,2),16),s=parseInt(a.substring(2,4),16),e=parseInt(a.substring(4,6),16)}return{r:t,g:s,b:e}}return{r:255,g:255,b:255}}drawParticles(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);let i=this.config.canvasBackgroundColor;if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t){const s=t[1],e=t[2],a=t[3];parseFloat(t[4])<1&&(i=`rgb(${s}, ${e}, ${a})`)}}if(this.ctx.fillStyle=i,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.drawTrailEffect(),this.config.showLine)for(let i=0;i<this.particles.length;i++)for(let t=i+1;t<this.particles.length;t++){const s=this.particles[i].x-this.particles[t].x,e=this.particles[i].y-this.particles[t].y,a=Math.sqrt(s*s+e*e);if(a<this.config.linkDistance){const s=this.config.lineOpacity*(1-a/this.config.linkDistance);this.ctx.strokeStyle=this.config.lineColor,this.ctx.globalAlpha=s,this.ctx.lineWidth=this.config.lineWidth,this.ctx.beginPath(),this.ctx.moveTo(this.particles[i].x,this.particles[i].y),this.ctx.lineTo(this.particles[t].x,this.particles[t].y),this.ctx.stroke()}}this.ctx.globalAlpha=1;for(const i of this.particles){const t=i.size*(1+.2*Math.sin(i.pulse));this.config.particleBlur>0&&(this.ctx.shadowColor=i.color,this.ctx.shadowBlur=4*this.config.particleBlur),this.ctx.beginPath(),this.ctx.arc(i.x,i.y,t,0,2*Math.PI),this.ctx.fillStyle=i.color,this.ctx.fill(),this.ctx.shadowBlur=0}}updateFPS(){this.frameCount++;const i=Date.now(),t=i-this.lastFpsUpdate;t>=1e3&&(this.fps=Math.round(1e3*this.frameCount/t),this.frameCount=0,this.lastFpsUpdate=i)}animate(){if(!this.isRunning)return;const i=performance.now(),t=i-this.lastFrameTime,s=Math.min(Math.max(t,1),100);this.updateParticles(s),this.drawParticles(),this.updateFPS(),this.lastFrameTime=i,this.animationId=requestAnimationFrame(()=>this.animate())}start(){this.isRunning||(this.isRunning=!0,this.lastFrameTime=performance.now(),this.animate())}pause(){this.isRunning=!1,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null)}reset(){const i=this.isRunning;i&&this.pause(),this.createParticles(),i?this.start():this.drawParticles()}resize(){if(this.config.isBackground){const i=this.canvas.width,t=this.canvas.height,s=window.innerWidth,e=window.innerHeight;if(this.canvas.width=s,this.canvas.height=e,this.particles.length>0){const a=s/i,n=e/t;for(const i of this.particles)if(i.x*=a,i.y*=n,i.x=Math.max(0,Math.min(s,i.x)),i.y=Math.max(0,Math.min(e,i.y)),(i.x<=0||i.x>=s)&&(i.vx*=-1),(i.y<=0||i.y>=e)&&(i.vy*=-1),this.config.showTrail)for(let t=0;t<i.trailPositions.length;t++){const r=i.trailPositions[t];r.x*=a,r.y*=n,r.x=Math.max(0,Math.min(s,r.x)),r.y=Math.max(0,Math.min(e,r.y))}this.drawParticles()}else this.createParticles(),this.drawParticles()}}destroy(){this.pause(),this.canvas&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)}bindEvents(){window.addEventListener("resize",()=>{this.config.isBackground&&(this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=window.setTimeout(()=>{this.resize()},150))}),document.addEventListener("visibilitychange",()=>{document.hidden?(this.wasRunningBeforeHide=this.isRunning,this.isRunning&&this.pause()):(this.wasRunningBeforeHide&&this.start(),this.wasRunningBeforeHide=!1)})}}const t=i;export{i as ParticleCanvas,t as default};
|
|
1
|
+
class i{constructor(i={}){this.MAX_PARTICLE_NUMBER=800,this.MAX_PARTICLE_SPEED=3,this.MAX_PARTICLE_SIZE=10,this.MAX_LINK_DISTANCE=300,this.MAX_LINE_WIDTH=5,this.MAX_LINE_OPACITY=1,this.MAX_TRAIL_VALUE=1,this.MAX_PARTICLE_BLUR=5,this.MAX_TRAIL_INTENSITY=5;const t=this.validateAndLimitOptions(i);this.config={canvasContainer:t.canvasContainer||document.body,isBackground:void 0===t.isBackground||t.isBackground,canvasBackgroundColor:t.canvasBackgroundColor||"rgb(10, 10, 25)",particleNumber:t.particleNumber||150,particleSpeed:t.particleSpeed||1,particleSize:t.particleSize||5,particleColor:t.particleColor||"rgba(156, 74, 255, 0.6)",particleBlur:void 0!==t.particleBlur?t.particleBlur:2,lineWidth:t.lineWidth||1,lineColor:t.lineColor||"#ffffff",lineOpacity:t.lineOpacity||.3,linkDistance:t.linkDistance||120,showLine:void 0===t.showLine||t.showLine,canvasSize:t.canvasSize||[800,600],showTrail:void 0===t.showTrail||t.showTrail,trailIntensity:t.trailIntensity||2},this.particles=[],this.animationId=null,this.isRunning=!1,this.lastTime=0,this.fps=60,this.fpsInterval=1e3/60,this.then=Date.now(),this.frameCount=0,this.lastFpsUpdate=Date.now(),this.resizeTimer=null,this.wasRunningBeforeHide=!1,this.lastFrameTime=performance.now(),this.init()}validateAndLimitOptions(i){const t=Object.assign({},i);return void 0!==i.particleNumber&&(i.particleNumber>this.MAX_PARTICLE_NUMBER?(console.warn(`Warning: particleNumber (${i.particleNumber}) exceeds maximum allowed value (${this.MAX_PARTICLE_NUMBER}). Using maximum value instead.`),t.particleNumber=this.MAX_PARTICLE_NUMBER):i.particleNumber<1&&(console.warn(`Warning: particleNumber (${i.particleNumber}) is below minimum value (1). Using default value instead.`),t.particleNumber=150)),void 0!==i.particleSpeed&&(i.particleSpeed>this.MAX_PARTICLE_SPEED?(console.warn(`Warning: particleSpeed (${i.particleSpeed}) exceeds maximum allowed value (${this.MAX_PARTICLE_SPEED}). Using maximum value instead.`),t.particleSpeed=this.MAX_PARTICLE_SPEED):i.particleSpeed<0&&(console.warn(`Warning: particleSpeed (${i.particleSpeed}) is below minimum value (0). Using default value instead.`),t.particleSpeed=1)),void 0!==i.particleSize&&(i.particleSize>this.MAX_PARTICLE_SIZE?(console.warn(`Warning: particleSize (${i.particleSize}) exceeds maximum allowed value (${this.MAX_PARTICLE_SIZE}). Using maximum value instead.`),t.particleSize=this.MAX_PARTICLE_SIZE):i.particleSize<1&&(console.warn(`Warning: particleSize (${i.particleSize}) is below minimum value (1). Using default value instead.`),t.particleSize=3)),void 0!==i.particleBlur&&(i.particleBlur>this.MAX_PARTICLE_BLUR?(console.warn(`Warning: particleBlur (${i.particleBlur}) exceeds maximum allowed value (${this.MAX_PARTICLE_BLUR}). Using maximum value instead.`),t.particleBlur=this.MAX_PARTICLE_BLUR):i.particleBlur<0&&(console.warn(`Warning: particleBlur (${i.particleBlur}) is below minimum value (0). Using default value instead.`),t.particleBlur=2)),void 0!==i.linkDistance&&(i.linkDistance>this.MAX_LINK_DISTANCE?(console.warn(`Warning: linkDistance (${i.linkDistance}) exceeds maximum allowed value (${this.MAX_LINK_DISTANCE}). Using maximum value instead.`),t.linkDistance=this.MAX_LINK_DISTANCE):i.linkDistance<10&&(console.warn(`Warning: linkDistance (${i.linkDistance}) is below minimum value (10). Using default value instead.`),t.linkDistance=120)),void 0!==i.lineWidth&&(i.lineWidth>this.MAX_LINE_WIDTH?(console.warn(`Warning: lineWidth (${i.lineWidth}) exceeds maximum allowed value (${this.MAX_LINE_WIDTH}). Using maximum value instead.`),t.lineWidth=this.MAX_LINE_WIDTH):i.lineWidth<0&&(console.warn(`Warning: lineWidth (${i.lineWidth}) is below minimum value (0). Using default value instead.`),t.lineWidth=1)),void 0!==i.lineOpacity&&(i.lineOpacity>this.MAX_LINE_OPACITY?(console.warn(`Warning: lineOpacity (${i.lineOpacity}) exceeds maximum allowed value (${this.MAX_LINE_OPACITY}). Using maximum value instead.`),t.lineOpacity=this.MAX_LINE_OPACITY):i.lineOpacity<0&&(console.warn(`Warning: lineOpacity (${i.lineOpacity}) is below minimum value (0). Using default value instead.`),t.lineOpacity=.3)),void 0!==i.trailIntensity&&(i.trailIntensity>this.MAX_TRAIL_INTENSITY?(console.warn(`Warning: trailIntensity (${i.trailIntensity}) exceeds maximum allowed value (${this.MAX_TRAIL_INTENSITY}). Using maximum value instead.`),t.trailIntensity=this.MAX_TRAIL_INTENSITY):i.trailIntensity<1&&(console.warn(`Warning: trailIntensity (${i.trailIntensity}) is below minimum value (1). Using default value instead.`),t.trailIntensity=2)),t}init(){this.canvas=document.createElement("canvas");const i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get 2D context from canvas");if(this.ctx=i,"string"==typeof this.config.canvasContainer){const i=document.querySelector(this.config.canvasContainer);if(!i)throw new Error(`Canvas container not found: ${this.config.canvasContainer}`);this.container=i}else this.container=this.config.canvasContainer;this.container?(this.container.appendChild(this.canvas),this.setupCanvas(),this.createParticles(),this.bindEvents()):console.error("Canvas container not found")}setupCanvas(){if(this.config.isBackground)this.canvas.style.position="fixed",this.canvas.style.top="0",this.canvas.style.left="0",this.canvas.style.width="100%",this.canvas.style.height="100%",this.canvas.style.zIndex="-1",this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight;else{this.canvas.style.display="block";const[i,t]=this.config.canvasSize;this.canvas.width=i,this.canvas.height=t,this.canvas.style.width=i+"px",this.canvas.style.height=t+"px"}this.canvas.style.pointerEvents="none"}createParticles(){this.particles=[];const i=Array.isArray(this.config.particleColor);for(let t=0;t<this.config.particleNumber;t++){let t;if(i){const i=this.config.particleColor;t=i[Math.floor(Math.random()*i.length)]}else t=this.config.particleColor;this.particles.push({x:Math.random()*this.canvas.width,y:Math.random()*this.canvas.height,vx:2*(Math.random()-.5)*this.config.particleSpeed,vy:2*(Math.random()-.5)*this.config.particleSpeed,size:this.config.particleSize,color:t,originalColor:t,pulse:0,pulseSpeed:.05*Math.random()+.02,trailPositions:[]})}}updateParticles(i){const t=i/16.67;for(const i of this.particles)i.pulse+=i.pulseSpeed*t,i.pulse>2*Math.PI&&(i.pulse=0),this.config.showTrail&&(i.trailPositions.unshift({x:i.x,y:i.y}),i.trailPositions.length>10*this.config.trailIntensity&&(i.trailPositions.length=10*this.config.trailIntensity)),i.x+=i.vx*t,i.y+=i.vy*t,(i.x<0||i.x>this.canvas.width)&&(i.vx*=-1),(i.y<0||i.y>this.canvas.height)&&(i.vy*=-1),i.x=Math.max(0,Math.min(this.canvas.width,i.x)),i.y=Math.max(0,Math.min(this.canvas.height,i.y))}drawTrailEffect(){if(this.config.showTrail){this.ctx.save();for(const i of this.particles){if(i.trailPositions.length<2)continue;this.ctx.beginPath(),this.ctx.moveTo(i.trailPositions[0].x,i.trailPositions[0].y);for(let t=1;t<i.trailPositions.length;t++)this.ctx.lineTo(i.trailPositions[t].x,i.trailPositions[t].y);const t=1.2*i.size;this.ctx.lineWidth=t,this.ctx.lineCap="round",this.ctx.lineJoin="round";const s=i.trailPositions[0],e=i.trailPositions[i.trailPositions.length-1],a=this.ctx.createLinearGradient(s.x,s.y,e.x,e.y),n=this.parseColor(i.color),r=.35;a.addColorStop(0,`rgba(${n.r}, ${n.g}, ${n.b}, ${r})`),a.addColorStop(.3,`rgba(${n.r}, ${n.g}, ${n.b}, ${.6*r})`),a.addColorStop(.7,`rgba(${n.r}, ${n.g}, ${n.b}, ${.2*r})`),a.addColorStop(1,`rgba(${n.r}, ${n.g}, ${n.b}, 0)`),this.ctx.strokeStyle=a,this.ctx.stroke()}this.ctx.restore()}}parseColor(i){if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3]),a:parseFloat(t[4])}}else if(i.startsWith("rgb")){const t=i.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3])}}else if(i.startsWith("#")){let t,s,e,a=i.replace("#","");if(3===a.length)t=parseInt(a[0]+a[0],16),s=parseInt(a[1]+a[1],16),e=parseInt(a[2]+a[2],16);else{if(6!==a.length)return{r:255,g:255,b:255};t=parseInt(a.substring(0,2),16),s=parseInt(a.substring(2,4),16),e=parseInt(a.substring(4,6),16)}return{r:t,g:s,b:e}}return{r:255,g:255,b:255}}drawParticles(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);let i=this.config.canvasBackgroundColor;if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t){const s=t[1],e=t[2],a=t[3];parseFloat(t[4])<1&&(i=`rgb(${s}, ${e}, ${a})`)}}if(this.ctx.fillStyle=i,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.drawTrailEffect(),this.config.showLine)for(let i=0;i<this.particles.length;i++)for(let t=i+1;t<this.particles.length;t++){const s=this.particles[i].x-this.particles[t].x,e=this.particles[i].y-this.particles[t].y,a=Math.sqrt(s*s+e*e);if(a<this.config.linkDistance){const s=this.config.lineOpacity*(1-a/this.config.linkDistance);this.ctx.strokeStyle=this.config.lineColor,this.ctx.globalAlpha=s,this.ctx.lineWidth=this.config.lineWidth,this.ctx.beginPath(),this.ctx.moveTo(this.particles[i].x,this.particles[i].y),this.ctx.lineTo(this.particles[t].x,this.particles[t].y),this.ctx.stroke()}}this.ctx.globalAlpha=1;for(const i of this.particles){const t=i.size*(1+.2*Math.sin(i.pulse));this.config.particleBlur>0&&(this.ctx.shadowColor=i.color,this.ctx.shadowBlur=4*this.config.particleBlur),this.ctx.beginPath(),this.ctx.arc(i.x,i.y,t,0,2*Math.PI),this.ctx.fillStyle=i.color,this.ctx.fill(),this.ctx.shadowBlur=0}}updateFPS(){this.frameCount++;const i=Date.now(),t=i-this.lastFpsUpdate;t>=1e3&&(this.fps=Math.round(1e3*this.frameCount/t),this.frameCount=0,this.lastFpsUpdate=i)}animate(){if(!this.isRunning)return;const i=performance.now(),t=i-this.lastFrameTime,s=Math.min(Math.max(t,1),100);this.updateParticles(s),this.drawParticles(),this.updateFPS(),this.lastFrameTime=i,this.animationId=requestAnimationFrame(()=>this.animate())}start(){this.isRunning||(this.isRunning=!0,this.lastFrameTime=performance.now(),this.animate())}pause(){this.isRunning=!1,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null)}reset(){const i=this.isRunning;i&&this.pause(),this.createParticles(),i?this.start():this.drawParticles()}resize(){if(this.config.isBackground){const i=this.canvas.width,t=this.canvas.height,s=window.innerWidth,e=window.innerHeight;if(this.canvas.width=s,this.canvas.height=e,this.particles.length>0){const a=s/i,n=e/t;for(const i of this.particles)if(i.x*=a,i.y*=n,i.x=Math.max(0,Math.min(s,i.x)),i.y=Math.max(0,Math.min(e,i.y)),(i.x<=0||i.x>=s)&&(i.vx*=-1),(i.y<=0||i.y>=e)&&(i.vy*=-1),this.config.showTrail)for(let t=0;t<i.trailPositions.length;t++){const r=i.trailPositions[t];r.x*=a,r.y*=n,r.x=Math.max(0,Math.min(s,r.x)),r.y=Math.max(0,Math.min(e,r.y))}this.drawParticles()}else this.createParticles(),this.drawParticles()}}destroy(){this.pause(),this.canvas&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)}bindEvents(){window.addEventListener("resize",()=>{this.config.isBackground&&(this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=window.setTimeout(()=>{this.resize()},150))}),document.addEventListener("visibilitychange",()=>{document.hidden?(this.wasRunningBeforeHide=this.isRunning,this.isRunning&&this.pause()):(this.wasRunningBeforeHide&&this.start(),this.wasRunningBeforeHide=!1)})}}const t=i;export{i as ParticleCanvas,t as default};
|
package/dist/bundle.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var ParticleCanvasPro=function(i){"use strict";class t{constructor(i={}){this.MAX_PARTICLE_NUMBER=800,this.MAX_PARTICLE_SPEED=3,this.MAX_PARTICLE_SIZE=10,this.MAX_LINK_DISTANCE=300,this.MAX_LINE_WIDTH=5,this.MAX_LINE_OPACITY=1,this.MAX_TRAIL_VALUE=1,this.MAX_PARTICLE_BLUR=5,this.MAX_TRAIL_INTENSITY=5;const t=this.validateAndLimitOptions(i);this.config={canvasContainer:t.canvasContainer||document.body,isBackground:void 0===t.isBackground||t.isBackground,canvasBackgroundColor:t.canvasBackgroundColor||"rgb(10, 10, 25)",particleNumber:t.particleNumber||150,particleSpeed:t.particleSpeed||1,particleSize:t.particleSize||5,particleColor:t.particleColor||"rgba(156, 74, 255, 0.6)",particleBlur:void 0!==t.particleBlur?t.particleBlur:2,lineWidth:t.lineWidth||1,lineColor:t.lineColor||"#ffffff",lineOpacity:t.lineOpacity||.3,linkDistance:t.linkDistance||120,showLine:void 0===t.showLine||t.showLine,canvasSize:t.canvasSize||[800,600],showTrail:void 0===t.showTrail||t.showTrail,trailIntensity:t.trailIntensity||2},this.particles=[],this.animationId=null,this.isRunning=!1,this.lastTime=0,this.fps=60,this.fpsInterval=1e3/60,this.then=Date.now(),this.frameCount=0,this.lastFpsUpdate=Date.now(),this.resizeTimer=null,this.wasRunningBeforeHide=!1,this.lastFrameTime=performance.now(),this.init()}validateAndLimitOptions(i){const t=Object.assign({},i);return void 0!==i.particleNumber&&(i.particleNumber>this.MAX_PARTICLE_NUMBER?(console.warn(`Warning: particleNumber (${i.particleNumber}) exceeds maximum allowed value (${this.MAX_PARTICLE_NUMBER}). Using maximum value instead.`),t.particleNumber=this.MAX_PARTICLE_NUMBER):i.particleNumber<1&&(console.warn(`Warning: particleNumber (${i.particleNumber}) is below minimum value (1). Using default value instead.`),t.particleNumber=150)),void 0!==i.particleSpeed&&(i.particleSpeed>this.MAX_PARTICLE_SPEED?(console.warn(`Warning: particleSpeed (${i.particleSpeed}) exceeds maximum allowed value (${this.MAX_PARTICLE_SPEED}). Using maximum value instead.`),t.particleSpeed=this.MAX_PARTICLE_SPEED):i.particleSpeed<0&&(console.warn(`Warning: particleSpeed (${i.particleSpeed}) is below minimum value (0). Using default value instead.`),t.particleSpeed=1)),void 0!==i.particleSize&&(i.particleSize>this.MAX_PARTICLE_SIZE?(console.warn(`Warning: particleSize (${i.particleSize}) exceeds maximum allowed value (${this.MAX_PARTICLE_SIZE}). Using maximum value instead.`),t.particleSize=this.MAX_PARTICLE_SIZE):i.particleSize<1&&(console.warn(`Warning: particleSize (${i.particleSize}) is below minimum value (1). Using default value instead.`),t.particleSize=3)),void 0!==i.particleBlur&&(i.particleBlur>this.MAX_PARTICLE_BLUR?(console.warn(`Warning: particleBlur (${i.particleBlur}) exceeds maximum allowed value (${this.MAX_PARTICLE_BLUR}). Using maximum value instead.`),t.particleBlur=this.MAX_PARTICLE_BLUR):i.particleBlur<0&&(console.warn(`Warning: particleBlur (${i.particleBlur}) is below minimum value (0). Using default value instead.`),t.particleBlur=2)),void 0!==i.linkDistance&&(i.linkDistance>this.MAX_LINK_DISTANCE?(console.warn(`Warning: linkDistance (${i.linkDistance}) exceeds maximum allowed value (${this.MAX_LINK_DISTANCE}). Using maximum value instead.`),t.linkDistance=this.MAX_LINK_DISTANCE):i.linkDistance<10&&(console.warn(`Warning: linkDistance (${i.linkDistance}) is below minimum value (10). Using default value instead.`),t.linkDistance=120)),void 0!==i.lineWidth&&(i.lineWidth>this.MAX_LINE_WIDTH?(console.warn(`Warning: lineWidth (${i.lineWidth}) exceeds maximum allowed value (${this.MAX_LINE_WIDTH}). Using maximum value instead.`),t.lineWidth=this.MAX_LINE_WIDTH):i.lineWidth<0&&(console.warn(`Warning: lineWidth (${i.lineWidth}) is below minimum value (0). Using default value instead.`),t.lineWidth=1)),void 0!==i.lineOpacity&&(i.lineOpacity>this.MAX_LINE_OPACITY?(console.warn(`Warning: lineOpacity (${i.lineOpacity}) exceeds maximum allowed value (${this.MAX_LINE_OPACITY}). Using maximum value instead.`),t.lineOpacity=this.MAX_LINE_OPACITY):i.lineOpacity<0&&(console.warn(`Warning: lineOpacity (${i.lineOpacity}) is below minimum value (0). Using default value instead.`),t.lineOpacity=.3)),void 0!==i.trailIntensity&&(i.trailIntensity>this.MAX_TRAIL_INTENSITY?(console.warn(`Warning: trailIntensity (${i.trailIntensity}) exceeds maximum allowed value (${this.MAX_TRAIL_INTENSITY}). Using maximum value instead.`),t.trailIntensity=this.MAX_TRAIL_INTENSITY):i.trailIntensity<1&&(console.warn(`Warning: trailIntensity (${i.trailIntensity}) is below minimum value (1). Using default value instead.`),t.trailIntensity=2)),t}init(){this.canvas=document.createElement("canvas");const i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get 2D context from canvas");if(this.ctx=i,"string"==typeof this.config.canvasContainer){const i=document.querySelector(this.config.canvasContainer);if(!i)throw new Error(`Canvas container not found: ${this.config.canvasContainer}`);this.container=i}else this.container=this.config.canvasContainer;this.container?(this.container.appendChild(this.canvas),this.setupCanvas(),this.createParticles(),this.bindEvents()):console.error("Canvas container not found")}setupCanvas(){if(this.config.isBackground)this.canvas.style.position="fixed",this.canvas.style.top="0",this.canvas.style.left="0",this.canvas.style.width="100%",this.canvas.style.height="100%",this.canvas.style.zIndex="-1",this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight;else{this.canvas.style.display="block";const[i,t]=this.config.canvasSize;this.canvas.width=i,this.canvas.height=t,this.canvas.style.width=i+"px",this.canvas.style.height=t+"px"}this.canvas.style.pointerEvents="none"}createParticles(){this.particles=[];const i=Array.isArray(this.config.particleColor);for(let t=0;t<this.config.particleNumber;t++){let t;if(i){const i=this.config.particleColor;t=i[Math.floor(Math.random()*i.length)]}else t=this.config.particleColor;this.particles.push({x:Math.random()*this.canvas.width,y:Math.random()*this.canvas.height,vx:2*(Math.random()-.5)*this.config.particleSpeed,vy:2*(Math.random()-.5)*this.config.particleSpeed,size:this.config.particleSize,color:t,originalColor:t,pulse:0,pulseSpeed:.05*Math.random()+.02,trailPositions:[]})}}updateParticles(i){const t=i/16.67;for(const i of this.particles)i.pulse+=i.pulseSpeed*t,i.pulse>2*Math.PI&&(i.pulse=0),this.config.showTrail&&(i.trailPositions.unshift({x:i.x,y:i.y}),i.trailPositions.length>10*this.config.trailIntensity&&(i.trailPositions.length=10*this.config.trailIntensity)),i.x+=i.vx*t,i.y+=i.vy*t,(i.x<0||i.x>this.canvas.width)&&(i.vx*=-1),(i.y<0||i.y>this.canvas.height)&&(i.vy*=-1),i.x=Math.max(0,Math.min(this.canvas.width,i.x)),i.y=Math.max(0,Math.min(this.canvas.height,i.y))}drawTrailEffect(){if(this.config.showTrail){this.ctx.save();for(const i of this.particles){if(i.trailPositions.length<2)continue;this.ctx.beginPath(),this.ctx.moveTo(i.trailPositions[0].x,i.trailPositions[0].y);for(let t=1;t<i.trailPositions.length;t++)this.ctx.lineTo(i.trailPositions[t].x,i.trailPositions[t].y);const t=1.2*i.size;this.ctx.lineWidth=t,this.ctx.lineCap="round",this.ctx.lineJoin="round";const s=i.trailPositions[0],e=i.trailPositions[i.trailPositions.length-1],a=this.ctx.createLinearGradient(s.x,s.y,e.x,e.y),n=this.parseColor(i.color),r=.35;a.addColorStop(0,`rgba(${n.r}, ${n.g}, ${n.b}, ${r})`),a.addColorStop(.3,`rgba(${n.r}, ${n.g}, ${n.b}, ${.6*r})`),a.addColorStop(.7,`rgba(${n.r}, ${n.g}, ${n.b}, ${.2*r})`),a.addColorStop(1,`rgba(${n.r}, ${n.g}, ${n.b}, 0)`),this.ctx.strokeStyle=a,this.ctx.stroke()}this.ctx.restore()}}parseColor(i){if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3]),a:parseFloat(t[4])}}else if(i.startsWith("rgb")){const t=i.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3])}}else if(i.startsWith("#")){let t,s,e,a=i.replace("#","");if(3===a.length)t=parseInt(a[0]+a[0],16),s=parseInt(a[1]+a[1],16),e=parseInt(a[2]+a[2],16);else{if(6!==a.length)return{r:255,g:255,b:255};t=parseInt(a.substring(0,2),16),s=parseInt(a.substring(2,4),16),e=parseInt(a.substring(4,6),16)}return{r:t,g:s,b:e}}return{r:255,g:255,b:255}}drawParticles(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);let i=this.config.canvasBackgroundColor;if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t){const s=t[1],e=t[2],a=t[3];parseFloat(t[4])<1&&(i=`rgb(${s}, ${e}, ${a})`)}}if(this.ctx.fillStyle=i,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.drawTrailEffect(),this.config.showLine)for(let i=0;i<this.particles.length;i++)for(let t=i+1;t<this.particles.length;t++){const s=this.particles[i].x-this.particles[t].x,e=this.particles[i].y-this.particles[t].y,a=Math.sqrt(s*s+e*e);if(a<this.config.linkDistance){const s=this.config.lineOpacity*(1-a/this.config.linkDistance);this.ctx.strokeStyle=this.config.lineColor,this.ctx.globalAlpha=s,this.ctx.lineWidth=this.config.lineWidth,this.ctx.beginPath(),this.ctx.moveTo(this.particles[i].x,this.particles[i].y),this.ctx.lineTo(this.particles[t].x,this.particles[t].y),this.ctx.stroke()}}this.ctx.globalAlpha=1;for(const i of this.particles){const t=i.size*(1+.2*Math.sin(i.pulse));this.config.particleBlur>0&&(this.ctx.shadowColor=i.color,this.ctx.shadowBlur=4*this.config.particleBlur),this.ctx.beginPath(),this.ctx.arc(i.x,i.y,t,0,2*Math.PI),this.ctx.fillStyle=i.color,this.ctx.fill(),this.ctx.shadowBlur=0}}updateFPS(){this.frameCount++;const i=Date.now(),t=i-this.lastFpsUpdate;t>=1e3&&(this.fps=Math.round(1e3*this.frameCount/t),this.frameCount=0,this.lastFpsUpdate=i)}animate(){if(!this.isRunning)return;const i=performance.now(),t=i-this.lastFrameTime,s=Math.min(Math.max(t,1),100);this.updateParticles(s),this.drawParticles(),this.updateFPS(),this.lastFrameTime=i,this.animationId=requestAnimationFrame(()=>this.animate())}start(){this.isRunning||(this.isRunning=!0,this.lastFrameTime=performance.now(),this.animate())}pause(){this.isRunning=!1,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null)}reset(){const i=this.isRunning;i&&this.pause(),this.createParticles(),i?this.start():this.drawParticles()}resize(){if(this.config.isBackground){const i=this.canvas.width,t=this.canvas.height,s=window.innerWidth,e=window.innerHeight;if(this.canvas.width=s,this.canvas.height=e,this.particles.length>0){const a=s/i,n=e/t;for(const i of this.particles)if(i.x*=a,i.y*=n,i.x=Math.max(0,Math.min(s,i.x)),i.y=Math.max(0,Math.min(e,i.y)),(i.x<=0||i.x>=s)&&(i.vx*=-1),(i.y<=0||i.y>=e)&&(i.vy*=-1),this.config.showTrail)for(let t=0;t<i.trailPositions.length;t++){const r=i.trailPositions[t];r.x*=a,r.y*=n,r.x=Math.max(0,Math.min(s,r.x)),r.y=Math.max(0,Math.min(e,r.y))}this.drawParticles()}else this.createParticles(),this.drawParticles()}}destroy(){this.pause(),this.canvas&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)}bindEvents(){window.addEventListener("resize",()=>{this.config.isBackground&&(this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=window.setTimeout(()=>{this.resize()},150))}),document.addEventListener("visibilitychange",()=>{document.hidden?(this.wasRunningBeforeHide=this.isRunning,this.isRunning&&this.pause()):(this.wasRunningBeforeHide&&this.start(),this.wasRunningBeforeHide=!1)})}}const s=t;return i.ParticleCanvas=t,i.default=s,Object.defineProperty(i,"__esModule",{value:!0}),i}({});
|
|
1
|
+
var ParticleCanvasPro=function(i){"use strict";class t{constructor(i={}){this.MAX_PARTICLE_NUMBER=800,this.MAX_PARTICLE_SPEED=3,this.MAX_PARTICLE_SIZE=10,this.MAX_LINK_DISTANCE=300,this.MAX_LINE_WIDTH=5,this.MAX_LINE_OPACITY=1,this.MAX_TRAIL_VALUE=1,this.MAX_PARTICLE_BLUR=5,this.MAX_TRAIL_INTENSITY=5;const t=this.validateAndLimitOptions(i);this.config={canvasContainer:t.canvasContainer||document.body,isBackground:void 0===t.isBackground||t.isBackground,canvasBackgroundColor:t.canvasBackgroundColor||"rgb(10, 10, 25)",particleNumber:t.particleNumber||150,particleSpeed:t.particleSpeed||1,particleSize:t.particleSize||5,particleColor:t.particleColor||"rgba(156, 74, 255, 0.6)",particleBlur:void 0!==t.particleBlur?t.particleBlur:2,lineWidth:t.lineWidth||1,lineColor:t.lineColor||"#ffffff",lineOpacity:t.lineOpacity||.3,linkDistance:t.linkDistance||120,showLine:void 0===t.showLine||t.showLine,canvasSize:t.canvasSize||[800,600],showTrail:void 0===t.showTrail||t.showTrail,trailIntensity:t.trailIntensity||2},this.particles=[],this.animationId=null,this.isRunning=!1,this.lastTime=0,this.fps=60,this.fpsInterval=1e3/60,this.then=Date.now(),this.frameCount=0,this.lastFpsUpdate=Date.now(),this.resizeTimer=null,this.wasRunningBeforeHide=!1,this.lastFrameTime=performance.now(),this.init()}validateAndLimitOptions(i){const t=Object.assign({},i);return void 0!==i.particleNumber&&(i.particleNumber>this.MAX_PARTICLE_NUMBER?(console.warn(`Warning: particleNumber (${i.particleNumber}) exceeds maximum allowed value (${this.MAX_PARTICLE_NUMBER}). Using maximum value instead.`),t.particleNumber=this.MAX_PARTICLE_NUMBER):i.particleNumber<1&&(console.warn(`Warning: particleNumber (${i.particleNumber}) is below minimum value (1). Using default value instead.`),t.particleNumber=150)),void 0!==i.particleSpeed&&(i.particleSpeed>this.MAX_PARTICLE_SPEED?(console.warn(`Warning: particleSpeed (${i.particleSpeed}) exceeds maximum allowed value (${this.MAX_PARTICLE_SPEED}). Using maximum value instead.`),t.particleSpeed=this.MAX_PARTICLE_SPEED):i.particleSpeed<0&&(console.warn(`Warning: particleSpeed (${i.particleSpeed}) is below minimum value (0). Using default value instead.`),t.particleSpeed=1)),void 0!==i.particleSize&&(i.particleSize>this.MAX_PARTICLE_SIZE?(console.warn(`Warning: particleSize (${i.particleSize}) exceeds maximum allowed value (${this.MAX_PARTICLE_SIZE}). Using maximum value instead.`),t.particleSize=this.MAX_PARTICLE_SIZE):i.particleSize<1&&(console.warn(`Warning: particleSize (${i.particleSize}) is below minimum value (1). Using default value instead.`),t.particleSize=3)),void 0!==i.particleBlur&&(i.particleBlur>this.MAX_PARTICLE_BLUR?(console.warn(`Warning: particleBlur (${i.particleBlur}) exceeds maximum allowed value (${this.MAX_PARTICLE_BLUR}). Using maximum value instead.`),t.particleBlur=this.MAX_PARTICLE_BLUR):i.particleBlur<0&&(console.warn(`Warning: particleBlur (${i.particleBlur}) is below minimum value (0). Using default value instead.`),t.particleBlur=2)),void 0!==i.linkDistance&&(i.linkDistance>this.MAX_LINK_DISTANCE?(console.warn(`Warning: linkDistance (${i.linkDistance}) exceeds maximum allowed value (${this.MAX_LINK_DISTANCE}). Using maximum value instead.`),t.linkDistance=this.MAX_LINK_DISTANCE):i.linkDistance<10&&(console.warn(`Warning: linkDistance (${i.linkDistance}) is below minimum value (10). Using default value instead.`),t.linkDistance=120)),void 0!==i.lineWidth&&(i.lineWidth>this.MAX_LINE_WIDTH?(console.warn(`Warning: lineWidth (${i.lineWidth}) exceeds maximum allowed value (${this.MAX_LINE_WIDTH}). Using maximum value instead.`),t.lineWidth=this.MAX_LINE_WIDTH):i.lineWidth<0&&(console.warn(`Warning: lineWidth (${i.lineWidth}) is below minimum value (0). Using default value instead.`),t.lineWidth=1)),void 0!==i.lineOpacity&&(i.lineOpacity>this.MAX_LINE_OPACITY?(console.warn(`Warning: lineOpacity (${i.lineOpacity}) exceeds maximum allowed value (${this.MAX_LINE_OPACITY}). Using maximum value instead.`),t.lineOpacity=this.MAX_LINE_OPACITY):i.lineOpacity<0&&(console.warn(`Warning: lineOpacity (${i.lineOpacity}) is below minimum value (0). Using default value instead.`),t.lineOpacity=.3)),void 0!==i.trailIntensity&&(i.trailIntensity>this.MAX_TRAIL_INTENSITY?(console.warn(`Warning: trailIntensity (${i.trailIntensity}) exceeds maximum allowed value (${this.MAX_TRAIL_INTENSITY}). Using maximum value instead.`),t.trailIntensity=this.MAX_TRAIL_INTENSITY):i.trailIntensity<1&&(console.warn(`Warning: trailIntensity (${i.trailIntensity}) is below minimum value (1). Using default value instead.`),t.trailIntensity=2)),t}init(){this.canvas=document.createElement("canvas");const i=this.canvas.getContext("2d");if(!i)throw new Error("Could not get 2D context from canvas");if(this.ctx=i,"string"==typeof this.config.canvasContainer){const i=document.querySelector(this.config.canvasContainer);if(!i)throw new Error(`Canvas container not found: ${this.config.canvasContainer}`);this.container=i}else this.container=this.config.canvasContainer;this.container?(this.container.appendChild(this.canvas),this.setupCanvas(),this.createParticles(),this.bindEvents()):console.error("Canvas container not found")}setupCanvas(){if(this.config.isBackground)this.canvas.style.position="fixed",this.canvas.style.top="0",this.canvas.style.left="0",this.canvas.style.width="100%",this.canvas.style.height="100%",this.canvas.style.zIndex="-1",this.canvas.width=window.innerWidth,this.canvas.height=window.innerHeight;else{this.canvas.style.display="block";const[i,t]=this.config.canvasSize;this.canvas.width=i,this.canvas.height=t,this.canvas.style.width=i+"px",this.canvas.style.height=t+"px"}this.canvas.style.pointerEvents="none"}createParticles(){this.particles=[];const i=Array.isArray(this.config.particleColor);for(let t=0;t<this.config.particleNumber;t++){let t;if(i){const i=this.config.particleColor;t=i[Math.floor(Math.random()*i.length)]}else t=this.config.particleColor;this.particles.push({x:Math.random()*this.canvas.width,y:Math.random()*this.canvas.height,vx:2*(Math.random()-.5)*this.config.particleSpeed,vy:2*(Math.random()-.5)*this.config.particleSpeed,size:this.config.particleSize,color:t,originalColor:t,pulse:0,pulseSpeed:.05*Math.random()+.02,trailPositions:[]})}}updateParticles(i){const t=i/16.67;for(const i of this.particles)i.pulse+=i.pulseSpeed*t,i.pulse>2*Math.PI&&(i.pulse=0),this.config.showTrail&&(i.trailPositions.unshift({x:i.x,y:i.y}),i.trailPositions.length>10*this.config.trailIntensity&&(i.trailPositions.length=10*this.config.trailIntensity)),i.x+=i.vx*t,i.y+=i.vy*t,(i.x<0||i.x>this.canvas.width)&&(i.vx*=-1),(i.y<0||i.y>this.canvas.height)&&(i.vy*=-1),i.x=Math.max(0,Math.min(this.canvas.width,i.x)),i.y=Math.max(0,Math.min(this.canvas.height,i.y))}drawTrailEffect(){if(this.config.showTrail){this.ctx.save();for(const i of this.particles){if(i.trailPositions.length<2)continue;this.ctx.beginPath(),this.ctx.moveTo(i.trailPositions[0].x,i.trailPositions[0].y);for(let t=1;t<i.trailPositions.length;t++)this.ctx.lineTo(i.trailPositions[t].x,i.trailPositions[t].y);const t=1.2*i.size;this.ctx.lineWidth=t,this.ctx.lineCap="round",this.ctx.lineJoin="round";const s=i.trailPositions[0],e=i.trailPositions[i.trailPositions.length-1],a=this.ctx.createLinearGradient(s.x,s.y,e.x,e.y),n=this.parseColor(i.color),r=.35;a.addColorStop(0,`rgba(${n.r}, ${n.g}, ${n.b}, ${r})`),a.addColorStop(.3,`rgba(${n.r}, ${n.g}, ${n.b}, ${.6*r})`),a.addColorStop(.7,`rgba(${n.r}, ${n.g}, ${n.b}, ${.2*r})`),a.addColorStop(1,`rgba(${n.r}, ${n.g}, ${n.b}, 0)`),this.ctx.strokeStyle=a,this.ctx.stroke()}this.ctx.restore()}}parseColor(i){if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3]),a:parseFloat(t[4])}}else if(i.startsWith("rgb")){const t=i.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);if(t)return{r:parseInt(t[1]),g:parseInt(t[2]),b:parseInt(t[3])}}else if(i.startsWith("#")){let t,s,e,a=i.replace("#","");if(3===a.length)t=parseInt(a[0]+a[0],16),s=parseInt(a[1]+a[1],16),e=parseInt(a[2]+a[2],16);else{if(6!==a.length)return{r:255,g:255,b:255};t=parseInt(a.substring(0,2),16),s=parseInt(a.substring(2,4),16),e=parseInt(a.substring(4,6),16)}return{r:t,g:s,b:e}}return{r:255,g:255,b:255}}drawParticles(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);let i=this.config.canvasBackgroundColor;if(i.startsWith("rgba")){const t=i.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/);if(t){const s=t[1],e=t[2],a=t[3];parseFloat(t[4])<1&&(i=`rgb(${s}, ${e}, ${a})`)}}if(this.ctx.fillStyle=i,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.drawTrailEffect(),this.config.showLine)for(let i=0;i<this.particles.length;i++)for(let t=i+1;t<this.particles.length;t++){const s=this.particles[i].x-this.particles[t].x,e=this.particles[i].y-this.particles[t].y,a=Math.sqrt(s*s+e*e);if(a<this.config.linkDistance){const s=this.config.lineOpacity*(1-a/this.config.linkDistance);this.ctx.strokeStyle=this.config.lineColor,this.ctx.globalAlpha=s,this.ctx.lineWidth=this.config.lineWidth,this.ctx.beginPath(),this.ctx.moveTo(this.particles[i].x,this.particles[i].y),this.ctx.lineTo(this.particles[t].x,this.particles[t].y),this.ctx.stroke()}}this.ctx.globalAlpha=1;for(const i of this.particles){const t=i.size*(1+.2*Math.sin(i.pulse));this.config.particleBlur>0&&(this.ctx.shadowColor=i.color,this.ctx.shadowBlur=4*this.config.particleBlur),this.ctx.beginPath(),this.ctx.arc(i.x,i.y,t,0,2*Math.PI),this.ctx.fillStyle=i.color,this.ctx.fill(),this.ctx.shadowBlur=0}}updateFPS(){this.frameCount++;const i=Date.now(),t=i-this.lastFpsUpdate;t>=1e3&&(this.fps=Math.round(1e3*this.frameCount/t),this.frameCount=0,this.lastFpsUpdate=i)}animate(){if(!this.isRunning)return;const i=performance.now(),t=i-this.lastFrameTime,s=Math.min(Math.max(t,1),100);this.updateParticles(s),this.drawParticles(),this.updateFPS(),this.lastFrameTime=i,this.animationId=requestAnimationFrame(()=>this.animate())}start(){this.isRunning||(this.isRunning=!0,this.lastFrameTime=performance.now(),this.animate())}pause(){this.isRunning=!1,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null)}reset(){const i=this.isRunning;i&&this.pause(),this.createParticles(),i?this.start():this.drawParticles()}resize(){if(this.config.isBackground){const i=this.canvas.width,t=this.canvas.height,s=window.innerWidth,e=window.innerHeight;if(this.canvas.width=s,this.canvas.height=e,this.particles.length>0){const a=s/i,n=e/t;for(const i of this.particles)if(i.x*=a,i.y*=n,i.x=Math.max(0,Math.min(s,i.x)),i.y=Math.max(0,Math.min(e,i.y)),(i.x<=0||i.x>=s)&&(i.vx*=-1),(i.y<=0||i.y>=e)&&(i.vy*=-1),this.config.showTrail)for(let t=0;t<i.trailPositions.length;t++){const r=i.trailPositions[t];r.x*=a,r.y*=n,r.x=Math.max(0,Math.min(s,r.x)),r.y=Math.max(0,Math.min(e,r.y))}this.drawParticles()}else this.createParticles(),this.drawParticles()}}destroy(){this.pause(),this.canvas&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas)}bindEvents(){window.addEventListener("resize",()=>{this.config.isBackground&&(this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=window.setTimeout(()=>{this.resize()},150))}),document.addEventListener("visibilitychange",()=>{document.hidden?(this.wasRunningBeforeHide=this.isRunning,this.isRunning&&this.pause()):(this.wasRunningBeforeHide&&this.start(),this.wasRunningBeforeHide=!1)})}}const s=t;return i.ParticleCanvas=t,i.default=s,Object.defineProperty(i,"__esModule",{value:!0}),i}({});
|
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 高性能粒子系统
|
|
3
|
-
* 使用Canvas实现可配置的粒子动画效果,支持背景模式和内嵌模式
|
|
4
|
-
*/
|
|
5
|
-
import { ParticleCanvasOptions } from './types';
|
|
6
|
-
declare class ParticleCanvas {
|
|
7
|
-
private config;
|
|
8
|
-
private particles;
|
|
9
|
-
private animationId;
|
|
10
|
-
private isRunning;
|
|
11
|
-
private lastTime;
|
|
12
|
-
private fps;
|
|
13
|
-
private fpsInterval;
|
|
14
|
-
private then;
|
|
15
|
-
private frameCount;
|
|
16
|
-
private lastFpsUpdate;
|
|
17
|
-
private canvas;
|
|
18
|
-
private ctx;
|
|
19
|
-
private container;
|
|
20
|
-
private resizeTimer;
|
|
21
|
-
private wasRunningBeforeHide;
|
|
22
|
-
private readonly MAX_PARTICLE_NUMBER;
|
|
23
|
-
private readonly MAX_PARTICLE_SPEED;
|
|
24
|
-
private readonly MAX_PARTICLE_SIZE;
|
|
25
|
-
private readonly MAX_LINK_DISTANCE;
|
|
26
|
-
private readonly MAX_LINE_WIDTH;
|
|
27
|
-
private readonly MAX_LINE_OPACITY;
|
|
28
|
-
private readonly MAX_TRAIL_VALUE;
|
|
29
|
-
private readonly MAX_PARTICLE_BLUR;
|
|
30
|
-
private readonly MAX_TRAIL_INTENSITY;
|
|
31
|
-
private lastFrameTime;
|
|
32
|
-
/**
|
|
33
|
-
* 初始化配置
|
|
34
|
-
* @param {ParticleCanvasOptions} options - 配置对象
|
|
35
|
-
*/
|
|
36
|
-
constructor(options?: ParticleCanvasOptions);
|
|
37
|
-
/**
|
|
38
|
-
* 验证并限制配置选项,确保参数在合理范围内
|
|
39
|
-
* @param options 用户提供的配置选项
|
|
40
|
-
* @returns 验证后的配置选项
|
|
41
|
-
*/
|
|
42
|
-
private validateAndLimitOptions;
|
|
43
|
-
/**
|
|
44
|
-
* 初始化粒子系统
|
|
45
|
-
* 创建画布、设置容器、创建粒子、绑定事件
|
|
46
|
-
*/
|
|
47
|
-
private init;
|
|
48
|
-
/**
|
|
49
|
-
* 设置画布样式和尺寸
|
|
50
|
-
* 根据配置决定是背景模式还是内嵌模式
|
|
51
|
-
*/
|
|
52
|
-
private setupCanvas;
|
|
53
|
-
/**
|
|
54
|
-
* 创建粒子数组
|
|
55
|
-
* 根据配置生成指定数量的粒子
|
|
56
|
-
*/
|
|
57
|
-
private createParticles;
|
|
58
|
-
/**
|
|
59
|
-
* 更新粒子状态
|
|
60
|
-
* 计算每个粒子的新位置和状态
|
|
61
|
-
* @param deltaTime 时间增量(毫秒)
|
|
62
|
-
*/
|
|
63
|
-
private updateParticles;
|
|
64
|
-
/**
|
|
65
|
-
* 绘制粒子轨迹效果
|
|
66
|
-
* 在粒子后面绘制自然的光影拖尾效果
|
|
67
|
-
*/
|
|
68
|
-
private drawTrailEffect;
|
|
69
|
-
/**
|
|
70
|
-
* 解析颜色字符串为RGB对象
|
|
71
|
-
* @param colorStr 颜色字符串
|
|
72
|
-
* @returns RGB对象
|
|
73
|
-
*/
|
|
74
|
-
private parseColor;
|
|
75
|
-
/**
|
|
76
|
-
* 绘制粒子和连线
|
|
77
|
-
* 在画布上渲染粒子系统
|
|
78
|
-
*/
|
|
79
|
-
private drawParticles;
|
|
80
|
-
/**
|
|
81
|
-
* 更新FPS计数器
|
|
82
|
-
* 计算并更新当前帧率
|
|
83
|
-
*/
|
|
84
|
-
private updateFPS;
|
|
85
|
-
/**
|
|
86
|
-
* 动画循环
|
|
87
|
-
* 使用requestAnimationFrame实现平滑动画
|
|
88
|
-
*/
|
|
89
|
-
private animate;
|
|
90
|
-
/**
|
|
91
|
-
* 开始粒子动画
|
|
92
|
-
*/
|
|
93
|
-
start(): void;
|
|
94
|
-
/**
|
|
95
|
-
* 暂停粒子动画
|
|
96
|
-
*/
|
|
97
|
-
pause(): void;
|
|
98
|
-
/**
|
|
99
|
-
* 重置粒子系统
|
|
100
|
-
* 重新创建粒子并开始动画
|
|
101
|
-
*/
|
|
102
|
-
reset(): void;
|
|
103
|
-
/**
|
|
104
|
-
* 调整画布尺寸
|
|
105
|
-
* 主要用于响应窗口大小变化,优化性能
|
|
106
|
-
*/
|
|
107
|
-
resize(): void;
|
|
108
|
-
/**
|
|
109
|
-
* 销毁粒子系统
|
|
110
|
-
* 停止动画并移除画布
|
|
111
|
-
*/
|
|
112
|
-
destroy(): void;
|
|
113
|
-
/**
|
|
114
|
-
* 绑定事件监听器
|
|
115
|
-
*/
|
|
116
|
-
private bindEvents;
|
|
117
|
-
}
|
|
118
|
-
export default ParticleCanvas;
|
|
1
|
+
/**
|
|
2
|
+
* 高性能粒子系统
|
|
3
|
+
* 使用Canvas实现可配置的粒子动画效果,支持背景模式和内嵌模式
|
|
4
|
+
*/
|
|
5
|
+
import { ParticleCanvasOptions } from './types';
|
|
6
|
+
declare class ParticleCanvas {
|
|
7
|
+
private config;
|
|
8
|
+
private particles;
|
|
9
|
+
private animationId;
|
|
10
|
+
private isRunning;
|
|
11
|
+
private lastTime;
|
|
12
|
+
private fps;
|
|
13
|
+
private fpsInterval;
|
|
14
|
+
private then;
|
|
15
|
+
private frameCount;
|
|
16
|
+
private lastFpsUpdate;
|
|
17
|
+
private canvas;
|
|
18
|
+
private ctx;
|
|
19
|
+
private container;
|
|
20
|
+
private resizeTimer;
|
|
21
|
+
private wasRunningBeforeHide;
|
|
22
|
+
private readonly MAX_PARTICLE_NUMBER;
|
|
23
|
+
private readonly MAX_PARTICLE_SPEED;
|
|
24
|
+
private readonly MAX_PARTICLE_SIZE;
|
|
25
|
+
private readonly MAX_LINK_DISTANCE;
|
|
26
|
+
private readonly MAX_LINE_WIDTH;
|
|
27
|
+
private readonly MAX_LINE_OPACITY;
|
|
28
|
+
private readonly MAX_TRAIL_VALUE;
|
|
29
|
+
private readonly MAX_PARTICLE_BLUR;
|
|
30
|
+
private readonly MAX_TRAIL_INTENSITY;
|
|
31
|
+
private lastFrameTime;
|
|
32
|
+
/**
|
|
33
|
+
* 初始化配置
|
|
34
|
+
* @param {ParticleCanvasOptions} options - 配置对象
|
|
35
|
+
*/
|
|
36
|
+
constructor(options?: ParticleCanvasOptions);
|
|
37
|
+
/**
|
|
38
|
+
* 验证并限制配置选项,确保参数在合理范围内
|
|
39
|
+
* @param options 用户提供的配置选项
|
|
40
|
+
* @returns 验证后的配置选项
|
|
41
|
+
*/
|
|
42
|
+
private validateAndLimitOptions;
|
|
43
|
+
/**
|
|
44
|
+
* 初始化粒子系统
|
|
45
|
+
* 创建画布、设置容器、创建粒子、绑定事件
|
|
46
|
+
*/
|
|
47
|
+
private init;
|
|
48
|
+
/**
|
|
49
|
+
* 设置画布样式和尺寸
|
|
50
|
+
* 根据配置决定是背景模式还是内嵌模式
|
|
51
|
+
*/
|
|
52
|
+
private setupCanvas;
|
|
53
|
+
/**
|
|
54
|
+
* 创建粒子数组
|
|
55
|
+
* 根据配置生成指定数量的粒子
|
|
56
|
+
*/
|
|
57
|
+
private createParticles;
|
|
58
|
+
/**
|
|
59
|
+
* 更新粒子状态
|
|
60
|
+
* 计算每个粒子的新位置和状态
|
|
61
|
+
* @param deltaTime 时间增量(毫秒)
|
|
62
|
+
*/
|
|
63
|
+
private updateParticles;
|
|
64
|
+
/**
|
|
65
|
+
* 绘制粒子轨迹效果
|
|
66
|
+
* 在粒子后面绘制自然的光影拖尾效果
|
|
67
|
+
*/
|
|
68
|
+
private drawTrailEffect;
|
|
69
|
+
/**
|
|
70
|
+
* 解析颜色字符串为RGB对象
|
|
71
|
+
* @param colorStr 颜色字符串
|
|
72
|
+
* @returns RGB对象
|
|
73
|
+
*/
|
|
74
|
+
private parseColor;
|
|
75
|
+
/**
|
|
76
|
+
* 绘制粒子和连线
|
|
77
|
+
* 在画布上渲染粒子系统
|
|
78
|
+
*/
|
|
79
|
+
private drawParticles;
|
|
80
|
+
/**
|
|
81
|
+
* 更新FPS计数器
|
|
82
|
+
* 计算并更新当前帧率
|
|
83
|
+
*/
|
|
84
|
+
private updateFPS;
|
|
85
|
+
/**
|
|
86
|
+
* 动画循环
|
|
87
|
+
* 使用requestAnimationFrame实现平滑动画
|
|
88
|
+
*/
|
|
89
|
+
private animate;
|
|
90
|
+
/**
|
|
91
|
+
* 开始粒子动画
|
|
92
|
+
*/
|
|
93
|
+
start(): void;
|
|
94
|
+
/**
|
|
95
|
+
* 暂停粒子动画
|
|
96
|
+
*/
|
|
97
|
+
pause(): void;
|
|
98
|
+
/**
|
|
99
|
+
* 重置粒子系统
|
|
100
|
+
* 重新创建粒子并开始动画
|
|
101
|
+
*/
|
|
102
|
+
reset(): void;
|
|
103
|
+
/**
|
|
104
|
+
* 调整画布尺寸
|
|
105
|
+
* 主要用于响应窗口大小变化,优化性能
|
|
106
|
+
*/
|
|
107
|
+
resize(): void;
|
|
108
|
+
/**
|
|
109
|
+
* 销毁粒子系统
|
|
110
|
+
* 停止动画并移除画布
|
|
111
|
+
*/
|
|
112
|
+
destroy(): void;
|
|
113
|
+
/**
|
|
114
|
+
* 绑定事件监听器
|
|
115
|
+
*/
|
|
116
|
+
private bindEvents;
|
|
117
|
+
}
|
|
118
|
+
export default ParticleCanvas;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from './types';
|
|
2
|
-
import ParticleCanvas from './ParticleCanvas';
|
|
3
|
-
declare const ParticleCanvasPro: typeof ParticleCanvas;
|
|
4
|
-
export default ParticleCanvasPro;
|
|
5
|
-
export { ParticleCanvas };
|
|
1
|
+
export * from './types';
|
|
2
|
+
import ParticleCanvas from './ParticleCanvas';
|
|
3
|
+
declare const ParticleCanvasPro: typeof ParticleCanvas;
|
|
4
|
+
export default ParticleCanvasPro;
|
|
5
|
+
export { ParticleCanvas };
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
export interface Particle {
|
|
2
|
-
x: number;
|
|
3
|
-
y: number;
|
|
4
|
-
vx: number;
|
|
5
|
-
vy: number;
|
|
6
|
-
size: number;
|
|
7
|
-
color: string;
|
|
8
|
-
originalColor: string;
|
|
9
|
-
pulse: number;
|
|
10
|
-
pulseSpeed: number;
|
|
11
|
-
trailPositions: any[];
|
|
12
|
-
}
|
|
13
|
-
export interface ParticleCanvasOptions {
|
|
14
|
-
canvasContainer?: HTMLElement | string;
|
|
15
|
-
canvasSize?: [number, number];
|
|
16
|
-
canvasBackgroundColor?: string;
|
|
17
|
-
isBackground?: boolean;
|
|
18
|
-
particleNumber?: number;
|
|
19
|
-
particleSpeed?: number;
|
|
20
|
-
particleSize?: number;
|
|
21
|
-
particleColor?: string | string[];
|
|
22
|
-
particleBlur?: number;
|
|
23
|
-
showTrail?: boolean;
|
|
24
|
-
trailIntensity?: number;
|
|
25
|
-
showLine?: boolean;
|
|
26
|
-
lineWidth?: number;
|
|
27
|
-
lineColor?: string;
|
|
28
|
-
lineOpacity?: number;
|
|
29
|
-
linkDistance?: number;
|
|
30
|
-
}
|
|
31
|
-
export interface ParticleCanvasConfig {
|
|
32
|
-
canvasContainer: HTMLElement | string;
|
|
33
|
-
canvasSize: [number, number];
|
|
34
|
-
canvasBackgroundColor: string;
|
|
35
|
-
isBackground: boolean;
|
|
36
|
-
particleNumber: number;
|
|
37
|
-
particleSpeed: number;
|
|
38
|
-
particleSize: number;
|
|
39
|
-
particleColor: string | string[];
|
|
40
|
-
particleBlur: number;
|
|
41
|
-
showTrail: boolean;
|
|
42
|
-
trailIntensity: number;
|
|
43
|
-
showLine: boolean;
|
|
44
|
-
lineWidth: number;
|
|
45
|
-
lineColor: string;
|
|
46
|
-
lineOpacity: number;
|
|
47
|
-
linkDistance: number;
|
|
48
|
-
}
|
|
49
|
-
export declare class ParticleCanvas {
|
|
50
|
-
constructor(options?: ParticleCanvasOptions);
|
|
51
|
-
start(): void;
|
|
52
|
-
pause(): void;
|
|
53
|
-
reset(): void;
|
|
54
|
-
resize(): void;
|
|
55
|
-
destroy(): void;
|
|
56
|
-
}
|
|
1
|
+
export interface Particle {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
vx: number;
|
|
5
|
+
vy: number;
|
|
6
|
+
size: number;
|
|
7
|
+
color: string;
|
|
8
|
+
originalColor: string;
|
|
9
|
+
pulse: number;
|
|
10
|
+
pulseSpeed: number;
|
|
11
|
+
trailPositions: any[];
|
|
12
|
+
}
|
|
13
|
+
export interface ParticleCanvasOptions {
|
|
14
|
+
canvasContainer?: HTMLElement | string;
|
|
15
|
+
canvasSize?: [number, number];
|
|
16
|
+
canvasBackgroundColor?: string;
|
|
17
|
+
isBackground?: boolean;
|
|
18
|
+
particleNumber?: number;
|
|
19
|
+
particleSpeed?: number;
|
|
20
|
+
particleSize?: number;
|
|
21
|
+
particleColor?: string | string[];
|
|
22
|
+
particleBlur?: number;
|
|
23
|
+
showTrail?: boolean;
|
|
24
|
+
trailIntensity?: number;
|
|
25
|
+
showLine?: boolean;
|
|
26
|
+
lineWidth?: number;
|
|
27
|
+
lineColor?: string;
|
|
28
|
+
lineOpacity?: number;
|
|
29
|
+
linkDistance?: number;
|
|
30
|
+
}
|
|
31
|
+
export interface ParticleCanvasConfig {
|
|
32
|
+
canvasContainer: HTMLElement | string;
|
|
33
|
+
canvasSize: [number, number];
|
|
34
|
+
canvasBackgroundColor: string;
|
|
35
|
+
isBackground: boolean;
|
|
36
|
+
particleNumber: number;
|
|
37
|
+
particleSpeed: number;
|
|
38
|
+
particleSize: number;
|
|
39
|
+
particleColor: string | string[];
|
|
40
|
+
particleBlur: number;
|
|
41
|
+
showTrail: boolean;
|
|
42
|
+
trailIntensity: number;
|
|
43
|
+
showLine: boolean;
|
|
44
|
+
lineWidth: number;
|
|
45
|
+
lineColor: string;
|
|
46
|
+
lineOpacity: number;
|
|
47
|
+
linkDistance: number;
|
|
48
|
+
}
|
|
49
|
+
export declare class ParticleCanvas {
|
|
50
|
+
constructor(options?: ParticleCanvasOptions);
|
|
51
|
+
start(): void;
|
|
52
|
+
pause(): void;
|
|
53
|
+
reset(): void;
|
|
54
|
+
resize(): void;
|
|
55
|
+
destroy(): void;
|
|
56
|
+
}
|
package/package.json
CHANGED
|
@@ -1,54 +1,58 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "particle-canvas-pro",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "🚀 🚀 一款基于requestAnimationFrame的高性能Canvas粒子系统,专为 Web 场景提供流畅、可配置的视觉动效方案,支持全屏背景与独立画布,提供实时控制、丰富视觉效果与流畅交互体验。",
|
|
5
|
-
"main": "dist/bundle.cjs.js",
|
|
6
|
-
"module": "dist/bundle.esm.js",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"import": {
|
|
10
|
-
"types": "./dist/types/index.d.ts",
|
|
11
|
-
"default": "./dist/bundle.esm.js"
|
|
12
|
-
},
|
|
13
|
-
"require": {
|
|
14
|
-
"types": "./dist/types/index.d.ts",
|
|
15
|
-
"default": "./dist/bundle.cjs.js"
|
|
16
|
-
},
|
|
17
|
-
"default": "./dist/bundle.esm.js"
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"types": "dist/types/index.d.ts",
|
|
21
|
-
"unpkg": "dist/bundle.js",
|
|
22
|
-
"type": "module",
|
|
23
|
-
"files": [
|
|
24
|
-
"dist"
|
|
25
|
-
],
|
|
26
|
-
"scripts": {
|
|
27
|
-
"build": "rollup -c --bundleConfigAsCjs",
|
|
28
|
-
"watch": "rollup -c -w --bundleConfigAsCjs",
|
|
29
|
-
"dev": "serve dist"
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
"particle"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"rollup
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "particle-canvas-pro",
|
|
3
|
+
"version": "1.3.2",
|
|
4
|
+
"description": "🚀 🚀 一款基于requestAnimationFrame的高性能Canvas粒子系统,专为 Web 场景提供流畅、可配置的视觉动效方案,支持全屏背景与独立画布,提供实时控制、丰富视觉效果与流畅交互体验。",
|
|
5
|
+
"main": "dist/bundle.cjs.js",
|
|
6
|
+
"module": "dist/bundle.esm.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": {
|
|
10
|
+
"types": "./dist/types/index.d.ts",
|
|
11
|
+
"default": "./dist/bundle.esm.js"
|
|
12
|
+
},
|
|
13
|
+
"require": {
|
|
14
|
+
"types": "./dist/types/index.d.ts",
|
|
15
|
+
"default": "./dist/bundle.cjs.js"
|
|
16
|
+
},
|
|
17
|
+
"default": "./dist/bundle.esm.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"types": "dist/types/index.d.ts",
|
|
21
|
+
"unpkg": "dist/bundle.js",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "rollup -c --bundleConfigAsCjs",
|
|
28
|
+
"watch": "rollup -c -w --bundleConfigAsCjs",
|
|
29
|
+
"dev": "serve dist"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/shilimingY/particle-canvas-pro.git"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"particle-system",
|
|
37
|
+
"particle",
|
|
38
|
+
"requestanimationframe",
|
|
39
|
+
"canvas",
|
|
40
|
+
"animation",
|
|
41
|
+
"fps",
|
|
42
|
+
"粒子动画",
|
|
43
|
+
"粒子系统",
|
|
44
|
+
"高性能粒子",
|
|
45
|
+
"可配置粒子",
|
|
46
|
+
"全屏背景动画"
|
|
47
|
+
],
|
|
48
|
+
"author": "lebron_shi",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
52
|
+
"rollup": "^4.57.1",
|
|
53
|
+
"typescript": "^5.4.5",
|
|
54
|
+
"tslib": "^2.6.2",
|
|
55
|
+
"rollup-plugin-terser": "^7.0.2",
|
|
56
|
+
"serve": "^14.2.5"
|
|
57
|
+
}
|
|
58
|
+
}
|