@ahmiao666/red-packet-rain-react
Version:
12 lines (11 loc) • 31.6 kB
JavaScript
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");const t={containerWidth:"100%",containerHeight:"100%",count:20,density:5,speed:{min:2,max:6},size:{width:60,height:80},rotation:!0,rotationSpeed:{min:-.02,max:.02},enablePerformanceMode:!0,maxFPS:60,qualityMaxFPS:144,clickEffect:!0,isParticle:!0};class i{constructor(e,i){this.redPackets=[],this.animationId=null,this.isRunning=!1,this.isPaused=!1,this.lastFrameTime=0,this.frameCount=0,this.lastFpsTime=0,this.currentFPS=0,this.lastSpawnTime=0,this.actualWidth=800,this.actualHeight=600,this.redPacketPool=[],this.poolSize=50,this.redPacketDataIndex=0,this.stats={totalCollected:0,totalValue:0,fps:0},this.redPacketImage=null,this.lastClickTime=0,this.clickDebounceDelay=100,this.debugClicks=[],this.particles=[],this.particlePool=[],this.particlePoolSize=100,this.particleConfig={count:15,speed:{min:2,max:8},size:{min:3,max:8},life:{min:800,max:1500},colors:["#FF6B6B"],gravity:.3,friction:.98,spread:2*Math.PI},this.canvas=e,this.ctx=e.getContext("2d"),this.config={...t,...i},this.optimizeConfig(),this.resizeCanvas(),this.initializePool(),this.initializeParticlePool(),this.bindEvents(),this.loadRedPacketImage()}initializePool(){for(let e=0;e<this.poolSize;e++)this.redPacketPool.push(this.createRedPacket())}initializeParticlePool(){for(let e=0;e<this.particlePoolSize;e++)this.particlePool.push(this.createParticle())}createParticle(){return{id:Math.random().toString(36).slice(2,11),x:0,y:0,vx:0,vy:0,size:5,opacity:1,color:"#FFD700",life:1,maxLife:1e3,gravity:.3,friction:.98,rotation:0,rotationSpeed:0}}getParticleFromPool(){return this.particlePool.pop()||this.createParticle()}returnParticleToPool(e){this.particlePool.length<this.particlePoolSize&&this.particlePool.push(e)}resetParticle(e,t,i){const a=this.particleConfig,n=Math.random()*a.spread,r=a.speed.min+Math.random()*(a.speed.max-a.speed.min);e.x=t,e.y=i,e.vx=Math.cos(n)*r,e.vy=Math.sin(n)*r-2*Math.random(),e.size=a.size.min+Math.random()*(a.size.max-a.size.min),e.initialSize=void 0,e.opacity=1,e.color=a.colors[Math.floor(Math.random()*a.colors.length)],e.maxLife=a.life.min+Math.random()*(a.life.max-a.life.min),e.life=e.maxLife,e.gravity=a.gravity,e.friction=a.friction,e.rotation=Math.random()*Math.PI*2,e.rotationSpeed=.2*(Math.random()-.5)}getRedPacketFromPool(){const e=this.redPacketPool.pop()||this.createRedPacket();return this.resetRedPacket(e),e}returnRedPacketToPool(e){this.redPacketPool.length<this.poolSize&&this.redPacketPool.push(e)}getRedPacketData(){if(!this.config.redPackets||"number"==typeof this.config.redPackets)return null;if(Array.isArray(this.config.redPackets)&&this.config.redPackets.length>0){const e=this.config.redPackets[this.redPacketDataIndex];return this.redPacketDataIndex=(this.redPacketDataIndex+1)%this.config.redPackets.length,e}return null}isSpecialRedPacket(e){return!!this.config.isSpecialFn&&("function"==typeof this.config.isSpecialFn?this.config.isSpecialFn(e):"string"==typeof this.config.isSpecialFn&&Boolean(e[this.config.isSpecialFn]))}createRedPacket(){const e=this.getRedPacketData(),t={id:Math.random().toString(36).slice(2,11),x:0,y:0,width:this.config.size.width,height:this.config.size.height,speed:0,rotation:0,rotationSpeed:0,scale:1,opacity:1,collected:!1,value:Math.floor(100*Math.random())+1,type:"normal",originalData:null};return e&&this.isUsingArrayMode()?(t.id=e.id||t.id,t.value=e.value||t.value,t.type=this.isSpecialRedPacket(e)?"special":"normal",t.originalData=e):(t.type="normal",t.originalData=null),t}resetRedPacket(e){const t=this.getRedPacketData();e.x=Math.random()*(this.actualWidth-this.config.size.width),e.y=-this.config.size.height,e.speed=Number(this.config.speed.min)+Math.random()*(Number(this.config.speed.max)-Number(this.config.speed.min)),e.rotation=0,e.rotationSpeed=this.config.rotation?this.config.rotationSpeed.min+Math.random()*(this.config.rotationSpeed.max-this.config.rotationSpeed.min):0,e.scale=.8+.4*Math.random(),e.opacity=1,e.collected=!1,t&&this.isUsingArrayMode()?(e.id=t.id||e.id,e.value=t.value||Math.floor(100*Math.random())+1,e.type=this.isSpecialRedPacket(t)?"special":"normal",e.originalData=t):(e.value=Math.floor(100*Math.random())+1,e.type="normal",e.originalData=null)}optimizeConfig(){this.config.redPackets&&Array.isArray(this.config.redPackets)&&this.config.redPackets.length>0?this.config.count=this.config.redPackets.length:(void 0===this.config.count||null===this.config.count||this.config.count<=0)&&(this.config.count=20)}isUsingArrayMode(){return!!(this.config.redPackets&&Array.isArray(this.config.redPackets)&&this.config.redPackets.length>0)}loadRedPacketImage(){this.config.redPacketImage&&("string"==typeof this.config.redPacketImage?(this.redPacketImage=new Image,this.redPacketImage.src=this.config.redPacketImage):this.redPacketImage=this.config.redPacketImage)}resizeCanvas(){let e=800,t=600;if("string"==typeof this.config.containerWidth&&this.config.containerWidth.includes("%")){const t=this.canvas.parentElement;t&&(e=t.clientWidth*parseFloat(this.config.containerWidth)/100)}else e="number"==typeof this.config.containerWidth?this.config.containerWidth:800;if("string"==typeof this.config.containerHeight&&this.config.containerHeight.includes("%")){const e=this.canvas.parentElement;e&&(t=e.clientHeight*parseFloat(this.config.containerHeight)/100)}else t="number"==typeof this.config.containerHeight?this.config.containerHeight:600;this.canvas.width=this.actualWidth=Math.max(100,Math.min(e,4e3)),this.canvas.height=this.actualHeight=Math.max(100,Math.min(t,4e3))}bindEvents(){this.canvas.addEventListener("click",this.handleClick.bind(this)),this.canvas.addEventListener("touchstart",this.handleTouch.bind(this)),window.addEventListener("resize",this.handleResize.bind(this))}handleClick(e){const t=this.getCanvasCoordinates(e.clientX,e.clientY);this.checkCollision(t.x,t.y,"mouse")}handleTouch(e){e.preventDefault();const t=e.touches[0],i=this.getCanvasCoordinates(t.clientX,t.clientY);this.checkCollision(i.x,i.y,"touch")}getCanvasCoordinates(e,t){const i=this.canvas.getBoundingClientRect(),a=i.width,n=i.height,r=this.canvas.width/a,o=this.canvas.height/n,s=(e-i.left)*r,l=(t-i.top)*o;return this.config.debugMode&&console.log(`🎯 点击坐标转换:\n 客户端坐标: (${e}, ${t})\n Canvas矩形: ${JSON.stringify(i)}\n 缩放比例: (${r.toFixed(3)}, ${o.toFixed(3)})\n 最终坐标: (${s.toFixed(1)}, ${l.toFixed(1)})`),{x:s,y:l}}handleResize(){this.resizeCanvas()}checkCollision(e,t,i="mouse"){const a=Date.now();if(a-this.lastClickTime<this.clickDebounceDelay)return void(this.config.debugMode&&console.log(`🎯 点击被防抖过滤 (间隔: ${a-this.lastClickTime}ms)`));this.lastClickTime=a,this.config.debugMode&&console.log(`🎯 检查碰撞: (${e.toFixed(1)}, ${t.toFixed(1)}) [${i}]`);let n=!1;for(let i=this.redPackets.length-1;i>=0;i--){const a=this.redPackets[i];if(this.isPointInRedPacket(e,t,a)){this.config.debugMode&&console.log(`🎯 命中红包: ${a.id}, 类型: ${a.type}, 价值: ${a.value}`),this.collectRedPacket(a,e,t),this.redPackets.splice(i,1),this.returnRedPacketToPool(a),n=!0;break}}this.config.debugMode&&(this.debugClicks.push({x:e,y:t,time:a,hit:n}),n||(console.log(`🎯 未命中任何红包 - 当前红包数量: ${this.redPackets.length}`),this.redPackets.slice(0,3).forEach((i,a)=>{const n=i.x+i.width/2,r=i.y+i.height/2,o=Math.sqrt((e-n)**2+(t-r)**2);console.log(`红包${a+1}: 中心(${n.toFixed(1)}, ${r.toFixed(1)}), 距离: ${o.toFixed(1)}`)})))}isPointInRedPacket(e,t,i){const a=i.x+i.width/2,n=i.y+i.height/2,r=i.width*i.scale,o=i.height*i.scale,s=r+.1*r,l=o+.1*o,c=e>=a-s/2&&e<=a+s/2&&t>=n-l/2&&t<=n+l/2;return this.config.debugMode&&c&&console.log(`🎯 红包边界检测:\n 红包中心: (${a.toFixed(1)}, ${n.toFixed(1)})\n 原始尺寸: ${r.toFixed(1)} x ${o.toFixed(1)}\n 扩展尺寸: ${s.toFixed(1)} x ${l.toFixed(1)}\n 点击坐标: (${e.toFixed(1)}, ${t.toFixed(1)})\n 距离中心: (${Math.abs(e-a).toFixed(1)}, ${Math.abs(t-n).toFixed(1)})`),c}collectRedPacket(e,t,i){e.collected=!0,this.stats.totalCollected++,this.stats.totalValue+=e.value,!this.config.enablePerformanceMode&&this.config.isParticle&&this.createRedPacketParticles(e,t,i),this.onRedPacketClickCallback&&this.onRedPacketClickCallback({redPacket:e,x:t,y:i,value:e.value})}createRedPacketParticles(e,t,i){const a=this.particleConfig.count,n="special"===e.type?1.5*a:a;for(let a=0;a<n;a++){const a=this.getParticleFromPool();this.resetParticle(a,t,i),"special"===e.type&&(a.color="#FFD700",a.size*=1.3),this.particles.push(a)}this.config.debugMode&&console.log(`🎆 创建了 ${n} 个粒子 [红包类型: ${e.type}]`)}updateParticles(e){const t=e/16.67;for(let i=this.particles.length-1;i>=0;i--){const a=this.particles[i];a.x+=a.vx*t,a.y+=a.vy*t,a.vy+=a.gravity*t,a.vx*=a.friction,a.vy*=a.friction,a.rotation+=a.rotationSpeed*t,a.life-=e;const n=Math.max(0,a.life/a.maxLife);a.opacity=n,a.initialSize||(a.initialSize=a.size);const r=.3+.7*n;a.size=a.initialSize*r,(a.life<=0||a.y>this.actualHeight+50)&&(this.particles.splice(i,1),this.returnParticleToPool(a))}}renderParticles(){const e=this.ctx;for(const t of this.particles){e.save(),e.globalAlpha=t.opacity,e.translate(t.x,t.y),e.rotate(t.rotation);const i=e.createRadialGradient(0,0,0,0,0,t.size);i.addColorStop(0,t.color),i.addColorStop(.7,t.color+"80"),i.addColorStop(1,t.color+"00"),e.fillStyle=i,e.beginPath(),e.arc(0,0,t.size,0,2*Math.PI),e.fill(),"#FFD700"!==t.color||this.config.enablePerformanceMode||(e.shadowColor=t.color,e.shadowBlur=2*t.size,e.beginPath(),e.arc(0,0,.5*t.size,0,2*Math.PI),e.fill()),e.restore()}}spawnRedPacket(){const e=Date.now(),t=1e3/this.config.density;if(e-this.lastSpawnTime>t&&this.redPackets.length<this.config.count){const t=this.getRedPacketFromPool();this.redPackets.push(t),this.lastSpawnTime=e}}updateRedPackets(e){for(let t=this.redPackets.length-1;t>=0;t--){const i=this.redPackets[t];i.y+=i.speed*(e/16.67),this.config.rotation&&(i.rotation+=i.rotationSpeed*(e/16.67)),i.y>this.actualHeight&&(this.redPackets.splice(t,1),this.returnRedPacketToPool(i))}}renderRedPackets(){this.ctx.clearRect(0,0,this.actualWidth,this.actualHeight),this.config.customStyles?.backgroundColor&&(this.ctx.fillStyle=this.config.customStyles.backgroundColor,this.ctx.fillRect(0,0,this.actualWidth,this.actualHeight));for(const e of this.redPackets)this.renderRedPacket(e)}renderRedPacket(e){const t=this.ctx,i=e.x+e.width/2,a=e.y+e.height/2;t.save(),t.globalAlpha=e.opacity,t.translate(i,a),this.config.rotation&&t.rotate(e.rotation),t.scale(e.scale,e.scale),this.config.enablePerformanceMode||"special"!==e.type||(t.shadowColor="#FFD700",t.shadowBlur=10),this.redPacketImage?t.drawImage(this.redPacketImage,-e.width/2,-e.height/2,e.width,e.height):this.drawDefaultRedPacket(t,e),t.restore()}drawDefaultRedPacket(e,t){const i=t.width,a=t.height;e.fillStyle="special"===t.type?"#FFD700":"#FF6B6B",e.fillRect(-i/2,-a/2,i,a),e.strokeStyle=this.config.customStyles?.borderColor||"#FF4444",e.lineWidth=2,e.strokeRect(-i/2,-a/2,i,a),e.fillStyle="#FFFFFF",e.font="20px Arial",e.textAlign="center",e.textBaseline="middle",e.fillText("¥",0,-5),t.value&&(e.font="10px Arial",e.fillText(t.value.toString(),0,8))}animate(e){if(!this.isRunning||this.isPaused)return;const t=1e3/(this.config.enablePerformanceMode?this.config.maxFPS:this.config.qualityMaxFPS||144),i=e-this.lastFrameTime;i<.9*t||(this.lastFrameTime=e,this.updateFPS(e),this.spawnRedPacket(),this.updateRedPackets(i),this.updateParticles(i),this.renderRedPackets(),this.renderParticles(),this.config.debugMode&&this.renderDebugInfo(),this.triggerCallbacks()),this.isRunning&&!this.isPaused&&(this.animationId=requestAnimationFrame(this.animate.bind(this)))}updateFPS(e){this.frameCount++,e-this.lastFpsTime>=1e3&&(this.stats.fps=this.frameCount,this.frameCount=0,this.lastFpsTime=e)}renderDebugInfo(){const e=this.ctx;e.save(),e.fillStyle="rgba(0, 0, 0, 0.8)",e.fillRect(10,10,300,120),e.fillStyle="#00FF00",e.font="14px Arial",e.textAlign="left",e.fillText(`FPS: ${this.stats.fps}`,15,30),e.fillText(`红包数量: ${this.redPackets.length}`,15,50),e.fillText(`粒子数量: ${this.particles.length}`,15,70),e.fillText(`Canvas尺寸: ${this.actualWidth}x${this.actualHeight}`,15,90),e.fillText(`点击记录: ${this.debugClicks.length}`,15,110);for(const t of this.redPackets){const i=t.x+t.width/2,a=t.y+t.height/2,n=t.width*t.scale,r=t.height*t.scale,o=n+.1*n,s=r+.1*r;e.strokeStyle="rgba(255, 0, 0, 0.5)",e.lineWidth=1,e.strokeRect(i-n/2,a-r/2,n,r),e.strokeStyle="rgba(0, 255, 0, 0.7)",e.lineWidth=2,e.strokeRect(i-o/2,a-s/2,o,s),e.fillStyle="rgba(0, 255, 255, 0.8)",e.fillRect(i-2,a-2,4,4)}const t=Date.now();for(const i of this.debugClicks){const a=t-i.time;if(a<2e3){const t=Math.max(0,1-a/2e3);e.fillStyle=i.hit?`rgba(0, 255, 0, ${t})`:`rgba(255, 0, 0, ${t})`,e.fillRect(i.x-5,i.y-5,10,10),e.strokeStyle=i.hit?`rgba(0, 255, 0, ${t})`:`rgba(255, 0, 0, ${t})`,e.lineWidth=2,e.beginPath(),e.arc(i.x,i.y,15,0,2*Math.PI),e.stroke()}}e.restore()}triggerCallbacks(){this.onAnimationStateChangeCallback&&this.onAnimationStateChangeCallback({isRunning:this.isRunning,isPaused:this.isPaused,totalCollected:this.stats.totalCollected,currentRedPackets:[...this.redPackets],fps:this.stats.fps}),this.onPerformanceUpdateCallback&&this.onPerformanceUpdateCallback({fps:this.stats.fps,renderTime:0,updateTime:0,totalRedPackets:this.stats.totalCollected,activeRedPackets:this.redPackets.length})}start(){this.isRunning||(this.isRunning=!0,this.isPaused=!1,this.lastFrameTime=performance.now(),this.animate(this.lastFrameTime))}stop(){this.isRunning=!1,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null)}pause(){this.isPaused=!0}resume(){this.isPaused&&this.isRunning&&(this.isPaused=!1,this.lastFrameTime=performance.now(),this.animate(this.lastFrameTime))}clear(){this.redPackets.forEach(e=>this.returnRedPacketToPool(e)),this.redPackets=[],this.particles.forEach(e=>this.returnParticleToPool(e)),this.particles=[],this.ctx.clearRect(0,0,this.actualWidth,this.actualHeight),this.stats.totalCollected=0,this.stats.totalValue=0}updateConfig(e){this.config={...this.config,...e},this.optimizeConfig(),this.resizeCanvas(),e.redPacketImage&&this.loadRedPacketImage(),e.redPackets&&(this.redPacketDataIndex=0)}getStats(){return{fps:this.stats.fps,renderTime:0,updateTime:0,totalRedPackets:this.stats.totalCollected,activeRedPackets:this.redPackets.length}}getCollectionStats(){return{totalCollected:this.stats.totalCollected,totalValue:this.stats.totalValue}}setPerformanceMode(e){this.config.enablePerformanceMode=e}getPerformanceMode(){return this.config.enablePerformanceMode}onRedPacketClick(e){this.onRedPacketClickCallback=e}onAnimationStateChange(e){this.onAnimationStateChangeCallback=e}onPerformanceUpdate(e){this.onPerformanceUpdateCallback=e}setParticleConfig(e){this.particleConfig={...this.particleConfig,...e}}getParticleConfig(){return{...this.particleConfig}}destroy(){this.stop(),this.clear(),this.debugClicks=[],this.lastClickTime=0,this.particlePool=[],this.canvas.removeEventListener("click",this.handleClick.bind(this)),this.canvas.removeEventListener("touchstart",this.handleTouch.bind(this)),window.removeEventListener("resize",this.handleResize.bind(this))}}var a,n={exports:{}},r={};var o,s={};
/**
* @license React
* react-jsx-runtime.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/"production"===process.env.NODE_ENV?n.exports=function(){if(a)return r;a=1;var e=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function i(t,i,a){var n=null;if(void 0!==a&&(n=""+a),void 0!==i.key&&(n=""+i.key),"key"in i)for(var r in a={},i)"key"!==r&&(a[r]=i[r]);else a=i;return i=a.ref,{$$typeof:e,type:t,key:n,ref:void 0!==i?i:null,props:a}}return r.Fragment=t,r.jsx=i,r.jsxs=i,r}():n.exports=(o||(o=1,"production"!==process.env.NODE_ENV&&function(){function t(e){if(null==e)return null;if("function"==typeof e)return e.$$typeof===R?null:e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case g:return"Fragment";case p:return"Profiler";case m:return"StrictMode";case x:return"Suspense";case k:return"SuspenseList";case S:return"Activity"}if("object"==typeof e)switch("number"==typeof e.tag&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case f:return"Portal";case y:return(e.displayName||"Context")+".Provider";case P:return(e._context.displayName||"Context")+".Consumer";case b:var i=e.render;return(e=e.displayName)||(e=""!==(e=i.displayName||i.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case C:return null!==(i=e.displayName||null)?i:t(e.type)||"Memo";case v:i=e._payload,e=e._init;try{return t(e(i))}catch(e){}}return null}function i(e){return""+e}function a(e){try{i(e);var t=!1}catch(e){t=!0}if(t){var a=(t=console).error,n="function"==typeof Symbol&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return a.call(t,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",n),i(e)}}function n(e){if(e===g)return"<>";if("object"==typeof e&&null!==e&&e.$$typeof===v)return"<...>";try{var i=t(e);return i?"<"+i+">":"<...>"}catch(e){return"<...>"}}function r(){return Error("react-stack-top-frame")}function o(){var e=t(this.type);return T[e]||(T[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),void 0!==(e=this.props.ref)?e:null}function l(e,i,n,r,s,l,h,f){var g,m=i.children;if(void 0!==m)if(r)if(w(m)){for(r=0;r<m.length;r++)c(m[r]);Object.freeze&&Object.freeze(m)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else c(m);if(M.call(i,"key")){m=t(e);var p=Object.keys(i).filter(function(e){return"key"!==e});r=0<p.length?"{key: someKey, "+p.join(": ..., ")+": ...}":"{key: someKey}",I[m+r]||(p=0<p.length?"{"+p.join(": ..., ")+": ...}":"{}",console.error('A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',r,m,p,m),I[m+r]=!0)}if(m=null,void 0!==n&&(a(n),m=""+n),function(e){if(M.call(e,"key")){var t=Object.getOwnPropertyDescriptor(e,"key").get;if(t&&t.isReactWarning)return!1}return void 0!==e.key}(i)&&(a(i.key),m=""+i.key),"key"in i)for(var P in n={},i)"key"!==P&&(n[P]=i[P]);else n=i;return m&&function(e,t){function i(){d||(d=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}i.isReactWarning=!0,Object.defineProperty(e,"key",{get:i,configurable:!0})}(n,"function"==typeof e?e.displayName||e.name||"Unknown":e),function(e,t,i,a,n,r,s,l){return i=r.ref,e={$$typeof:u,type:e,key:t,props:r,_owner:n},null!==(void 0!==i?i:null)?Object.defineProperty(e,"ref",{enumerable:!1,get:o}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:s}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:l}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}(e,m,l,0,null===(g=F.A)?null:g.getOwner(),n,h,f)}function c(e){"object"==typeof e&&null!==e&&e.$$typeof===u&&e._store&&(e._store.validated=1)}var d,h=e,u=Symbol.for("react.transitional.element"),f=Symbol.for("react.portal"),g=Symbol.for("react.fragment"),m=Symbol.for("react.strict_mode"),p=Symbol.for("react.profiler"),P=Symbol.for("react.consumer"),y=Symbol.for("react.context"),b=Symbol.for("react.forward_ref"),x=Symbol.for("react.suspense"),k=Symbol.for("react.suspense_list"),C=Symbol.for("react.memo"),v=Symbol.for("react.lazy"),S=Symbol.for("react.activity"),R=Symbol.for("react.client.reference"),F=h.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,M=Object.prototype.hasOwnProperty,w=Array.isArray,j=console.createTask?console.createTask:function(){return null},T={},$=(h={"react-stack-bottom-frame":function(e){return e()}})["react-stack-bottom-frame"].bind(h,r)(),z=j(n(r)),I={};s.Fragment=g,s.jsx=function(e,t,i,a,r){var o=1e4>F.recentlyCreatedOwnerStacks++;return l(e,t,i,!1,0,r,o?Error("react-stack-top-frame"):$,o?j(n(e)):z)},s.jsxs=function(e,t,i,a,r){var o=1e4>F.recentlyCreatedOwnerStacks++;return l(e,t,i,!0,0,r,o?Error("react-stack-top-frame"):$,o?j(n(e)):z)}}()),s);var l=n.exports;const c={card:{background:"#f8f9fa",borderRadius:"8px",padding:"20px",marginBottom:"20px"},whiteCard:{textAlign:"center",padding:"15px",background:"white",borderRadius:"6px",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.1)"},grid:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(200px, 1fr))",gap:"20px"}},d={container:{...c.card,...c.grid},statItem:c.whiteCard,statValue:{fontSize:"2em",fontWeight:"bold",color:"#ff6b6b"},statLabel:{color:"#666",marginTop:"5px"},modeValue:{fontSize:"1.2em",fontWeight:"bold",color:"#ff6b6b"}},h={container:{marginBottom:"20px",display:"flex",gap:"10px",flexWrap:"wrap"},base:{padding:"12px 24px",border:"none",borderRadius:"25px",fontSize:"16px",fontWeight:"600",cursor:"pointer",transition:"all 0.3s ease",boxShadow:"0 4px 15px rgba(0, 0, 0, 0.2)",margin:"5px"},primary:{background:"linear-gradient(45deg, #ff6b6b, #ffa500)",color:"white"},secondary:{background:"#6c757d",color:"white"}},u={container:c.card,title:{margin:"0 0 20px 0",color:"#ff6b6b"},configItem:{display:"flex",alignItems:"center",gap:"10px",marginBottom:"15px"},label:{minWidth:"80px",fontWeight:"600",color:"#333"},slider:{flex:1,height:"6px",background:"#ddd",borderRadius:"3px",outline:"none",appearance:"none"},value:{minWidth:"30px",textAlign:"center",fontWeight:"bold",color:"#ff6b6b"}},f={container:{background:"linear-gradient(135deg, #e8f4f8 0%, #d4e6f1 100%)",borderRadius:"8px",padding:"25px",marginTop:"20px"},title:{color:"#2c3e50",marginTop:0},list:{paddingLeft:"20px"},listItem:{marginBottom:"8px",color:"#34495e"}},g={display:"block",width:"100%",height:"100%"},m=e=>({width:"100%",height:"400px",overflow:"hidden",...e}),p=({value:e,label:t,isMode:i=!1})=>l.jsxs("div",{style:d.statItem,children:[l.jsx("div",{style:i?d.modeValue:d.statValue,children:e}),l.jsx("div",{style:d.statLabel,children:t})]}),P=({stats:e})=>l.jsxs("div",{style:d.container,children:[l.jsx(p,{value:e.fps,label:"FPS"}),l.jsx(p,{value:e.collected,label:"已收集"}),l.jsx(p,{value:`¥${e.totalValue}`,label:"总价值"}),l.jsx(p,{value:e.activeCount,label:"活跃红包"}),l.jsx(p,{value:e.performanceMode,label:"当前模式",isMode:!0})]}),y=({onClick:e,children:t,isPrimary:i=!1})=>{const a={...h.base,...i?h.primary:h.secondary};return l.jsx("button",{style:a,onClick:e,children:t})},b=({onStart:e,onStop:t,onPause:i,onResume:a,onClear:n,onToggleDebug:r,onTogglePerformance:o,onToggleFrameLimit:s,isPerformanceMode:c,isDebugMode:d,isFrameLimitEnabled:u})=>l.jsxs("div",{style:h.container,children:[l.jsx(y,{onClick:e,isPrimary:!0,children:"🚀 开始"}),l.jsx(y,{onClick:t,children:"⏹️ 停止"}),l.jsx(y,{onClick:i,children:"⏸️ 暂停"}),l.jsx(y,{onClick:a,children:"▶️ 继续"}),l.jsx(y,{onClick:n,children:"🧹 清空"}),l.jsxs(y,{onClick:r,isPrimary:d,children:["🐛 ",d?"关闭调试":"调试模式"]}),l.jsxs(y,{onClick:o,isPrimary:c,children:["⚡ ",c?"高质量模式":"性能模式"]}),l.jsxs(y,{onClick:s,isPrimary:u,children:["🎯 ",u?"关闭限制":"启用限制"]})]}),x=({label:e,value:t,min:i,max:a,onChange:n})=>l.jsxs("div",{style:u.configItem,children:[l.jsx("label",{style:u.label,children:e}),l.jsx("input",{style:u.slider,type:"range",min:i,max:a,value:t,onChange:e=>n(parseInt(e.target.value))}),l.jsx("span",{style:u.value,children:t})]}),k=({config:e,onConfigChange:t})=>l.jsxs("div",{style:u.container,children:[l.jsx("h3",{style:u.title,children:"⚙️ 配置调整"}),l.jsx(x,{label:"红包数量",value:e.count||15,min:5,max:50,onChange:e=>t("count",e)}),l.jsx(x,{label:"红包密度",value:e.density||3,min:1,max:10,onChange:e=>t("density",e)}),l.jsx(x,{label:"最小速度",value:e.speed?.min||2,min:1,max:5,onChange:e=>t("minSpeed",e)}),l.jsx(x,{label:"最大速度",value:e.speed?.max||5,min:3,max:10,onChange:e=>t("maxSpeed",e)}),l.jsx(x,{label:"高质量帧率",value:e.qualityMaxFPS||144,min:60,max:240,onChange:e=>t("qualityMaxFPS",e)})]}),C=()=>l.jsxs("div",{style:f.container,children:[l.jsx("h3",{style:f.title,children:"📖 使用说明"}),l.jsx("ul",{style:f.list,children:["🎯 点击红包进行收集,每个红包都有随机的价值","⚡ 金色红包为特殊红包,价值更高","🎛️ 使用滑块实时调整红包参数","📊 观察FPS和性能统计","🔍 性能模式:简化渲染、60FPS限制、对象池复用","🎨 高质量模式:完整视觉效果、144FPS限制、对象池复用","🖥️ 帧率受显示器刷新率限制,会自动检测并调整"].map((e,t)=>l.jsx("li",{style:f.listItem,children:e},t))})]}),{useState:v,useCallback:S}=e,R={count:15,density:3,speed:{min:2,max:5},maxFPS:60,qualityMaxFPS:144,enablePerformanceMode:!0,enableFrameRateLimit:!0,debugMode:!1},{useCallback:F,useEffect:M}=e,w=e=>{if(!e)return{width:800,height:400};const t=e.getBoundingClientRect();return{width:t.width||800,height:t.height||400}},{useRef:j,useEffect:T,useCallback:$}=e,z=(t,a,n=!0,r,o,s)=>{const l=e.useRef(null),c=e.useRef(!1),d=e.useRef(a);e.useEffect(()=>{d.current=a,l.current&&c.current&&l.current.updateConfig(a)},[a]);const h=$(()=>{if(t.current&&!l.current&&!c.current){const e=t.current,a=e.parentElement;requestAnimationFrame(()=>{if(a&&!l.current){const{width:t,height:h}=w(a);console.log(`📐 Canvas容器尺寸: ${t}x${h}px`);const u={containerWidth:t,containerHeight:h,count:15,density:3,speed:{min:2,max:5},maxFPS:60,qualityMaxFPS:144,enablePerformanceMode:!0,enableFrameRateLimit:!0,debugMode:!1,...d.current};l.current=new i(e,u),r&&l.current.onRedPacketClick(r),o&&l.current.onAnimationStateChange(o),s&&l.current.onPerformanceUpdate(s),c.current=!0,setTimeout(()=>{(e=>{let t=0;const i=performance.now(),a=n=>{if(t++,n-i>=1e3){const i=t;console.log(`当前显示器刷新率: ${i}Hz`),e&&e(i)}else requestAnimationFrame(a)};requestAnimationFrame(a)})()},1e3),n&&(console.log("🎬 自动启动红包雨"),l.current.start());const f=()=>{if(l.current&&a){const e=w(a);l.current.updateConfig({containerWidth:e.width,containerHeight:e.height})}};window.addEventListener("resize",f);const g=()=>{window.removeEventListener("resize",f)};l.current.cleanup=g}})}},[t,n,r,o,s]),u=$(()=>{l.current&&(l.current.cleanup&&l.current.cleanup(),l.current.destroy(),l.current=null,c.current=!1)},[]),f=$(()=>{l.current&&l.current.start()},[]),g=$(()=>{l.current&&l.current.stop()},[]),m=$(()=>{l.current&&l.current.pause()},[]),p=$(()=>{l.current&&l.current.resume()},[]),P=$(()=>{l.current&&l.current.clear()},[]),y=$(e=>{l.current&&l.current.updateConfig(e)},[]),b=$(()=>{if(l.current){const e=l.current.getPerformanceMode();return l.current.setPerformanceMode(!e),console.log("性能模式:",e?"已禁用":"已启用"),!e}return!1},[]),x=$(()=>l.current?.getStats()||{fps:0,renderTime:0,updateTime:0,totalRedPackets:0,activeRedPackets:0},[]),k=$(()=>l.current?.getCollectionStats()||{totalCollected:0,totalValue:0},[]),C=$(()=>{l.current&&l.current.resetCollectionStats()},[]),v=$(()=>l.current?.getPerformanceMode()||!1,[]),S=$(e=>{l.current&&l.current.setPerformanceMode(e)},[]);return T(()=>(h(),()=>{u()}),[]),{engineRef:l,start:f,stop:g,pause:m,resume:p,clear:P,updateConfig:y,togglePerformanceMode:b,getStats:x,getCollectionStats:k,resetCollectionStats:C,getPerformanceMode:v,setPerformanceMode:S}},{useRef:I,useMemo:E,useCallback:D}=e,A=e.forwardRef((t,i)=>{const{config:a={},className:n="",style:r={},autoStart:o=!0,showControls:s=!0,onRedPacketClick:c,onAnimationStateChange:d,onPerformanceUpdate:h}=t,u=e.useRef(null),{currentConfig:f,handleConfigChange:p,updateConfig:y,toggleDebugMode:x,toggleFrameLimit:w}=((e={})=>{const[t,i]=v({...R,...e}),a=S((e,t)=>{let a;return i(i=>(a={...i},"minSpeed"===e?a.speed={...a.speed,min:t}:"maxSpeed"===e?a.speed={...a.speed,max:t}:a[e]=t,a)),a},[]),n=S(e=>{let t;return i(i=>(t={...i,...e},t)),t},[]),r=S(()=>{let e,a;return i(t=>(e=!t.debugMode,a={...t,debugMode:e},console.log("调试模式:",e?"开启":"关闭"),a)),{newConfig:{...t,debugMode:!t.debugMode},debugMode:!t.debugMode}},[t]),o=S(()=>{let e,a;return i(t=>(e=!t.enableFrameRateLimit,a={...t,enableFrameRateLimit:e},console.log("帧率限制:",e?"已启用":"已关闭"),a)),{newConfig:{...t,enableFrameRateLimit:!t.enableFrameRateLimit},frameLimitEnabled:!t.enableFrameRateLimit}},[t]);return{currentConfig:t,setCurrentConfig:i,handleConfigChange:a,updateConfig:n,toggleDebugMode:r,toggleFrameLimit:o}})(a),{engineRef:j,start:T,stop:$,pause:I,resume:A,clear:L,updateConfig:W,togglePerformanceMode:O,getStats:_,getCollectionStats:N,resetCollectionStats:H,getPerformanceMode:V,setPerformanceMode:U}=z(u,f,o,c,d,h),{stats:B,startStatsUpdate:q}=(t=>{const[i,a]=e.useState({fps:0,collected:0,totalValue:0,activeCount:0,performanceMode:"性能模式"}),n=e.useRef(null),r=F(()=>{if(!t.current)return;const e=t.current.getStats(),i=t.current.getCollectionStats(),n=t.current.getPerformanceMode()?"性能模式":"高质量";a({fps:e.fps,collected:i.totalCollected,totalValue:i.totalValue,activeCount:e.activeRedPackets,performanceMode:`${n}(限制已启用)`})},[t]),o=F(()=>{n.current&&clearInterval(n.current),n.current=setInterval(()=>{r()},100)},[r]),s=F(()=>{n.current&&(clearInterval(n.current),n.current=null)},[]);return M(()=>()=>{s()},[s]),{stats:i,updateStats:r,startStatsUpdate:o,stopStatsUpdate:s}})(j);e.useEffect(()=>{q()},[q]);const X=E(()=>g,[]),J=E(()=>m(r),[r]),Y=D(()=>{const e=x();j.current&&j.current.updateConfig({debugMode:e.debugMode})},[x,j]),K=D(()=>O(),[O]),G=D(()=>{const e=w();j.current&&j.current.updateConfig({enableFrameRateLimit:e.frameLimitEnabled})},[w,j]),Q=D((e,t)=>{const i=p(e,t);i&&W(i)},[p,W]);return e.useImperativeHandle(i,()=>({start:T,stop:$,pause:I,resume:A,clear:L,updateConfig:e=>{y(e),W(e)},getStats:_,getCollectionStats:N,resetCollectionStats:H,getEngine:()=>j.current,togglePerformanceMode:O,setPerformanceMode:U,getPerformanceMode:V}),[T,$,I,A,L,y,W,_,N,H,j,O,U,V]),l.jsxs("div",{className:n,children:[s&&l.jsxs(l.Fragment,{children:[l.jsx(P,{stats:B}),l.jsx(b,{onStart:T,onStop:$,onPause:I,onResume:A,onClear:L,onToggleDebug:Y,onTogglePerformance:K,onToggleFrameLimit:G,isPerformanceMode:f.enablePerformanceMode,isDebugMode:f.debugMode,isFrameLimitEnabled:f.enableFrameRateLimit}),l.jsx(k,{config:f,onConfigChange:Q})]}),l.jsx("div",{style:J,children:l.jsx("canvas",{ref:u,style:X})}),s&&l.jsx(C,{})]})});A.displayName="RedPacketRain";exports.RedPacketRain=A,exports.RedPacketRainEngine=i,exports.VERSION="1.0.0",exports.default=A;
//# sourceMappingURL=index.js.map