<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title><![CDATA[睿意进取]]></title> 
<atom:link href="https://ikerbring.top/rss.php" rel="self" type="application/rss+xml" />
<description><![CDATA[向世界广播]]></description>
<link>https://ikerbring.top/</link>
<language>zh-cn</language>

<item>
    <title>清凉一夏</title>
    <link>https://ikerbring.top/?post=3</link>
    <description><![CDATA[<div class="summer-all-in-one" style="position: relative; width: 100%; max-width: 1400px; height: 90vh; min-height: 580px; margin: 0 auto; border-radius: 48px; overflow: hidden; box-shadow: 0 30px 45px rgba(0,20,30,0.5); background: radial-gradient(circle at 20% 30%, #a1d9f0, #4eaccf); cursor: crosshair;">
    <style>
        /* 所有样式只作用于这个div内部 */
        .summer-all-in-one * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        .summer-canvas-layer {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: block;
            z-index: 1;
            border-radius: inherit;
            pointer-events: auto;
        }
        .summer-content-layer {
            position: absolute;
            z-index: 2;
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            pointer-events: none;
            text-align: center;
            top: 0;
            left: 0;
            backdrop-filter: blur(1.5px);
        }
        .main-title {
            font-size: clamp(2.2rem, 10vw, 5.5rem);
            font-weight: 800;
            background: linear-gradient(135deg, #f0fcff, #c5f0ff, #ffffff, #b0e4ff);
            background-clip: text;
            -webkit-background-clip: text;
            color: transparent;
            text-shadow: 0 8px 28px rgba(0,30,50,0.3);
            letter-spacing: 0.06em;
            animation: floatTitle 3.2s ease-in-out infinite;
            margin-bottom: 0.8rem;
            filter: drop-shadow(0 4px 6px rgba(0,0,0,0.1));
        }
        .subtitle {
            font-size: clamp(0.9rem, 4vw, 1.5rem);
            font-weight: 500;
            color: rgba(255,255,245,0.96);
            background: rgba(0,55,70,0.35);
            backdrop-filter: blur(12px);
            padding: 0.6rem 1.8rem;
            border-radius: 60px;
            letter-spacing: 2px;
            border: 1px solid rgba(255,255,250,0.5);
            box-shadow: 0 8px 22px rgba(0,0,0,0.15);
            animation: pulseGlow 2.4s infinite alternate;
        }
        .summer-icons {
            position: absolute;
            bottom: 22px;
            left: 0;
            right: 0;
            display: flex;
            justify-content: center;
            gap: 1rem;
            font-size: 1.8rem;
            z-index: 2;
            pointer-events: none;
            filter: drop-shadow(0 6px 14px rgba(0,0,0,0.2));
            animation: iconBobbing 3s infinite ease;
        }
        .summer-icons span {
            background: rgba(255,255,240,0.25);
            backdrop-filter: blur(8px);
            padding: 0.3rem 0.7rem;
            border-radius: 50px;
            font-size: 1.6rem;
            display: inline-block;
        }
        .cursor-hint {
            position: absolute;
            bottom: 18px;
            right: 24px;
            z-index: 3;
            background: rgba(0,30,40,0.5);
            backdrop-filter: blur(8px);
            padding: 6px 14px;
            border-radius: 36px;
            font-size: 0.75rem;
            color: #eef9ff;
            font-weight: 500;
            pointer-events: none;
            font-family: 'Segoe UI', monospace;
            letter-spacing: 0.8px;
            border: 0.5px solid rgba(255,255,210,0.5);
        }
        @keyframes floatTitle {
            0% { transform: translateY(0px); text-shadow: 0 5px 18px rgba(0,160,200,0.3);}
            50% { transform: translateY(-12px); text-shadow: 0 18px 32px rgba(0,200,240,0.6);}
            100% { transform: translateY(0px); text-shadow: 0 5px 18px rgba(0,160,200,0.3);}
        }
        @keyframes pulseGlow {
            0% { text-shadow: 0 0 2px white; background: rgba(0,60,80,0.3); border-color: rgba(255,255,240,0.4);}
            100% { text-shadow: 0 0 14px #d4f4ff; background: rgba(0,90,115,0.5); border-color: rgba(255,255,220,0.9);}
        }
        @keyframes iconBobbing {
            0% { transform: translateY(0px); opacity: 0.8;}
            50% { transform: translateY(-7px); opacity: 1;}
            100% { transform: translateY(0px); opacity: 0.8;}
        }
        @media (max-width: 650px) {
            .summer-icons span { font-size: 1.2rem; padding: 0.2rem 0.6rem; }
            .subtitle { padding: 0.4rem 1.2rem; font-size: 0.9rem; }
            .cursor-hint { font-size: 0.65rem; bottom: 12px; right: 12px; }
            .summer-all-in-one { height: 85vh; min-height: 520px; border-radius: 32px; }
        }
    </style>

    <canvas class="summer-canvas-layer" id="summerCanvas"></canvas>

    <div class="summer-content-layer">
        <div class="main-title">❄️ 清凉一夏 ❄️</div>
        <div class="subtitle">冰爽气泡 · 海浪轻拂 · 夏日幻想</div>
    </div>
    <div class="summer-icons">
        <span>🍧</span><span>🧊</span><span>🍉</span><span>🥤</span><span>❄️</span>
    </div>
    <div class="cursor-hint">✨ 鼠标/手指滑动 · 生凉气泡 ✨</div>

    <script>
        (function() {
            // 获取当前div内的canvas元素
            const container = document.querySelector('.summer-all-in-one');
            const canvas = document.getElementById('summerCanvas');
            if (!canvas || !container) return;
            let ctx = canvas.getContext('2d');
            let width = container.clientWidth;
            let height = container.clientHeight;

            // 粒子系统
            let bubbles = [];
            let iceCubes = [];
            let tempBubbles = [];
            const BUBBLE_COUNT = 40;
            const ICE_COUNT = 32;
            let animationId = null;
            let timeOffset = 0;
            let mouseMoveThrottle = false;
            let throttleTimer = null;

            function randomRange(min, max) { return min + Math.random() * (max - min); }

            function initParticles() {
                bubbles = [];
                for (let i = 0; i < BUBBLE_COUNT; i++) {
                    bubbles.push({
                        x: randomRange(0, width),
                        y: randomRange(height * 0.6, height + 30),
                        radius: randomRange(5, 20),
                        speedY: randomRange(-1.3, -3.8),
                        speedX: randomRange(-0.4, 0.4),
                        opacity: randomRange(0.45, 0.88)
                    });
                }
                iceCubes = [];
                for (let i = 0; i < ICE_COUNT; i++) {
                    iceCubes.push({
                        x: randomRange(0, width),
                        y: randomRange(-50, height * 0.8),
                        sizeW: randomRange(8, 26),
                        sizeH: randomRange(8, 24),
                        speedY: randomRange(0.5, 2.3),
                        speedX: randomRange(-0.7, 0.8),
                        rotation: randomRange(0, Math.PI * 2),
                        rotationSpeed: randomRange(-0.025, 0.03),
                        alpha: randomRange(0.65, 0.96)
                    });
                }
                tempBubbles = [];
            }

            function resizeCanvas() {
                if (!container || !canvas) return;
                width = container.clientWidth;
                height = container.clientHeight;
                canvas.width = width;
                canvas.height = height;
                initParticles();
            }

            function drawBackground(nowTime) {
                const grad = ctx.createLinearGradient(0, 0, 0, height);
                grad.addColorStop(0, '#89d0e8');
                grad.addColorStop(0.35, '#50b5da');
                grad.addColorStop(0.7, '#2d9bc2');
                grad.addColorStop(1, '#176c8c');
                ctx.fillStyle = grad;
                ctx.fillRect(0, 0, width, height);

                ctx.save();
                ctx.globalCompositeOperation = 'lighter';
                for (let i = 0; i < 5; i++) {
                    const waveY = height - 65 + Math.sin(nowTime * 0.0025 + i) * 14;
                    ctx.beginPath();
                    ctx.moveTo(0, waveY + i * 12);
                    for (let x = 0; x <= width; x += 40) {
                        const y = waveY + Math.sin(x * 0.007 + nowTime * 0.006 + i * 1.3) * 7;
                        ctx.lineTo(x, y);
                    }
                    ctx.lineTo(width, height);
                    ctx.lineTo(0, height);
                    ctx.fillStyle = `rgba(255, 250, 230, ${0.09 - i * 0.012})`;
                    ctx.fill();
                }
                ctx.globalCompositeOperation = 'overlay';
                for (let s = 0; s < 45; s++) {
                    let fx = (nowTime * 0.25 + s * 61) % width;
                    let fy = (nowTime * 0.18 + s * 37) % (height * 0.65);
                    ctx.beginPath();
                    ctx.arc(fx, fy, 2 + Math.sin(nowTime * 0.012 + s) * 1.8, 0, Math.PI * 2);
                    ctx.fillStyle = `rgba(255, 250, 200, ${0.25 + Math.sin(nowTime * 0.008 + s) * 0.12})`;
                    ctx.fill();
                }
                ctx.restore();

                ctx.save();
                ctx.globalAlpha = 0.3;
                for (let l = 0; l < 14; l++) {
                    let lineX = (timeOffset * 0.12 + l * 48) % (width + 120) - 60;
                    ctx.beginPath();
                    ctx.moveTo(lineX, height * 0.65);
                    ctx.quadraticCurveTo(lineX + 42, height * 0.78, lineX + 85, height * 0.92);
                    ctx.strokeStyle = '#dcf5ff';
                    ctx.lineWidth = 2.2;
                    ctx.stroke();
                }
                ctx.restore();
            }

            function drawBubbles() {
                for (let b of bubbles) {
                    ctx.save();
                    ctx.shadowBlur = 9;
                    ctx.shadowColor = `rgba(80, 200, 240, 0.6)`;
                    ctx.beginPath();
                    const grad = ctx.createRadialGradient(b.x - 4, b.y - 4, 2.5, b.x, b.y, b.radius);
                    grad.addColorStop(0, `rgba(255, 255, 250, ${b.opacity + 0.2})`);
                    grad.addColorStop(0.6, `rgba(120, 220, 255, ${b.opacity * 0.9})`);
                    grad.addColorStop(1, `rgba(60, 170, 230, ${b.opacity * 0.7})`);
                    ctx.fillStyle = grad;
                    ctx.arc(b.x, b.y, b.radius, 0, Math.PI * 2);
                    ctx.fill();
                    ctx.beginPath();
                    ctx.arc(b.x - b.radius * 0.28, b.y - b.radius * 0.28, b.radius * 0.2, 0, Math.PI * 2);
                    ctx.fillStyle = `rgba(255, 255, 250, 0.85)`;
                    ctx.fill();
                    ctx.restore();
                }
            }

            function drawIceCubes() {
                for (let ice of iceCubes) {
                    ctx.save();
                    ctx.translate(ice.x, ice.y);
                    ctx.rotate(ice.rotation);
                    ctx.shadowBlur = 10;
                    ctx.shadowColor = 'rgba(0, 170, 210, 0.55)';
                    const grad = ctx.createLinearGradient(-ice.sizeW/2, -ice.sizeH/2, ice.sizeW/2, ice.sizeH/2);
                    grad.addColorStop(0, `rgba(215, 248, 255, ${ice.alpha})`);
                    grad.addColorStop(0.5, `rgba(120, 205, 245, ${ice.alpha * 0.9})`);
                    grad.addColorStop(1, `rgba(70, 165, 215, ${ice.alpha * 0.8})`);
                    ctx.fillStyle = grad;
                    ctx.fillRect(-ice.sizeW/2, -ice.sizeH/2, ice.sizeW, ice.sizeH);
                    ctx.beginPath();
                    ctx.moveTo(-ice.sizeW/3.2, -ice.sizeH/3.2);
                    ctx.lineTo(ice.sizeW/4, -ice.sizeH/2.4);
                    ctx.lineTo(ice.sizeW/2.2, -ice.sizeH/4);
                    ctx.strokeStyle = 'rgba(255, 255, 250, 0.85)';
                    ctx.lineWidth = 1.8;
                    ctx.stroke();
                    ctx.beginPath();
                    ctx.arc(ice.sizeW*0.22, ice.sizeH*0.12, ice.sizeW*0.12, 0, Math.PI*2);
                    ctx.fillStyle = `rgba(255, 255, 250, 0.6)`;
                    ctx.fill();
                    ctx.restore();
                }
            }

            function drawTempBubbles() {
                for (let i = 0; i < tempBubbles.length; i++) {
                    const t = tempBubbles[i];
                    ctx.save();
                    ctx.globalAlpha = t.opacity;
                    ctx.shadowBlur = 7;
                    ctx.shadowColor = '#7ec8ff';
                    ctx.beginPath();
                    ctx.arc(t.x, t.y, t.radius, 0, Math.PI * 2);
                    const grad = ctx.createRadialGradient(t.x-3, t.y-3, 2, t.x, t.y, t.radius);
                    grad.addColorStop(0, `rgba(255, 255, 240, 0.98)`);
                    grad.addColorStop(1, `rgba(80, 200, 250, 0.8)`);
                    ctx.fillStyle = grad;
                    ctx.fill();
                    ctx.restore();
                    t.y += t.speedY;
                    t.x += t.speedX;
                    t.radius *= 0.985;
                    t.opacity -= 0.01;
                    t.life--;
                }
                tempBubbles = tempBubbles.filter(t => t.life > 0 && t.radius > 2 && t.opacity > 0.05);
            }

            function updateParticles() {
                for (let b of bubbles) {
                    b.y += b.speedY;
                    b.x += b.speedX;
                    if (b.y + b.radius < 0) {
                        b.y = height + randomRange(8, 35);
                        b.x = randomRange(0, width);
                        b.radius = randomRange(5, 20);
                        b.speedY = randomRange(-1.6, -4.0);
                        b.speedX = randomRange(-0.5, 0.5);
                        b.opacity = randomRange(0.5, 0.9);
                    }
                    if (b.x + b.radius < 0) b.x = width + b.radius;
                    if (b.x - b.radius > width) b.x = -b.radius;
                    if (b.y - b.radius > height + 70) {
                        b.y = -randomRange(8, 30);
                        b.x = randomRange(0, width);
                    }
                }
                for (let ice of iceCubes) {
                    ice.x += ice.speedX;
                    ice.y += ice.speedY;
                    ice.rotation += ice.rotationSpeed;
                    if (ice.y - ice.sizeH/2 > height + 50) {
                        ice.y = -randomRange(15, 45);
                        ice.x = randomRange(0, width);
                        ice.sizeW = randomRange(8, 26);
                        ice.sizeH = randomRange(8, 24);
                        ice.speedY = randomRange(0.6, 2.4);
                        ice.speedX = randomRange(-0.8, 0.9);
                        ice.alpha = randomRange(0.65, 0.96);
                    }
                    if (ice.x + ice.sizeW/2 < -50) ice.x = width + 40;
                    if (ice.x - ice.sizeW/2 > width + 50) ice.x = -40;
                    if (ice.y + ice.sizeH/2 < -60) {
                        ice.y = height + randomRange(15, 60);
                        ice.x = randomRange(0, width);
                    }
                }
            }

            function addBubbleAtPointer(clientX, clientY) {
                const rect = canvas.getBoundingClientRect();
                const scaleX = canvas.width / rect.width;
                const scaleY = canvas.height / rect.height;
                let pointX = (clientX - rect.left) * scaleX;
                let pointY = (clientY - rect.top) * scaleY;
                pointX = Math.min(Math.max(5, pointX), width - 5);
                pointY = Math.min(Math.max(5, pointY), height - 5);
                const count = Math.floor(randomRange(2, 5));
                for (let i = 0; i < count; i++) {
                    tempBubbles.push({
                        x: pointX + randomRange(-14, 14),
                        y: pointY + randomRange(-8, 10),
                        radius: randomRange(5, 14),
                        speedY: randomRange(-2.5, -4.8),
                        speedX: randomRange(-0.9, 0.9),
                        opacity: 0.92,
                        life: 58 + Math.floor(randomRange(0, 32))
                    });
                }
                if (Math.random() < 0.2) {
                    iceCubes.push({
                        x: pointX,
                        y: pointY - 4,
                        sizeW: randomRange(7, 18),
                        sizeH: randomRange(7, 16),
                        speedY: randomRange(0.4, 1.8),
                        speedX: randomRange(-0.7, 0.8),
                        rotation: randomRange(0, Math.PI*2),
                        rotationSpeed: randomRange(-0.02, 0.03),
                        alpha: 0.85
                    });
                    if (iceCubes.length > ICE_COUNT + 22) iceCubes.splice(0, 8);
                }
            }

            function onMouseMove(e) {
                if (mouseMoveThrottle) return;
                mouseMoveThrottle = true;
                if (throttleTimer) clearTimeout(throttleTimer);
                throttleTimer = setTimeout(() => { mouseMoveThrottle = false; }, 38);
                addBubbleAtPointer(e.clientX, e.clientY);
            }

            function onTouchMove(e) {
                e.preventDefault();
                if (mouseMoveThrottle) return;
                mouseMoveThrottle = true;
                if (throttleTimer) clearTimeout(throttleTimer);
                throttleTimer = setTimeout(() => { mouseMoveThrottle = false; }, 40);
                for (let i = 0; i < e.touches.length; i++) {
                    addBubbleAtPointer(e.touches[i].clientX, e.touches[i].clientY);
                }
            }

            function maintainParticleCount() {
                if (bubbles.length < BUBBLE_COUNT - 4) {
                    for (let i = 0; i < 3; i++) bubbles.push({
                        x: randomRange(0, width), y: randomRange(height-40, height+25),
                        radius: randomRange(5, 18), speedY: randomRange(-1.2, -3.5),
                        speedX: randomRange(-0.4, 0.4), opacity: randomRange(0.5, 0.88)
                    });
                }
                if (iceCubes.length < ICE_COUNT - 5) {
                    iceCubes.push({
                        x: randomRange(0, width), y: randomRange(-30, 60),
                        sizeW: randomRange(8, 24), sizeH: randomRange(8, 22),
                        speedY: randomRange(0.5, 2.2), speedX: randomRange(-0.7, 0.8),
                        rotation: randomRange(0, Math.PI*2), rotationSpeed: randomRange(-0.025, 0.03),
                        alpha: randomRange(0.7, 0.95)
                    });
                }
            }

            function animate(timestamp) {
                if (!ctx) return;
                timeOffset = timestamp || performance.now();
                drawBackground(timeOffset);
                drawIceCubes();
                drawBubbles();
                drawTempBubbles();
                ctx.save();
                ctx.globalCompositeOperation = 'lighter';
                for (let s = 0; s < 55; s++) {
                    let starX = (timeOffset * 0.22 + s * 97) % width;
                    let starY = (timeOffset * 0.13 + s * 53) % (height * 0.55);
                    ctx.beginPath();
                    ctx.arc(starX, starY, 1.3, 0, Math.PI*2);
                    ctx.fillStyle = `rgba(235, 250, 255, 0.55)`;
                    ctx.fill();
                }
                ctx.restore();
                updateParticles();
                maintainParticleCount();
                animationId = requestAnimationFrame(animate);
            }

            function handleResize() {
                resizeCanvas();
            }

            // 初始化
            resizeCanvas();
            window.addEventListener('resize', handleResize);
            const resizeObserver = new ResizeObserver(() => handleResize());
            resizeObserver.observe(container);
            canvas.addEventListener('mousemove', onMouseMove);
            canvas.addEventListener('touchmove', onTouchMove, { passive: false });
            canvas.addEventListener('touchstart', (e) => {
                e.preventDefault();
                if (e.touches.length) addBubbleAtPointer(e.touches[0].clientX, e.touches[0].clientY);
            });
            animationId = requestAnimationFrame(animate);

            window.addEventListener('beforeunload', () => { if (animationId) cancelAnimationFrame(animationId); });
        })();
    </script>
</div>]]></description>
    <pubDate>Thu, 28 May 2026 15:30:49 +0800</pubDate>
    <dc:creator>admin</dc:creator>
    <guid>https://ikerbring.top/?post=3</guid>
</item>
<item>
    <title>给自己放个烟花吧~</title>
    <link>https://ikerbring.top/?post=2</link>
    <description><![CDATA[<div id="fireworkStage" style="position: relative; width: 100%; max-width: 1000px; height: 80vh; min-height: 450px; background: radial-gradient(circle at 30% 10%, #0a0f2a, #03050c); border-radius: 2rem; box-shadow: 0 20px 35px rgba(0,0,0,0.5), inset 0 0 1px rgba(255,200,100,0.3); overflow: hidden; cursor: crosshair; margin: 20px auto;">
    <canvas id="fireCanvas" style="display: block; width: 100%; height: 100%; position: absolute; top: 0; left: 0;"></canvas>
    <div style="position: absolute; bottom: 12px; left: 0; right: 0; text-align: center; pointer-events: none; color: rgba(255,245,180,0.8); background: rgba(0,0,0,0.4); backdrop-filter: blur(6px); width: fit-content; margin: 0 auto; padding: 5px 16px; border-radius: 40px; font-size: 13px; font-family: monospace;">✨ 点击任意处绽放烟花 | 自动升空花火 ✨</div>
</div>
<script>
    (function(){
        // ----- 获取容器和canvas (都在这个div内部) -----
        const container = document.getElementById('fireworkStage');
        const canvas = document.getElementById('fireCanvas');
        let ctx = canvas.getContext('2d');
        let width, height;

        // ----- 粒子系统 -----
        let particles = [];
        let fireworks = [];
        const MAX_PARTICLES = 1800;
        const MAX_FIREWORKS = 6;
        const DEFAULT_PARTICLE_COUNT = 78;
        const GRAVITY = 0.2;
        const PARTICLE_FRICTION = 0.985;
        const ROCKET_SPEED = 5.7;

        // ----- 背景星星 -----
        let stars = [];
        const STAR_COUNT = 150;
        let starTime = 0;

        function randomRange(min, max) { return min + Math.random() * (max - min); }
        function getFireworkColor() { return `hsl(${Math.random() * 360}, ${75 + Math.random() * 20}%, ${60 + Math.random() * 20}%)`; }

        function generateStars() {
            stars = [];
            for(let i=0; i<STAR_COUNT; i++) {
                stars.push({
                    x: Math.random() * width,
                    y: Math.random() * height,
                    radius: Math.random() * 2.2 + 0.8,
                    alpha: Math.random() * 0.6 + 0.2,
                    twinkleSpeed: 0.5 + Math.random() * 1.5,
                    phase: Math.random() * Math.PI * 2,
                    currentAlpha: 0.5
                });
            }
        }

        function updateStarsBlink() {
            starTime += 0.02;
            for(let s of stars) {
                let twinkle = 0.5 + 0.5 * Math.sin(starTime * s.twinkleSpeed + s.phase);
                s.currentAlpha = Math.min(0.9, s.alpha * (0.5 + twinkle * 0.7));
            }
        }

        function drawBackground() {
            const grad = ctx.createLinearGradient(0, 0, 0, height);
            grad.addColorStop(0, '#0a0f2a');
            grad.addColorStop(0.6, '#11162f');
            grad.addColorStop(1, '#03050c');
            ctx.fillStyle = grad;
            ctx.fillRect(0, 0, width, height);
            for(let s of stars) {
                ctx.beginPath();
                ctx.arc(s.x, s.y, s.radius, 0, Math.PI*2);
                ctx.fillStyle = `rgba(255, 240, 200, ${s.currentAlpha || s.alpha})`;
                ctx.fill();
            }
        }

        class Particle {
            constructor(x, y, vx, vy, color, size, alpha=1.0) {
                this.x=x; this.y=y; this.vx=vx; this.vy=vy; this.color=color; this.size=size; this.alpha=alpha;
                this.decay = 0.011 + Math.random()*0.013;
                this.gravity = GRAVITY;
                this.friction = PARTICLE_FRICTION;
            }
            update() {
                this.vx *= this.friction;
                this.vy *= this.friction;
                this.vy += this.gravity;
                this.x += this.vx;
                this.y += this.vy;
                this.alpha -= this.decay;
                if(this.size>0.6) this.size*=0.99;
                return this.alpha>0.03 && this.x+this.size>0 && this.x-this.size<width && this.y+this.size>0 && this.y-this.size<height;
            }
            draw(ctx) {
                ctx.save();
                ctx.globalAlpha = this.alpha;
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI*2);
                ctx.fillStyle = this.color;
                ctx.fill();
                ctx.shadowBlur = 5;
                ctx.shadowColor = this.color;
                ctx.fill();
                ctx.shadowBlur = 0;
                ctx.restore();
            }
        }

        class Rocket {
            constructor(x, targetY) {
                this.x = x;
                this.y = height - 6;
                this.targetY = targetY;
                this.speed = ROCKET_SPEED;
                this.color = `hsl(${randomRange(20,50)}, 88%, 62%)`;
                this.size = 4.2;
                this.trail = [];
                for(let i=0;i<3;i++) this.trail.push({x:this.x, y:this.y});
            }
            update() {
                this.trail.unshift({x:this.x, y:this.y});
                if(this.trail.length>6) this.trail.pop();
                this.y -= this.speed;
                this.x += (Math.random()-0.5)*0.4;
                this.x = Math.min(width-15, Math.max(15, this.x));
                return this.y <= this.targetY;
            }
            draw(ctx) {
                for(let i=0;i<this.trail.length;i++) {
                    let p = this.trail[i];
                    let progress = i/this.trail.length;
                    let alpha = 0.55*(1-progress);
                    let sz = this.size*(1-progress*0.65);
                    ctx.beginPath();
                    ctx.arc(p.x, p.y, sz, 0, Math.PI*2);
                    ctx.fillStyle = `rgba(255,140,50,${alpha})`;
                    ctx.fill();
                }
                ctx.save();
                ctx.shadowBlur = 12;
                ctx.shadowColor = '#ff8800';
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI*2);
                ctx.fillStyle = this.color;
                ctx.fill();
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size*0.6, 0, Math.PI*2);
                ctx.fillStyle = '#fff3b0';
                ctx.fill();
                ctx.restore();
            }
        }

        function createExplosion(px, py, customCount=null) {
            let count = customCount !== null ? customCount : DEFAULT_PARTICLE_COUNT;
            if(particles.length+count > MAX_PARTICLES) count = Math.min(count, MAX_PARTICLES-particles.length);
            if(count<=8) return;
            let newParticles = [];
            for(let i=0;i<count;i++) {
                let angle = Math.random()*Math.PI*2;
                let speed = randomRange(2.3,7.0);
                let vx = Math.cos(angle)*speed*(0.5+Math.random()*0.7);
                let vy = Math.sin(angle)*speed*(0.5+Math.random()*0.6)-1.0;
                let color = (Math.random()>0.25) ? getFireworkColor() : `hsl(${45+Math.random()*25}, 92%, 65%)`;
                let size = randomRange(1.8,4.2);
                newParticles.push(new Particle(px,py,vx,vy,color,size,0.95));
            }
            for(let i=0;i<count*0.22;i++) {
                let angle = Math.random()*Math.PI*2;
                let speed = randomRange(3.2,8);
                let vx = Math.cos(angle)*speed*0.9;
                let vy = Math.sin(angle)*speed*0.85-0.8;
                let color = `hsl(${randomRange(0,65)}, 100%, 68%)`;
                newParticles.push(new Particle(px,py,vx,vy,color,randomRange(1.5,3.0),0.9));
            }
            particles.push(...newParticles);
        }

        function addRocket() {
            if(fireworks.length>=MAX_FIREWORKS) return;
            let randX = randomRange(45, width-45);
            let targetY = randomRange(height*0.2, height*0.75);
            fireworks.push(new Rocket(randX, targetY));
        }

        function updateFireworks() {
            for(let i=fireworks.length-1;i>=0;i--) {
                let rocket = fireworks[i];
                let explode = rocket.update();
                if(rocket.y<=rocket.targetY+3 || rocket.y<=12) explode=true;
                if(rocket.x<-30 || rocket.x>width+30 || rocket.y<-40) { fireworks.splice(i,1); continue; }
                if(explode) {
                    let count = DEFAULT_PARTICLE_COUNT + Math.floor(Math.random()*40);
                    if(rocket.y<height*0.4) count+=12;
                    createExplosion(rocket.x, rocket.y, Math.min(count,115));
                    fireworks.splice(i,1);
                }
            }
        }

        function updateParticles() {
            for(let i=particles.length-1;i>=0;i--) if(!particles[i].update()) particles.splice(i,1);
        }

        function draw() {
            drawBackground();
            for(let r of fireworks) r.draw(ctx);
            ctx.save();
            ctx.globalCompositeOperation = 'lighter';
            for(let p of particles) p.draw(ctx);
            ctx.restore();
        }

        function animate() {
            updateStarsBlink();
            updateFireworks();
            updateParticles();
            draw();
            requestAnimationFrame(animate);
        }

        function resizeCanvas() {
            let rect = container.getBoundingClientRect();
            width = rect.width;
            height = rect.height;
            canvas.width = width;
            canvas.height = height;
            particles = [];
            fireworks = [];
            generateStars();
            drawBackground();
        }

        function handleClick(e) {
            let rect = container.getBoundingClientRect();
            let clientX, clientY;
            if(e.touches) { clientX=e.touches[0].clientX; clientY=e.touches[0].clientY; e.preventDefault(); }
            else { clientX=e.clientX; clientY=e.clientY; }
            let x = clientX - rect.left;
            let y = clientY - rect.top;
            x = Math.min(width-8, Math.max(8, x));
            y = Math.min(height-8, Math.max(8, y));
            let amount = 70 + Math.floor(Math.random()*60);
            createExplosion(x, y, amount);
            setTimeout(() => { if(particles.length<MAX_PARTICLES-45) createExplosion(x,y,Math.floor(amount*0.6)); }, 28);
        }

        let autoTimer;
        function startAutoFireworks() {
            if(autoTimer) clearInterval(autoTimer);
            autoTimer = setInterval(() => {
                if(fireworks.length<MAX_FIREWORKS) addRocket();
                if(fireworks.length<MAX_FIREWORKS-1 && Math.random()<0.25) setTimeout(()=>addRocket(),70);
            }, 1380);
        }

        // 监听尺寸变化
        let resizeObserver = new ResizeObserver(()=>resizeCanvas());
        resizeObserver.observe(container);
        window.addEventListener('resize', ()=>resizeCanvas());

        // 初始化
        resizeCanvas();
        generateStars();
        startAutoFireworks();
        animate();
        container.addEventListener('click', handleClick);
        container.addEventListener('touchstart', handleClick, {passive:false});

        // 开场两枚火箭
        setTimeout(()=>{ if(fireworks.length===0){ addRocket(); setTimeout(addRocket,300); } },200);
    })();
</script>]]></description>
    <pubDate>Mon, 18 May 2026 10:35:09 +0800</pubDate>
    <dc:creator>admin</dc:creator>
    <guid>https://ikerbring.top/?post=2</guid>
</item>
</channel>
</rss>