分享图
动画工坊
引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>被动分流器均布原理 (TRIZ 理想解)</title>
    <link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;600;700&family=Noto+Sans+SC:wght@300;500;700&display=swap" rel="stylesheet">
    <style>
        :root {
            --bg-color: #060913;
            --grid-color: #121A2F;
            --accent-cyan: #00F3FF;
            --accent-magenta: #FF2A6D;
            --text-main: #D1F2EB;
            --text-muted: #5B7586;
            --panel-bg: rgba(10, 15, 30, 0.7);
        }

        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            background-color: var(--bg-color);
            color: var(--text-main);
            font-family: 'Noto Sans SC', sans-serif;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* 背景网格与纹理 */
        .bg-layer {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-image: 
                linear-gradient(var(--grid-color) 1px, transparent 1px),
                linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
            background-size: 40px 40px;
            background-position: center center;
            opacity: 0.4;
            z-index: 0;
            pointer-events: none;
        }

        .bg-glow {
            position: absolute;
            width: 800px;
            height: 800px;
            background: radial-gradient(circle, rgba(0, 243, 255, 0.05) 0%, transparent 60%);
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            z-index: 0;
            pointer-events: none;
        }

        /* 主容器 */
        .dashboard {
            position: relative;
            width: 100%;
            max-width: 1400px;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 1;
        }

        /* SVG 动画区域 */
        svg {
            width: 100%;
            height: 100%;
            max-height: 900px;
            filter: drop-shadow(0 0 20px rgba(0, 243, 255, 0.1));
        }

        /* 浮动控制面板 */
        .control-panel {
            position: absolute;
            bottom: 40px;
            left: 40px;
            background: var(--panel-bg);
            border: 1px solid rgba(0, 243, 255, 0.2);
            border-radius: 8px;
            padding: 20px;
            width: 280px;
            backdrop-filter: blur(10px);
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            font-family: 'Chakra Petch', 'Noto Sans SC', sans-serif;
            z-index: 10;
        }

        .panel-title {
            font-size: 14px;
            font-weight: 700;
            color: var(--accent-magenta);
            margin-bottom: 15px;
            text-transform: uppercase;
            letter-spacing: 1px;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .panel-title::before {
            content: '';
            display: block;
            width: 8px;
            height: 8px;
            background: var(--accent-magenta);
            box-shadow: 0 0 10px var(--accent-magenta);
        }

        .control-group {
            margin-bottom: 15px;
        }

        .control-label {
            font-size: 12px;
            color: var(--text-muted);
            margin-bottom: 8px;
            display: flex;
            justify-content: space-between;
        }

        .val-display {
            color: var(--accent-cyan);
            font-weight: 600;
        }

        /* 自定义滑块 */
        input[type=range] {
            -webkit-appearance: none;
            width: 100%;
            background: transparent;
        }
        input[type=range]::-webkit-slider-thumb {
            -webkit-appearance: none;
            height: 14px;
            width: 14px;
            border-radius: 50%;
            background: var(--accent-cyan);
            cursor: pointer;
            margin-top: -5px;
            box-shadow: 0 0 10px var(--accent-cyan);
        }
        input[type=range]::-webkit-slider-runnable-track {
            width: 100%;
            height: 4px;
            cursor: pointer;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 2px;
        }

        /* 标题区域 */
        .header-title {
            position: absolute;
            top: 40px;
            left: 40px;
            z-index: 10;
            pointer-events: none;
        }

        .header-title h1 {
            margin: 0;
            font-size: 24px;
            font-weight: 700;
            color: #fff;
            letter-spacing: 2px;
            font-family: 'Chakra Petch', 'Noto Sans SC', sans-serif;
            text-shadow: 0 0 15px rgba(0, 243, 255, 0.5);
        }

        .header-title p {
            margin: 5px 0 0 0;
            font-size: 12px;
            color: var(--text-muted);
            letter-spacing: 1px;
        }

        /* SVG 样式 */
        .svg-text {
            font-family: 'Chakra Petch', 'Noto Sans SC', sans-serif;
            font-size: 12px;
            fill: var(--text-muted);
            letter-spacing: 1px;
        }
        .svg-text-highlight {
            fill: var(--accent-magenta);
            font-weight: 700;
        }
        .svg-text-cyan {
            fill: var(--accent-cyan);
        }
        .svg-line-guide {
            stroke: var(--text-muted);
            stroke-width: 1;
            stroke-dasharray: 2, 2;
        }
        .vibrating-screen {
            animation: vibrate 0.1s linear infinite alternate;
        }

        @keyframes vibrate {
            0% { transform: translateY(0); }
            100% { transform: translateY(1.5px); }
        }

        @keyframes pulse-glow {
            0% { filter: drop-shadow(0 0 5px var(--accent-magenta)); }
            100% { filter: drop-shadow(0 0 15px var(--accent-magenta)); }
        }
        
        .weir-plate {
            animation: pulse-glow 2s infinite alternate;
        }
    </style>
</head>
<body>

    <div class="bg-layer"></div>
    <div class="bg-glow"></div>

    <div class="dashboard">
        
        <div class="header-title">
            <h1>被动分流均布系统</h1>
            <p>TRIZ 最终理想解 (IFR) · 核心原理演示</p>
        </div>

        <div class="control-panel">
            <div class="panel-title">流体边界条件模拟</div>
            <div class="control-group">
                <div class="control-label">
                    <span>流体粘度 (Viscosity)</span>
                    <span class="val-display" id="vis-val">低</span>
                </div>
                <input type="range" id="viscosity-slider" min="1" max="10" step="0.5" value="2">
                <div style="font-size: 10px; color: var(--text-muted); margin-top: 6px; line-height: 1.4;">
                    * 观察失效边界:粘度升高会导致水平展布受阻,流体集中于中部,体现该方案“适用于低粘度钻井液”的物理约束。
                </div>
            </div>
        </div>

        <svg viewBox="0 0 1200 800" preserveAspectRatio="xMidYMid meet">
            <defs>
                <filter id="glow-cyan" x="-20%" y="-20%" width="140%" height="140%">
                    <feGaussianBlur stdDeviation="3" result="blur" />
                    <feComposite in="SourceGraphic" in2="blur" operator="over" />
                </filter>
                <filter id="glow-magenta" x="-20%" y="-20%" width="140%" height="140%">
                    <feGaussianBlur stdDeviation="5" result="blur" />
                    <feComposite in="SourceGraphic" in2="blur" operator="over" />
                </filter>
                
                <linearGradient id="chute-grad" x1="0%" y1="0%" x2="0%" y2="100%">
                    <stop offset="0%" stop-color="#121A2F" stop-opacity="0.8" />
                    <stop offset="100%" stop-color="#060913" stop-opacity="0" />
                </linearGradient>
            </defs>

            <!-- 物理结构背景 -->
            <g id="infrastructure">
                <!-- 进料溜槽 (外壳轮廓) -->
                <path d="M 500 50 L 500 200 L 250 280 L 250 650" fill="none" stroke="#1C2A43" stroke-width="2" />
                <path d="M 700 50 L 700 200 L 950 280 L 950 650" fill="none" stroke="#1C2A43" stroke-width="2" />
                
                <path d="M 500 50 L 700 50 L 700 200 L 950 280 L 950 650 L 250 650 L 250 280 L 500 200 Z" fill="url(#chute-grad)" opacity="0.3" />

                <!-- 整流栅格 -->
                <g stroke="#1C2A43" stroke-width="1" stroke-dasharray="4, 4" opacity="0.6">
                    <line x1="250" y1="320" x2="950" y2="320" />
                    <line x1="250" y1="340" x2="950" y2="340" />
                    <line x1="250" y1="360" x2="950" y2="360" />
                </g>

                <!-- 底部筛面 -->
                <g class="vibrating-screen">
                    <line x1="200" y1="650" x2="1000" y2="650" stroke="#39FF14" stroke-width="4" filter="url(#glow-cyan)" />
                    <line x1="200" y1="660" x2="1000" y2="660" stroke="#1C2A43" stroke-width="2" />
                    <!-- 筛孔指示 -->
                    <path d="M 220 650 L 230 670 M 260 650 L 270 670 M 300 650 L 310 670 M 340 650 L 350 670 M 380 650 L 390 670 M 420 650 L 430 670 M 460 650 L 470 670 M 500 650 L 510 670 M 540 650 L 550 670 M 580 650 L 590 670 M 620 650 L 630 670 M 660 650 L 670 670 M 700 650 L 710 670 M 740 650 L 750 670 M 780 650 L 790 670 M 820 650 L 830 670 M 860 650 L 870 670 M 900 650 L 910 670 M 940 650 L 950 670 M 980 650 L 990 670" stroke="#39FF14" stroke-width="1" opacity="0.3" />
                </g>
            </g>

            <!-- 动态粒子层(通过 JS 填充) -->
            <g id="fluid-particles"></g>

            <!-- 核心创新件:锯齿堰板 (放置在流体之上以突显切割作用) -->
            <g id="weir-system" class="weir-plate">
                <!-- 由 JS 动态生成精确的锯齿路径 -->
                <path id="weir-path" fill="none" stroke="var(--accent-magenta)" stroke-width="4" stroke-linejoin="miter" filter="url(#glow-magenta)" />
                <path id="weir-base" fill="none" stroke="var(--accent-magenta)" stroke-width="2" opacity="0.5" />
            </g>

            <!-- 注释与引线 (严控位置,不遮挡中心) -->
            <g id="annotations">
                <!-- 顶部:集中液流 -->
                <line x1="550" y1="120" x2="680" y2="80" class="svg-line-guide" />
                <circle cx="550" cy="120" r="3" fill="var(--text-muted)" />
                <text x="690" y="75" class="svg-text svg-text-cyan">集中入料液流</text>
                <text x="690" y="90" class="svg-text" style="font-size:10px;">初始状态:分布极不均匀</text>

                <!-- 核心:锯齿堰板 -->
                <line x1="850" y1="280" x2="980" y2="240" class="svg-line-guide" stroke="var(--accent-magenta)" />
                <circle cx="850" cy="280" r="3" fill="var(--accent-magenta)" />
                <text x="990" y="235" class="svg-text svg-text-highlight">IFR: 被动锯齿堰板</text>
                <text x="990" y="255" class="svg-text" style="font-size:10px;">利用重力与几何构型切割流体</text>
                <text x="990" y="270" class="svg-text" style="font-size:10px;">开孔率: 45%~65% | 齿距: 50mm</text>
                <text x="990" y="285" class="svg-text" style="font-size:10px;">零能耗实现宽度方向均匀分配</text>

                <!-- 下部:多股细流 -->
                <line x1="800" y1="500" x2="980" y2="500" class="svg-line-guide" />
                <circle cx="800" cy="500" r="3" fill="var(--text-muted)" />
                <text x="990" y="495" class="svg-text svg-text-cyan">多股均匀射流</text>
                <text x="990" y="510" class="svg-text" style="font-size:10px;">消除局部过载矛盾</text>

                <!-- 底部:筛面 -->
                <line x1="280" y1="650" x2="150" y2="600" class="svg-line-guide" />
                <circle cx="280" cy="650" r="3" fill="var(--text-muted)" />
                <text x="50" y="590" class="svg-text" style="fill:#39FF14">均布作业筛面</text>
            </g>
        </svg>
    </div>

    <script>
        document.addEventListener("DOMContentLoaded", () => {
            // 系统参数配置
            const config = {
                particleCount: 500,        // 粒子总数
                chuteTop: 50,              // 进料高度
                weirY: 280,                // 堰板基础高度
                toothHeight: 30,           // 锯齿高度 (250 到 280)
                screenY: 650,              // 筛面高度
                weirStartX: 250,           // 堰板左边界
                weirEndX: 950,             // 堰板右边界
                valleyCount: 14            // 谷底(细流)数量
            };

            // 计算锯齿几何坐标
            const width = config.weirEndX - config.weirStartX;
            const pitch = width / config.valleyCount;
            const valleys = [];
            const peaks = [];
            
            let pathD = `M ${config.weirStartX} ${config.weirY}`;
            let baseY = config.weirY;
            let peakY = config.weirY - config.toothHeight;

            for (let i = 0; i < config.valleyCount; i++) {
                let peakX = config.weirStartX + i * pitch + pitch / 2;
                let valleyX = config.weirStartX + (i + 1) * pitch;
                
                peaks.push(peakX);
                valleys.push(valleyX - pitch/2); // 将细流位置对准谷底
                
                pathD += ` L ${peakX} ${peakY} L ${valleyX} ${baseY}`;
            }

            // 绘制静态锯齿堰板
            document.getElementById('weir-path').setAttribute('d', pathD);
            document.getElementById('weir-base').setAttribute('d', `M ${config.weirStartX} ${config.weirY} L ${config.weirEndX} ${config.weirY}`);

            // 交互控制
            const visSlider = document.getElementById('viscosity-slider');
            const visDisplay = document.getElementById('vis-val');
            let fluidViscosity = parseFloat(visSlider.value);

            visSlider.addEventListener('input', (e) => {
                fluidViscosity = parseFloat(e.target.value);
                if (fluidViscosity < 4) visDisplay.textContent = '低 (理想工作区)';
                else if (fluidViscosity < 7) visDisplay.textContent = '中 (展布受限)';
                else visDisplay.textContent = '高 (边界失效警告)';
            });

            // 粒子系统类
            const svgns = "http://www.w3.org/2000/svg";
            const particleGroup = document.getElementById('fluid-particles');
            const particles = [];

            class Particle {
                constructor() {
                    this.el = document.createElementNS(svgns, "circle");
                    this.el.setAttribute("fill", "var(--accent-cyan)");
                    this.el.setAttribute("filter", "url(#glow-cyan)");
                    particleGroup.appendChild(this.el);
                    this.reset(true);
                }

                reset(initial = false) {
                    // 集中入料:位于 550 到 650 之间
                    this.x = 550 + Math.random() * 100;
                    this.y = initial ? Math.random() * 200 : config.chuteTop;
                    this.vx = (Math.random() - 0.5) * 1.5;
                    this.vy = 4 + Math.random() * 3;
                    this.state = 'falling_in'; // falling_in, spreading, falling_out
                    this.r = 2 + Math.random() * 2.5;
                    
                    this.el.setAttribute("r", this.r);
                    this.el.setAttribute("opacity", 0.8 + Math.random() * 0.2);
                }

                update() {
                    // 物理状态机
                    if (this.state === 'falling_in') {
                        // 触及堰板液面区域 (蓄水池效果)
                        if (this.y > config.weirY - config.toothHeight - 10) {
                            this.state = 'spreading';
                            // 赋予水平展布速度,受粘度直接制约
                            const dir = this.x < 600 ? -1 : 1;
                            // 粘度越大,vx 越小,越难到达两侧
                            this.vx = dir * (2 + Math.random() * 8) / (fluidViscosity * 0.8);
                            this.vy = 0.8; // 缓冲区的缓慢垂直下沉
                        }
                    } 
                    else if (this.state === 'spreading') {
                        // 寻找最近的锯齿谷底
                        let inValley = false;
                        for (let v of valleys) {
                            if (Math.abs(this.x - v) < 6) { // 谷底捕获宽度
                                inValley = true;
                                this.vx = this.vx * 0.2; // 阻尼
                                break;
                            }
                        }

                        // 如果到达谷底高度,或被谷底捕获
                        if (inValley || this.y >= config.weirY - 2) {
                            this.state = 'falling_out';
                            this.vx = (Math.random() - 0.5) * 0.5; // 保持细流垂直
                            this.vy = 5 + Math.random() * 4; // 加速下落
                        }
                        
                        // 边界处理:防止溢出溜槽
                        const leftBound = 500 - ((this.y - 50) / 230) * 250;
                        const rightBound = 700 + ((this.y - 50) / 230) * 250;
                        if (this.x < leftBound || this.x > rightBound) {
                            this.vx *= -1;
                        }
                    }

                    // 运动更新
                    this.x += this.vx;
                    this.y += this.vy;

                    // 到达筛面:产生细微溅射后重置
                    if (this.y > config.screenY) {
                        this.reset();
                    }

                    // 渲染更新
                    this.el.setAttribute("cx", this.x);
                    this.el.setAttribute("cy", this.y);
                }
            }

            // 初始化粒子群
            for (let i = 0; i < config.particleCount; i++) {
                particles.push(new Particle());
            }

            // 动画循环 (自动播放,重载即播)
            function animate() {
                for (let p of particles) {
                    p.update();
                }
                requestAnimationFrame(animate);
            }

            // 启动
            requestAnimationFrame(animate);
        });
    </script>
</body>
</html>
积分规则:每轮对话扣10分