@ahmiao666/red-packet-rain-vue
Version:
3 lines (2 loc) • 28.6 kB
JavaScript
!function(e,t){"object"==typeof exports&&typeof module<"u"?t(exports,require("vue")):"function"==typeof define&&define.amd?define(["exports","vue"],t):t((e=typeof globalThis<"u"?globalThis:e||self).RedPacketRainVue={},e.Vue)}(this,function(e,t){"use strict";const i={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 a{constructor(e,t){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={...i,...t},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,o=a.speed.min+Math.random()*(a.speed.max-a.speed.min);e.x=t,e.y=i,e.vx=Math.cos(n)*o,e.vy=Math.sin(n)*o-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&&!!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,o=this.canvas.width/a,s=this.canvas.height/n,l=(e-i.left)*o,c=(t-i.top)*s;return this.config.debugMode&&console.log(`🎯 点击坐标转换:\n 客户端坐标: (${e}, ${t})\n Canvas矩形: ${JSON.stringify(i)}\n 缩放比例: (${o.toFixed(3)}, ${s.toFixed(3)})\n 最终坐标: (${l.toFixed(1)}, ${c.toFixed(1)})`),{x:l,y:c}}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,o=i.y+i.height/2,s=Math.sqrt((e-n)**2+(t-o)**2);console.log(`红包${a+1}: 中心(${n.toFixed(1)}, ${o.toFixed(1)}), 距离: ${s.toFixed(1)}`)})))}isPointInRedPacket(e,t,i){const a=i.x+i.width/2,n=i.y+i.height/2,o=i.width*i.scale,s=i.height*i.scale,l=o+.1*o,c=s+.1*s,r=e>=a-l/2&&e<=a+l/2&&t>=n-c/2&&t<=n+c/2;return this.config.debugMode&&r&&console.log(`🎯 红包边界检测:\n 红包中心: (${a.toFixed(1)}, ${n.toFixed(1)})\n 原始尺寸: ${o.toFixed(1)} x ${s.toFixed(1)}\n 扩展尺寸: ${l.toFixed(1)} x ${c.toFixed(1)}\n 点击坐标: (${e.toFixed(1)}, ${t.toFixed(1)})\n 距离中心: (${Math.abs(e-a).toFixed(1)}, ${Math.abs(t-n).toFixed(1)})`),r}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 o=.3+.7*n;a.size=a.initialSize*o,(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,o=t.height*t.scale,s=n+.1*n,l=o+.1*o;e.strokeStyle="rgba(255, 0, 0, 0.5)",e.lineWidth=1,e.strokeRect(i-n/2,a-o/2,n,o),e.strokeStyle="rgba(0, 255, 0, 0.7)",e.lineWidth=2,e.strokeRect(i-s/2,a-l/2,s,l),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))}}const n={class:"red-packet-rain-container",style:{fontFamily:"Arial, sans-serif"}},o={key:0,class:"stats-panel"},s={class:"stats-grid"},l={class:"stats-item"},c={class:"stats-value"},r={class:"stats-item"},d={class:"stats-value"},h={class:"stats-item"},f={class:"stats-value"},m={class:"stats-item"},g={class:"stats-value"},u={class:"stats-item"},p={class:"stats-value"},P={key:1,class:"control-buttons"},v={key:2,class:"config-panel"},k={class:"config-item"},b={class:"config-value"},x={class:"config-item"},y={class:"config-value"},C={class:"config-item"},S={class:"config-value"},F={class:"config-item"},M={class:"config-value"},R={class:"config-item"},V={class:"config-value"},E=["width","height"],w={key:3,class:"instructions"};var N=t.defineComponent({__name:"VueRedPacketRain",props:{config:{type:Object,required:!1,default:()=>({})},className:{type:String,required:!1,default:""},style:{type:Object,required:!1,default:()=>({})},autoStart:{type:Boolean,required:!1,default:!0},showControls:{type:Boolean,required:!1,default:!0}},emits:["redPacketClick","animationStateChange","performanceUpdate"],setup(e,{expose:i,emit:N}){const z=e,T=N,D=t.ref(null),$=t.ref(null),I=t.ref(!1),A=t.reactive({fps:0,collected:0,totalValue:0,activeCount:0,performanceMode:"性能模式"}),B=t.reactive({count:15,density:3,speed:{min:2,max:5},maxFPS:60,qualityMaxFPS:144,enablePerformanceMode:!0,enableFrameRateLimit:!0,debugMode:!1,containerWidth:"100%",containerHeight:"100%",...z.config}),H=t.computed(()=>({display:"block",width:"100%",height:"100%",...z.style}));t.watchEffect(()=>{if(!$.value)return;const e=$.value.getStats(),t=B.enablePerformanceMode?"性能模式":"高质量",i=B.enableFrameRateLimit?"限制已启用":"无限制";A.fps=e.fps,A.collected=$.value.getCollectionStats().totalCollected,A.totalValue=$.value.getCollectionStats().totalValue,A.activeCount=e.activeRedPackets,A.performanceMode=`${t}(${i})`});const W=async()=>{if(!D.value||$.value)return;await t.nextTick();const e=D.value.getBoundingClientRect(),i={containerWidth:e.width||800,containerHeight:e.height||600,...B};$.value=new a(D.value,i),$.value.onRedPacketClick(e=>{T("redPacketClick",e)}),$.value.onAnimationStateChange(e=>{T("animationStateChange",e)}),$.value.onPerformanceUpdate(e=>{T("performanceUpdate",e)}),I.value=!0,setTimeout(()=>{console.log("🎮 Vue红包雨组件已初始化"),console.log("🖥️ 正在检测显示器刷新率..."),(()=>{let e=0;const t=performance.now(),i=a=>{if(e++,a-t>=1e3){const t=e;console.log(`🖥️ 检测到显示器刷新率: ${t}Hz`),t<=60?console.log("📺 您的显示器: 60Hz"):t<=120?console.log("📺 您的显示器: 120Hz - 这解释了为什么看到120FPS而不是144FPS"):console.log("📺 您的显示器: 高刷新率,支持144FPS+")}else requestAnimationFrame(i)};requestAnimationFrame(i)})()},1e3),z.autoStart&&$.value.start()},L=()=>{$.value&&$.value.updateConfig(B)},q=()=>{$.value?.start()},U=()=>{$.value?.stop()},_=()=>{$.value?.pause()},O=()=>{$.value?.resume()},j=()=>{$.value?.clear()},Y=()=>{B.debugMode=!B.debugMode,L(),console.log("调试模式:",B.debugMode?"开启":"关闭")},X=()=>{if($.value){const e=$.value.getPerformanceMode();$.value.setPerformanceMode(!e),B.enablePerformanceMode=!e,console.log("性能模式:",e?"已禁用":"已启用")}},G=()=>{B.enableFrameRateLimit=!B.enableFrameRateLimit,L(),console.log("帧率限制:",B.enableFrameRateLimit?"已启用":"已关闭")};return t.onMounted(()=>{W()}),t.onUnmounted(()=>{$.value&&($.value.destroy(),$.value=null)}),i({start:q,stop:U,pause:_,resume:O,clear:j,updateConfig:e=>{Object.assign(B,e),L()},getStats:()=>$.value?.getStats()||{fps:0,renderTime:0,updateTime:0,totalRedPackets:0,activeRedPackets:0},getEngine:()=>$.value,togglePerformanceMode:()=>{if($.value){const e=$.value.getPerformanceMode();return $.value.setPerformanceMode(!e),B.enablePerformanceMode=!e,!e}return!1},setPerformanceMode:e=>{$.value?.setPerformanceMode(e),B.enablePerformanceMode=e},getPerformanceMode:()=>$.value?.getPerformanceMode()||!1}),(e,i)=>(t.openBlock(),t.createElementBlock("div",n,[t.createCommentVNode(" 统计面板 "),e.showControls?(t.openBlock(),t.createElementBlock("div",o,[t.createElementVNode("div",s,[t.createElementVNode("div",l,[t.createElementVNode("div",c,t.toDisplayString(A.fps),1),i[5]||(i[5]=t.createElementVNode("div",{class:"stats-label"},"FPS",-1))]),t.createElementVNode("div",r,[t.createElementVNode("div",d,t.toDisplayString(A.collected),1),i[6]||(i[6]=t.createElementVNode("div",{class:"stats-label"},"已收集",-1))]),t.createElementVNode("div",h,[t.createElementVNode("div",f,"¥"+t.toDisplayString(A.totalValue),1),i[7]||(i[7]=t.createElementVNode("div",{class:"stats-label"},"总价值",-1))]),t.createElementVNode("div",m,[t.createElementVNode("div",g,t.toDisplayString(A.activeCount),1),i[8]||(i[8]=t.createElementVNode("div",{class:"stats-label"},"活跃红包",-1))]),t.createElementVNode("div",u,[t.createElementVNode("div",p,t.toDisplayString(A.performanceMode),1),i[9]||(i[9]=t.createElementVNode("div",{class:"stats-label"},"当前模式",-1))])])])):t.createCommentVNode("v-if",!0),t.createCommentVNode(" 控制按钮 "),e.showControls?(t.openBlock(),t.createElementBlock("div",P,[t.createElementVNode("button",{class:"btn btn-primary",onClick:q},"🚀 开始"),t.createElementVNode("button",{class:"btn btn-secondary",onClick:U},"⏹️ 停止"),t.createElementVNode("button",{class:"btn btn-secondary",onClick:_},"⏸️ 暂停"),t.createElementVNode("button",{class:"btn btn-secondary",onClick:O},"▶️ 继续"),t.createElementVNode("button",{class:"btn btn-secondary",onClick:j},"🧹 清空"),t.createElementVNode("button",{class:t.normalizeClass(["btn",B.debugMode?"btn-primary":"btn-secondary"]),onClick:Y}," 🐛 "+t.toDisplayString(B.debugMode?"关闭调试":"调试模式"),3),t.createElementVNode("button",{class:t.normalizeClass(["btn",B.enablePerformanceMode?"btn-primary":"btn-secondary"]),onClick:X}," ⚡ "+t.toDisplayString(B.enablePerformanceMode?"高质量模式":"性能模式"),3),t.createElementVNode("button",{class:t.normalizeClass(["btn",B.enableFrameRateLimit?"btn-primary":"btn-secondary"]),onClick:G}," 🎯 "+t.toDisplayString(B.enableFrameRateLimit?"关闭限制":"启用限制"),3)])):t.createCommentVNode("v-if",!0),t.createCommentVNode(" 配置面板 "),e.showControls?(t.openBlock(),t.createElementBlock("div",v,[i[15]||(i[15]=t.createElementVNode("h3",null,"⚙️ 配置调整",-1)),t.createElementVNode("div",k,[i[10]||(i[10]=t.createElementVNode("label",null,"红包数量",-1)),t.withDirectives(t.createElementVNode("input",{type:"range",min:"5",max:"50","onUpdate:modelValue":i[0]||(i[0]=e=>B.count=e),onInput:L},null,544),[[t.vModelText,B.count]]),t.createElementVNode("span",b,t.toDisplayString(B.count),1)]),t.createElementVNode("div",x,[i[11]||(i[11]=t.createElementVNode("label",null,"红包密度",-1)),t.withDirectives(t.createElementVNode("input",{type:"range",min:"1",max:"10","onUpdate:modelValue":i[1]||(i[1]=e=>B.density=e),onInput:L},null,544),[[t.vModelText,B.density]]),t.createElementVNode("span",y,t.toDisplayString(B.density),1)]),t.createElementVNode("div",C,[i[12]||(i[12]=t.createElementVNode("label",null,"最小速度",-1)),t.withDirectives(t.createElementVNode("input",{type:"range",min:"1",max:"5","onUpdate:modelValue":i[2]||(i[2]=e=>B.speed.min=e),onInput:L},null,544),[[t.vModelText,B.speed.min]]),t.createElementVNode("span",S,t.toDisplayString(B.speed.min),1)]),t.createElementVNode("div",F,[i[13]||(i[13]=t.createElementVNode("label",null,"最大速度",-1)),t.withDirectives(t.createElementVNode("input",{type:"range",min:"3",max:"10","onUpdate:modelValue":i[3]||(i[3]=e=>B.speed.max=e),onInput:L},null,544),[[t.vModelText,B.speed.max]]),t.createElementVNode("span",M,t.toDisplayString(B.speed.max),1)]),t.createElementVNode("div",R,[i[14]||(i[14]=t.createElementVNode("label",null,"高质量帧率",-1)),t.withDirectives(t.createElementVNode("input",{type:"range",min:"60",max:"240","onUpdate:modelValue":i[4]||(i[4]=e=>B.qualityMaxFPS=e),onInput:L},null,544),[[t.vModelText,B.qualityMaxFPS]]),t.createElementVNode("span",V,t.toDisplayString(B.qualityMaxFPS),1)])])):t.createCommentVNode("v-if",!0),t.createCommentVNode(" Canvas容器 "),t.createElementVNode("div",{class:t.normalizeClass(["canvas-container",e.className])},[t.createElementVNode("canvas",{ref_key:"canvasRef",ref:D,style:t.normalizeStyle(H.value),width:B.containerWidth,height:B.containerHeight},null,12,E)],2),t.createCommentVNode(" 使用说明 "),e.showControls?(t.openBlock(),t.createElementBlock("div",w,i[16]||(i[16]=[t.createElementVNode("h3",null,"📖 使用说明",-1),t.createElementVNode("ul",null,[t.createElementVNode("li",null,"🎯 点击红包进行收集,每个红包都有随机的价值"),t.createElementVNode("li",null,"⚡ 金色红包为特殊红包,价值更高"),t.createElementVNode("li",null,"🎛️ 使用滑块实时调整红包参数"),t.createElementVNode("li",null,"📊 观察FPS和性能统计"),t.createElementVNode("li",null,"🔍 性能模式:简化渲染、60FPS限制、对象池复用"),t.createElementVNode("li",null,"🎨 高质量模式:完整视觉效果、144FPS限制、对象池复用"),t.createElementVNode("li",null,"🖥️ 帧率受显示器刷新率限制,会自动检测并调整")],-1)]))):t.createCommentVNode("v-if",!0)]))}});!function(e,t){void 0===t&&(t={});var i=t.insertAt;if(e&&!(typeof document>"u")){var a=document.head||document.getElementsByTagName("head")[0],n=document.createElement("style");n.type="text/css","top"===i&&a.firstChild?a.insertBefore(n,a.firstChild):a.appendChild(n),n.styleSheet?n.styleSheet.cssText=e:n.appendChild(document.createTextNode(e))}}('\n.red-packet-rain-container[data-v-f127135f] {\n font-family: Arial, sans-serif;\n}\n.stats-panel[data-v-f127135f] {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 20px;\n margin-bottom: 20px;\n}\n.stats-grid[data-v-f127135f] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 20px;\n}\n.stats-item[data-v-f127135f] {\n text-align: center;\n padding: 15px;\n background: white;\n border-radius: 6px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n.stats-value[data-v-f127135f] {\n font-size: 2em;\n font-weight: bold;\n color: #ff6b6b;\n}\n.stats-label[data-v-f127135f] {\n color: #666;\n margin-top: 5px;\n}\n.control-buttons[data-v-f127135f] {\n margin-bottom: 20px;\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n}\n.btn[data-v-f127135f] {\n padding: 12px 24px;\n border: none;\n border-radius: 25px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s ease;\n box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);\n margin: 5px;\n}\n.btn-primary[data-v-f127135f] {\n background: linear-gradient(45deg, #ff6b6b, #ffa500);\n color: white;\n}\n.btn-secondary[data-v-f127135f] {\n background: #6c757d;\n color: white;\n}\n.btn[data-v-f127135f]:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);\n}\n.config-panel[data-v-f127135f] {\n background: #f8f9fa;\n border-radius: 8px;\n padding: 20px;\n margin-bottom: 20px;\n}\n.config-panel h3[data-v-f127135f] {\n margin: 0 0 20px 0;\n color: #ff6b6b;\n}\n.config-item[data-v-f127135f] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 15px;\n}\n.config-item label[data-v-f127135f] {\n min-width: 80px;\n font-weight: 600;\n color: #333;\n}\n.config-item input[type="range"][data-v-f127135f] {\n flex: 1;\n height: 6px;\n background: #ddd;\n border-radius: 3px;\n outline: none;\n -webkit-appearance: none;\n appearance: none;\n}\n.config-item input[type="range"][data-v-f127135f]::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 20px;\n height: 20px;\n background: #ff6b6b;\n border-radius: 50%;\n cursor: pointer;\n}\n.config-item input[type="range"][data-v-f127135f]::-moz-range-thumb {\n width: 20px;\n height: 20px;\n background: #ff6b6b;\n border-radius: 50%;\n cursor: pointer;\n border: none;\n}\n.config-value[data-v-f127135f] {\n min-width: 30px;\n text-align: center;\n font-weight: bold;\n color: #ff6b6b;\n}\n.canvas-container[data-v-f127135f] {\n width: 100%;\n height: 500px;\n overflow: hidden;\n}\n.instructions[data-v-f127135f] {\n background: linear-gradient(135deg, #e8f4f8 0%, #d4e6f1 100%);\n border-radius: 8px;\n padding: 25px;\n margin-top: 20px;\n}\n.instructions h3[data-v-f127135f] {\n color: #2c3e50;\n margin-top: 0;\n}\n.instructions ul[data-v-f127135f] {\n padding-left: 20px;\n}\n.instructions li[data-v-f127135f] {\n margin-bottom: 8px;\n color: #34495e;\n}\ncanvas[data-v-f127135f] {\n user-select: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n}\n\n');var z=((e,t)=>{const i=e.__vccOpts||e;for(const[e,a]of t)i[e]=a;return i})(N,[["__scopeId","data-v-f127135f"]]);e.RedPacketRain=z,e.RedPacketRainEngine=a,e.VERSION="1.0.0",e.default=z,Object.defineProperty(e,"__esModule",{value:!0})});
//# sourceMappingURL=index.umd.js.map