用 通义灵码 为网站生成动感粒子背景,打造星空效果

简介: 星空粒子背景因其动态性与交互性,成为网站设计中提升用户体验的重要元素。通过通义灵码,开发者可以轻松生成多种风格的星空粒子背景,并将其融入网页设计。本文介绍了使用通义灵码创建动态粒子背景的步骤,展示了

视觉效果已经不再是简单的装饰,它往往决定了用户的第一印象。尤其是动态背景,能够为网站增添动感和魅力,使访客在浏览过程中感到一种无形的吸引力。而在众多动态背景中,星空粒子背景无疑是最受欢迎的一种,它不仅能展现优雅的视觉效果,还能带给用户一种沉浸式的体验。

今天,我将带你一步步走进如何使用 通义灵码来为网站生成一个炫酷的星空粒子背景,并让它完美融入你的网页设计中。

为什么选择星空粒子背景?

首先,让我们稍微聊一聊为什么星空粒子背景这么受欢迎。星空背景能够带给网站一种科幻、神秘的氛围,尤其适用于那些想要展示技术实力、创意和独特个性的个人网站、科技产品、游戏开发者和创意公司等。

星空背景的核心在于它的动态性,不同于静态的图片或颜色,动态背景能够随时间变化产生不同的效果。这种视觉上的流动感,能够大大提升用户体验,使访客不自觉地留在页面上更久。

此外,星空粒子背景本身具备一定的交互性,能够与用户的鼠标或滚动事件产生互动。当你将这样的背景与其他页面元素结合时,网站的整体视觉效果往往会变得更有层次感。

通义灵码:开发者的灵活助手

在谈到如何为网站实现动态星空背景时,选择合适的开发工具是非常重要的。这里,我推荐你使用 通义灵码,它是一款强大的开发工具,可以帮助你快速生成和部署网站背景效果。无论你是前端开发新人,还是有一定经验的开发者,通义灵码都能让你更加高效地完成项目。

通义灵码提供了一个简单而直观的编程环境,让你无需繁琐的配置与繁杂的调试,就能轻松地进行网页设计和开发。其内置的代码提示、实时预览功能、插件支持等,能够大幅度提升开发效率,同时也减少了出错的机会。

步骤一:准备工作

首先,确保你已经安装并配置好了 通义灵码。如果你还没有安装,可以直接去下载并安装。

安装完成后,打开 通义灵码,在欢迎界面选择创建一个新的项目。

步骤二:发送指令

在 通义灵码对话中输入:为网站生成动态粒子背景(canvas 或 tsParticles)想要“星空背景”

看下效果:

一种效果可能不够看,那我们就多来几种;

输入指令:请在提供多种背景主题风格。

使用 通义灵码创建一个动态粒子背景,特别是星空效果,既简单又高效。通过这个过程,你不仅能够为网站增添美观的动态效果,还能提升用户体验,让你的网页更加生动、富有活力。而 通义灵码提供的便捷开发环境,无需复杂配置,轻松生成项目,使得开发者能够更专注于创意和内容本身。

如果你是前端开发者,或者希望为自己的网站增添一些特别的效果,不妨尝试一下通义灵码。相信它会为你带来不一样的惊喜!

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>动态粒子背景生成器</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Arial', 'Microsoft YaHei', sans-serif;
            background: #1a1a1a;
            color: white;
            min-height: 100vh;
            overflow-x: hidden;
        }
        .canvas-container {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
        }
        #particleCanvas {
            width: 100%;
            height: 100%;
            background: transparent;
        }
        .control-panel {
            position: fixed;
            top: 20px;
            right: 20px;
            background: rgba(0, 0, 0, 0.8);
            border-radius: 15px;
            padding: 20px;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.1);
            max-width: 350px;
            max-height: 80vh;
            overflow-y: auto;
            z-index: 1000;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
        }
        .panel-header {
            text-align: center;
            margin-bottom: 20px;
            font-size: 1.2em;
            font-weight: bold;
            color: #00f5ff;
            text-shadow: 0 0 10px rgba(0, 245, 255, 0.5);
        }
        .theme-selector {
            margin-bottom: 20px;
        }
        .theme-title {
            font-size: 1em;
            margin-bottom: 10px;
            color: #fff;
            font-weight: bold;
        }
        .theme-grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 10px;
        }
        .theme-btn {
            padding: 10px;
            border: 2px solid transparent;
            border-radius: 8px;
            background: rgba(255, 255, 255, 0.1);
            color: white;
            cursor: pointer;
            transition: all 0.3s ease;
            text-align: center;
            font-size: 0.9em;
            position: relative;
            overflow: hidden;
        }
        .theme-btn:hover {
            border-color: #00f5ff;
            background: rgba(0, 245, 255, 0.2);
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(0, 245, 255, 0.3);
        }
        .theme-btn.active {
            border-color: #00f5ff;
            background: rgba(0, 245, 255, 0.3);
            box-shadow: 0 0 20px rgba(0, 245, 255, 0.5);
        }
        .control-group {
            margin-bottom: 15px;
        }
        .control-label {
            display: block;
            margin-bottom: 5px;
            font-size: 0.9em;
            color: #ccc;
        }
        .control-input {
            width: 100%;
            padding: 8px;
            border: 1px solid rgba(255, 255, 255, 0.3);
            border-radius: 5px;
            background: rgba(255, 255, 255, 0.1);
            color: white;
            font-size: 0.9em;
        }
        .control-input:focus {
            outline: none;
            border-color: #00f5ff;
            box-shadow: 0 0 8px rgba(0, 245, 255, 0.3);
        }
        .range-input {
            width: 100%;
            margin: 5px 0;
        }
        .range-value {
            display: inline-block;
            background: rgba(0, 245, 255, 0.2);
            padding: 2px 8px;
            border-radius: 4px;
            font-size: 0.8em;
            color: #00f5ff;
            float: right;
        }
        .action-buttons {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 10px;
            margin-top: 20px;
        }
        .action-btn {
            padding: 10px;
            border: none;
            border-radius: 8px;
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            cursor: pointer;
            transition: all 0.3s ease;
            font-size: 0.9em;
            font-weight: bold;
        }
        .action-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
        }
        .export-btn {
            background: linear-gradient(135deg, #4facfe, #00f2fe);
        }
        .reset-btn {
            background: linear-gradient(135deg, #fa709a, #fee140);
        }
        .info-panel {
            position: fixed;
            bottom: 20px;
            left: 20px;
            background: rgba(0, 0, 0, 0.8);
            padding: 15px;
            border-radius: 10px;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.1);
            z-index: 1000;
        }
        .fps-counter {
            color: #00f5ff;
            font-weight: bold;
            margin-bottom: 5px;
        }
        .particle-count {
            color: #ffa500;
            font-size: 0.9em;
        }
        .preset-themes {
            margin-bottom: 20px;
        }
        .preset-grid {
            display: grid;
            grid-template-columns: 1fr;
            gap: 8px;
        }
        .preset-item {
            padding: 8px 12px;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.3s ease;
            border-left: 3px solid transparent;
            font-size: 0.85em;
        }
        .preset-item:hover {
            background: rgba(255, 255, 255, 0.1);
            border-left-color: #00f5ff;
            transform: translateX(5px);
        }
        .toggle-panel {
            position: fixed;
            top: 20px;
            left: 20px;
            background: rgba(0, 0, 0, 0.8);
            padding: 10px;
            border-radius: 50%;
            cursor: pointer;
            z-index: 1001;
            transition: all 0.3s ease;
            width: 50px;
            height: 50px;
            display: flex;
            align-items: center;
            justify-content: center;
            border: 2px solid rgba(255, 255, 255, 0.2);
        }
        .toggle-panel:hover {
            background: rgba(0, 245, 255, 0.2);
            border-color: #00f5ff;
            transform: scale(1.1);
        }
        @media (max-width: 768px) {
            .control-panel {
                top: 80px;
                right: 10px;
                left: 10px;
                max-width: none;
                max-height: 60vh;
            }
            
            .theme-grid {
                grid-template-columns: 1fr;
            }
            
            .action-buttons {
                grid-template-columns: 1fr;
            }
        }
        /* 自定义滚动条 */
        .control-panel::-webkit-scrollbar {
            width: 6px;
        }
        .control-panel::-webkit-scrollbar-track {
            background: rgba(255, 255, 255, 0.1);
            border-radius: 3px;
        }
        .control-panel::-webkit-scrollbar-thumb {
            background: rgba(0, 245, 255, 0.5);
            border-radius: 3px;
        }
        .code-preview {
            margin-top: 15px;
            background: rgba(0, 0, 0, 0.5);
            border-radius: 8px;
            padding: 15px;
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        .code-preview h4 {
            color: #00f5ff;
            margin-bottom: 10px;
            font-size: 0.9em;
        }
        .code-content {
            background: #1e1e1e;
            padding: 10px;
            border-radius: 5px;
            font-family: 'Courier New', monospace;
            font-size: 0.8em;
            color: #e6e6e6;
            overflow-x: auto;
            white-space: pre-wrap;
            max-height: 150px;
            overflow-y: auto;
        }
        .copy-code-btn {
            margin-top: 8px;
            padding: 6px 12px;
            background: rgba(0, 245, 255, 0.2);
            border: 1px solid #00f5ff;
            border-radius: 4px;
            color: #00f5ff;
            cursor: pointer;
            font-size: 0.8em;
            transition: all 0.3s ease;
        }
        .copy-code-btn:hover {
            background: rgba(0, 245, 255, 0.3);
        }
    </style>
</head>
<body>
    <div class="canvas-container">
        <canvas id="particleCanvas"></canvas>
    </div>
    <div class="toggle-panel" onclick="toggleControlPanel()" title="切换控制面板">
        ⚙️
    </div>
    <div class="control-panel" id="controlPanel">
        <div class="panel-header">
            ✨ 粒子背景生成器
        </div>
        <!-- 主题选择器 -->
        <div class="theme-selector">
            <div class="theme-title">🎨 主题风格</div>
            <div class="theme-grid">
                <div class="theme-btn active" onclick="setTheme('starry')" data-theme="starry">
                    🌟 星空夜晚
                </div>
                <div class="theme-btn" onclick="setTheme('snow')" data-theme="snow">
                    ❄️ 雪花飘落
                </div>
                <div class="theme-btn" onclick="setTheme('aurora')" data-theme="aurora">
                    🌌 极光幻彩
                </div>
                <div class="theme-btn" onclick="setTheme('galaxy')" data-theme="galaxy">
                    🌠 银河星系
                </div>
                <div class="theme-btn" onclick="setTheme('matrix')" data-theme="matrix">
                    💚 数字矩阵
                </div>
                <div class="theme-btn" onclick="setTheme('neon')" data-theme="neon">
                    💙 霓虹科技
                </div>
                <div class="theme-btn" onclick="setTheme('fire')" data-theme="fire">
                    🔥 火焰粒子
                </div>
                <div class="theme-btn" onclick="setTheme('ocean')" data-theme="ocean">
                    🌊 深海波浪
                </div>
            </div>
        </div>
        <!-- 预设效果 -->
        <div class="preset-themes">
            <div class="theme-title">🎭 预设效果</div>
            <div class="preset-grid">
                <div class="preset-item" onclick="applyPreset('romantic')">💕 浪漫粉樱</div>
                <div class="preset-item" onclick="applyPreset('cyberpunk')">🤖 赛博朋克</div>
                <div class="preset-item" onclick="applyPreset('forest')">🌲 魔法森林</div>
                <div class="preset-item" onclick="applyPreset('space')">🚀 太空探索</div>
                <div class="preset-item" onclick="applyPreset('retro')">📼 复古波浪</div>
            </div>
        </div>
        <!-- 参数控制 -->
        <div class="control-group">
            <label class="control-label">
                粒子数量 
                <span class="range-value" id="particleCountValue">150</span>
            </label>
            <input type="range" class="range-input" id="particleCount" min="50" max="500" value="150" oninput="updateControls()">
        </div>
        <div class="control-group">
            <label class="control-label">
                粒子大小 
                <span class="range-value" id="particleSizeValue">2</span>
            </label>
            <input type="range" class="range-input" id="particleSize" min="0.5" max="8" step="0.5" value="2" oninput="updateControls()">
        </div>
        <div class="control-group">
            <label class="control-label">
                移动速度 
                <span class="range-value" id="speedValue">1</span>
            </label>
            <input type="range" class="range-input" id="speed" min="0.1" max="5" step="0.1" value="1" oninput="updateControls()">
        </div>
        <div class="control-group">
            <label class="control-label">
                连接距离 
                <span class="range-value" id="connectionDistanceValue">100</span>
            </label>
            <input type="range" class="range-input" id="connectionDistance" min="0" max="200" value="100" oninput="updateControls()">
        </div>
        <div class="control-group">
            <label class="control-label">
                鼠标交互半径 
                <span class="range-value" id="mouseRadiusValue">150</span>
            </label>
            <input type="range" class="range-input" id="mouseRadius" min="50" max="300" value="150" oninput="updateControls()">
        </div>
        <div class="action-buttons">
            <button class="action-btn export-btn" onclick="exportCanvas()">💾 导出图片</button>
            <button class="action-btn reset-btn" onclick="resetToDefault()">🔄 重置设置</button>
            <button class="action-btn" onclick="pauseAnimation()">⏸️ 暂停动画</button>
            <button class="action-btn" onclick="toggleFullscreen()">🖥️ 全屏显示</button>
        </div>
        <!-- 代码预览 -->
        <div class="code-preview">
            <h4>📋 CSS 背景代码</h4>
            <div class="code-content" id="cssCode">
                /* 在您的网站中使用此背景 */
                body {
                    background: #000;
                    position: relative;
                }
            </div>
            <button class="copy-code-btn" onclick="copyCSSCode()">复制 CSS 代码</button>
        </div>
    </div>
    <div class="info-panel">
        <div class="fps-counter" id="fpsCounter">FPS: 60</div>
        <div class="particle-count" id="particleCountDisplay">粒子: 150</div>
    </div>
    <script>
        // 全局变量
        let canvas, ctx;
        let particles = [];
        let animationId;
        let mouse = { x: 0, y: 0 };
        let isAnimationPaused = false;
        let currentTheme = 'starry';
        let fps = 0;
        let lastFrameTime = 0;
        let frameCount = 0;
        // 主题配置
        const themes = {
            starry: {
                background: 'radial-gradient(circle, #0c0c0c 0%, #1a1a2e 50%, #16213e 100%)',
                particleColor: ['#ffffff', '#ffffcc', '#fff9c4', '#f0f8ff'],
                connectionColor: 'rgba(255, 255, 255, 0.1)',
                glowEffect: true,
                twinkle: true,
                gravity: false
            },
            snow: {
                background: 'linear-gradient(180deg, #2c3e50 0%, #34495e 50%, #2c3e50 100%)',
                particleColor: ['#ffffff', '#f8f8ff', '#e6f3ff'],
                connectionColor: 'rgba(255, 255, 255, 0.05)',
                glowEffect: false,
                twinkle: false,
                gravity: true
            },
            aurora: {
                background: 'radial-gradient(circle, #001122 0%, #003366 50%, #004488 100%)',
                particleColor: ['#00ff88', '#44ffaa', '#88ffcc', '#aaffdd', '#ff6644', '#ff8866'],
                connectionColor: 'rgba(0, 255, 136, 0.2)',
                glowEffect: true,
                twinkle: true,
                gravity: false
            },
            galaxy: {
                background: 'radial-gradient(circle, #0f0f23 0%, #1a1a3a 50%, #2d2d5a 100%)',
                particleColor: ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#feca57', '#ff9ff3'],
                connectionColor: 'rgba(255, 107, 107, 0.15)',
                glowEffect: true,
                twinkle: true,
                gravity: false
            },
            matrix: {
                background: 'linear-gradient(180deg, #000000 0%, #001100 50%, #000000 100%)',
                particleColor: ['#00ff00', '#44ff44', '#88ff88'],
                connectionColor: 'rgba(0, 255, 0, 0.2)',
                glowEffect: true,
                twinkle: false,
                gravity: false
            },
            neon: {
                background: 'radial-gradient(circle, #0a0a0a 0%, #1a0a2e 50%, #2a1b3d 100%)',
                particleColor: ['#00ffff', '#ff00ff', '#ffff00', '#ff0080'],
                connectionColor: 'rgba(0, 255, 255, 0.3)',
                glowEffect: true,
                twinkle: true,
                gravity: false
            },
            fire: {
                background: 'radial-gradient(circle, #1a0000 0%, #330000 50%, #660000 100%)',
                particleColor: ['#ff4500', '#ff6347', '#ffa500', '#ffff00', '#ff8c00'],
                connectionColor: 'rgba(255, 69, 0, 0.2)',
                glowEffect: true,
                twinkle: true,
                gravity: false
            },
            ocean: {
                background: 'radial-gradient(circle, #001133 0%, #002266 50%, #003399 100%)',
                particleColor: ['#00bfff', '#1e90ff', '#87ceeb', '#b0e0e6'],
                connectionColor: 'rgba(0, 191, 255, 0.15)',
                glowEffect: true,
                twinkle: false,
                gravity: false
            }
        };
        // 预设效果
        const presets = {
            romantic: {
                theme: 'starry',
                particleCount: 200,
                particleSize: 3,
                speed: 0.5,
                connectionDistance: 120,
                mouseRadius: 200,
                particleColor: ['#ffb6c1', '#ffc0cb', '#fff0f5', '#ffe4e1']
            },
            cyberpunk: {
                theme: 'neon',
                particleCount: 300,
                particleSize: 1.5,
                speed: 2,
                connectionDistance: 80,
                mouseRadius: 180,
                particleColor: ['#00ffff', '#ff00ff', '#ffff00']
            },
            forest: {
                theme: 'aurora',
                particleCount: 180,
                particleSize: 2.5,
                speed: 0.8,
                connectionDistance: 90,
                mouseRadius: 160,
                particleColor: ['#228b22', '#32cd32', '#90ee90', '#98fb98']
            },
            space: {
                theme: 'galaxy',
                particleCount: 250,
                particleSize: 1.8,
                speed: 1.2,
                connectionDistance: 150,
                mouseRadius: 220,
                particleColor: ['#ffffff', '#b0c4de', '#87ceeb', '#4169e1']
            },
            retro: {
                theme: 'neon',
                particleCount: 150,
                particleSize: 4,
                speed: 0.6,
                connectionDistance: 100,
                mouseRadius: 150,
                particleColor: ['#ff1493', '#00ffff', '#ffff00', '#ff00ff']
            }
        };
        // 粒子类
        class Particle {
            constructor() {
                this.reset();
                this.y = Math.random() * canvas.height;
            }
            reset() {
                this.x = Math.random() * canvas.width;
                this.y = -10;
                this.vx = (Math.random() - 0.5) * 2;
                this.vy = Math.random() * 2 + 0.5;
                this.size = Math.random() * parseFloat(document.getElementById('particleSize').value) + 0.5;
                this.color = themes[currentTheme].particleColor[Math.floor(Math.random() * themes[currentTheme].particleColor.length)];
                this.opacity = Math.random() * 0.8 + 0.2;
                this.twinkleSpeed = Math.random() * 0.02 + 0.01;
                this.angle = 0;
            }
            update() {
                const speed = parseFloat(document.getElementById('speed').value);
                
                this.x += this.vx * speed;
                this.y += this.vy * speed;
                // 应用重力效果(雪花主题)
                if (themes[currentTheme].gravity) {
                    this.vy += 0.01;
                }
                // 鼠标交互
                const mouseRadius = parseFloat(document.getElementById('mouseRadius').value);
                const dx = mouse.x - this.x;
                const dy = mouse.y - this.y;
                const distance = Math.sqrt(dx * dx + dy * dy);
                if (distance < mouseRadius) {
                    const force = (mouseRadius - distance) / mouseRadius;
                    this.vx -= (dx / distance) * force * 0.1;
                    this.vy -= (dy / distance) * force * 0.1;
                }
                // 闪烁效果
                if (themes[currentTheme].twinkle) {
                    this.angle += this.twinkleSpeed;
                    this.opacity = 0.5 + Math.sin(this.angle) * 0.5;
                }
                // 边界检测
                if (this.x < -10) this.x = canvas.width + 10;
                if (this.x > canvas.width + 10) this.x = -10;
                if (this.y < -10) this.y = canvas.height + 10;
                if (this.y > canvas.height + 10) this.y = -10;
            }
            draw() {
                ctx.save();
                ctx.globalAlpha = this.opacity;
                
                if (themes[currentTheme].glowEffect) {
                    ctx.shadowBlur = 10;
                    ctx.shadowColor = this.color;
                }
                ctx.fillStyle = this.color;
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                ctx.fill();
                ctx.restore();
            }
        }
        // 初始化
        function init() {
            canvas = document.getElementById('particleCanvas');
            ctx = canvas.getContext('2d');
            
            resizeCanvas();
            createParticles();
            setTheme('starry');
            animate();
            // 事件监听
            window.addEventListener('resize', resizeCanvas);
            canvas.addEventListener('mousemove', handleMouseMove);
            canvas.addEventListener('touchmove', handleTouchMove);
            // 更新控制面板
            updateControls();
        }
        // 调整画布大小
        function resizeCanvas() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        }
        // 创建粒子
        function createParticles() {
            particles = [];
            const count = parseInt(document.getElementById('particleCount').value);
            
            for (let i = 0; i < count; i++) {
                particles.push(new Particle());
            }
            
            document.getElementById('particleCountDisplay').textContent = `粒子: ${count}`;
        }
        // 鼠标移动处理
        function handleMouseMove(e) {
            mouse.x = e.clientX;
            mouse.y = e.clientY;
        }
        function handleTouchMove(e) {
            e.preventDefault();
            mouse.x = e.touches[0].clientX;
            mouse.y = e.touches[0].clientY;
        }
        // 绘制连接线
        function drawConnections() {
            const connectionDistance = parseFloat(document.getElementById('connectionDistance').value);
            
            if (connectionDistance === 0) return;
            for (let i = 0; i < particles.length; i++) {
                for (let j = i + 1; j < particles.length; j++) {
                    const dx = particles[i].x - particles[j].x;
                    const dy = particles[i].y - particles[j].y;
                    const distance = Math.sqrt(dx * dx + dy * dy);
                    if (distance < connectionDistance) {
                        const opacity = 1 - (distance / connectionDistance);
                        ctx.strokeStyle = themes[currentTheme].connectionColor.replace('0.1)', `${opacity * 0.3})`);
                        ctx.lineWidth = 0.5;
                        ctx.beginPath();
                        ctx.moveTo(particles[i].x, particles[i].y);
                        ctx.lineTo(particles[j].x, particles[j].y);
                        ctx.stroke();
                    }
                }
            }
        }
        // 动画循环
        function animate(currentTime = 0) {
            if (isAnimationPaused) return;
            // FPS 计算
            frameCount++;
            if (currentTime - lastFrameTime >= 1000) {
                fps = Math.round((frameCount * 1000) / (currentTime - lastFrameTime));
                document.getElementById('fpsCounter').textContent = `FPS: ${fps}`;
                frameCount = 0;
                lastFrameTime = currentTime;
            }
            // 清空画布
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            // 绘制背景渐变
            const gradient = ctx.createRadialGradient(canvas.width/2, canvas.height/2, 0, canvas.width/2, canvas.height/2, Math.max(canvas.width, canvas.height)/2);
            const theme = themes[currentTheme];
            
            // 解析背景渐变
            if (theme.background.includes('radial-gradient')) {
                gradient.addColorStop(0, theme.background.match(/#[a-f0-9]{6}/gi)[0]);
                gradient.addColorStop(0.5, theme.background.match(/#[a-f0-9]{6}/gi)[1] || theme.background.match(/#[a-f0-9]{6}/gi)[0]);
                gradient.addColorStop(1, theme.background.match(/#[a-f0-9]{6}/gi)[2] || theme.background.match(/#[a-f0-9]{6}/gi)[0]);
            }
            
            ctx.fillStyle = gradient;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            // 更新和绘制粒子
            particles.forEach(particle => {
                particle.update();
                particle.draw();
            });
            // 绘制连接线
            drawConnections();
            animationId = requestAnimationFrame(animate);
        }
        // 设置主题
        function setTheme(themeName) {
            currentTheme = themeName;
            
            // 更新主题按钮状态
            document.querySelectorAll('.theme-btn').forEach(btn => {
                btn.classList.remove('active');
            });
            document.querySelector(`[data-theme="${themeName}"]`).classList.add('active');
            // 重新创建粒子以应用新颜色
            particles.forEach(particle => {
                particle.color = themes[currentTheme].particleColor[Math.floor(Math.random() * themes[currentTheme].particleColor.length)];
            });
            // 更新背景
            document.body.style.background = themes[currentTheme].background;
            
            updateCSSCode();
        }
        // 应用预设
        function applyPreset(presetName) {
            const preset = presets[presetName];
            
            // 设置控制器值
            document.getElementById('particleCount').value = preset.particleCount;
            document.getElementById('particleSize').value = preset.particleSize;
            document.getElementById('speed').value = preset.speed;
            document.getElementById('connectionDistance').value = preset.connectionDistance;
            document.getElementById('mouseRadius').value = preset.mouseRadius;
            
            // 应用主题
            setTheme(preset.theme);
            
            // 如果有自定义颜色,应用它们
            if (preset.particleColor) {
                themes[currentTheme].particleColor = preset.particleColor;
            }
            
            // 重新创建粒子
            createParticles();
            updateControls();
        }
        // 更新控制器
        function updateControls() {
            document.getElementById('particleCountValue').textContent = document.getElementById('particleCount').value;
            document.getElementById('particleSizeValue').textContent = document.getElementById('particleSize').value;
            document.getElementById('speedValue').textContent = document.getElementById('speed').value;
            document.getElementById('connectionDistanceValue').textContent = document.getElementById('connectionDistance').value;
            document.getElementById('mouseRadiusValue').textContent = document.getElementById('mouseRadius').value;
            
            // 实时更新粒子数量
            const newCount = parseInt(document.getElementById('particleCount').value);
            if (particles.length !== newCount) {
                createParticles();
            }
            
            updateCSSCode();
        }
        // 更新CSS代码
        function updateCSSCode() {
            const theme = themes[currentTheme];
            const code = `/* 动态粒子背景 CSS */
body {
    background: ${theme.background};
    position: relative;
    overflow: hidden;
}
/* 粒子容器 */
.particle-background {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
    pointer-events: none;
}
/* 配置参数 */
/* 粒子数量: ${document.getElementById('particleCount').value} */
/* 粒子大小: ${document.getElementById('particleSize').value}px */
/* 移动速度: ${document.getElementById('speed').value} */
/* 连接距离: ${document.getElementById('connectionDistance').value}px */`;
            document.getElementById('cssCode').textContent = code;
        }
        // 导出画布
        function exportCanvas() {
            const link = document.createElement('a');
            link.download = `particle-background-${currentTheme}-${Date.now()}.png`;
            link.href = canvas.toDataURL();
            link.click();
        }
        // 复制CSS代码
        function copyCSSCode() {
            const code = document.getElementById('cssCode').textContent;
            navigator.clipboard.writeText(code).then(() => {
                alert('CSS代码已复制到剪贴板!');
            });
        }
        // 重置到默认设置
        function resetToDefault() {
            document.getElementById('particleCount').value = 150;
            document.getElementById('particleSize').value = 2;
            document.getElementById('speed').value = 1;
            document.getElementById('connectionDistance').value = 100;
            document.getElementById('mouseRadius').value = 150;
            
            setTheme('starry');
            createParticles();
            updateControls();
        }
        // 暂停/恢复动画
        function pauseAnimation() {
            isAnimationPaused = !isAnimationPaused;
            const btn = event.target;
            
            if (isAnimationPaused) {
                btn.textContent = '▶️ 恢复动画';
                cancelAnimationFrame(animationId);
            } else {
                btn.textContent = '⏸️ 暂停动画';
                animate();
            }
        }
        // 全屏显示
        function toggleFullscreen() {
            if (!document.fullscreenElement) {
                document.documentElement.requestFullscreen();
            } else {
                document.exitFullscreen();
            }
        }
        // 切换控制面板
        function toggleControlPanel() {
            const panel = document.getElementById('controlPanel');
            panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
        }
        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', init);
        // 键盘快捷键
        document.addEventListener('keydown', function(e) {
            switch(e.key) {
                case ' ':
                    e.preventDefault();
                    pauseAnimation();
                    break;
                case 'f':
                case 'F':
                    toggleFullscreen();
                    break;
                case 'h':
                case 'H':
                    toggleControlPanel();
                    break;
                case 'r':
                case 'R':
                    resetToDefault();
                    break;
            }
        });
    </script>
</body>
</html>
相关文章
大模型应用开发-LangChain入门教程
大模型应用开发-LangChain入门教程
459 0
|
安全
在钉钉中,Stream 模式审批回调怎么弄?
在钉钉中,Stream 模式审批回调怎么弄?
612 1
|
3月前
|
人工智能 IDE 定位技术
通义灵码 AI IDE 上线,第一时间测评体验
通义灵码 AI IDE 重磅上线,开启智能编程新纪元!无需插件,开箱即用,依托通义千问大模型,实现高效、智能的编程体验。支持 MCP 工具链,可快速调用多种服务(如12306余票查询、高德地图标注等),大幅提升开发效率。结合 Qwen3 强大的 Agent 能力,开发者可通过自然语言快速构建功能,如智能选票系统、地图可视化页面等。行间代码预测、AI 规则定制、记忆能力等功能,让 AI 更懂你的编码习惯。Lingma IDE 不仅是工具,更是开发者身边的智能助手,助力 AI 编程落地实践。立即下载体验,感受未来编程的魅力!
510 17
|
2月前
|
消息中间件 供应链 前端开发
如何开发进销存系统中的库存管理板块?(附架构图+流程图+代码参考)
进销存系统中的库存管理是企业运营关键环节,影响效率、资金周转与物流成本。本文详解库存管理概念、模块结构、业务流程及开发技巧,通过示例代码展示入库、出库等功能实现,助力企业优化库存管理,提升运作效率。
|
关系型数据库 Shell Linux
|
1月前
|
人工智能 数据可视化
关于AI编程对普通人的一个最大的缺点
AI虽擅长编码,但图形界面设计能力较弱,普通人难以通过命令行操作。建议集成可视化UI设计工具,如拖拽组件、精准设尺寸,让AI生成代码,减少反复调试,提升效率。
|
资源调度 前端开发 JavaScript
web实现酷炫的canvas粒子动画背景
web实现酷炫的canvas粒子动画背景
444 0
|
10月前
|
Web App开发 JavaScript 前端开发
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念,包括事件驱动、单线程模型和模块系统;探讨其安装配置、核心模块使用、实战应用如搭建 Web 服务器、文件操作及实时通信;分析项目结构与开发流程,讨论其优势与挑战,并通过案例展示 Node.js 在实际项目中的应用,旨在帮助开发者更好地掌握这一强大工具。
258 1
|
JavaScript 中间件 API
深入浅出Node.js后端框架——Express
【8月更文挑战第27天】在这篇文章中,我们将一起探索Node.js的热门框架Express。Express以其简洁、高效的特点,成为了许多Node.js开发者的首选框架。本文将通过实例引导你了解Express的核心概念和使用方法,让你快速上手构建自己的Web应用。
|
12月前
|
前端开发 Java 应用服务中间件

热门文章

最新文章