xBlog 背景相关代码

简约平替版:

第一步:CSS 代码 - 粘贴到 style.css 文件中

/* ==========================================
   动态背景
   ========================================== */
.bg-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
    overflow: hidden;
    filter: blur(380px) contrast(120%);
    background-color: #FDFFF0;
}

.fluid-shape {
    position: absolute;
    top: 0; 
    left: 0;
    border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%; /* 初始不规则形状 */
    opacity: 0.95;
    will-change: transform;
    animation: drift linear infinite;
}

/* 飘动动画 */
@keyframes drift {
    0% { transform: translate(0, 0) rotate(0deg) scale(1); }
    25% { transform: translate(50px, -50px) rotate(90deg) scale(1.1); }
    50% { transform: translate(0, 50px) rotate(180deg) scale(0.9); }
    75% { transform: translate(-50px, 0) rotate(270deg) scale(1.05); }
    100% { transform: translate(0, 0) rotate(360deg) scale(1); }
}

/* 形状变形动画 */
@keyframes morph {
    0% { border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%; }
    33% { border-radius: 70% 30% 30% 70% / 60% 40% 60% 40%; }
    66% { border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%; }
    100% { border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%; }
}

第二步:HTML 代码 - 粘贴到 header.php <body> 最上方

<!-- 动态背景容器 -->
<div class="bg-container" id="bgContainer"></div>

第三步:JavaScript 代码 - 粘贴到 header.php </body> 标签之前

<!-- 动态背景容器 -->
<script>
    document.addEventListener('DOMContentLoaded', () => {
        const container = document.getElementById('bgContainer');
        const colors = ['#86DFE9', '#A4EFF4', '#FDFFF0', '#D6F2C7'];
        const shapeCount = 8; // 生成多少个色块,可以改这个数字

        for (let i = 0; i < shapeCount; i++) {
            createShape();
        }

        function createShape() {
            const div = document.createElement('div');
            div.classList.add('fluid-shape');

            // 1. 随机大小 (30vw 到 60vw 之间)
            const size = Math.random() * 30 + 180; 
            div.style.width = `${size}vw`;
            div.style.height = `${size}vw`;

            // 2. 随机颜色
            div.style.background = colors[Math.floor(Math.random() * colors.length)];

            // 3. 随机位置 (-10% 到 100% 之间,确保能飘进屏幕)
            const posX = Math.random() * 110 - 10;
            const posY = Math.random() * 110 - 10;
            div.style.left = `${posX}%`;
            div.style.top = `${posY}%`;

            // 4. 随机动画时长 (20s 到 40s),让速度不一样
            const duration = Math.random() * 20 + 20;
            div.style.animationDuration = `${duration}s, ${duration}s`; // 同时应用到 drift 和 morph

            // 5. 应用变形动画
            // 注意:这里我们给它添加第二个动画效果 'morph'
            div.style.animationName = 'drift, morph';

            container.appendChild(div);
        }
    });
</script>

织物质感背景

/* 织物质感背景 */
body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: 
        repeating-linear-gradient(
            0deg,
            transparent,
            transparent 2px,
            rgba(46, 164, 79, 0.05) 2px, /* 0.1 */
            rgba(46, 164, 79, 0.05) 4px /* 0.1 */
        ),
        repeating-linear-gradient(
            90deg,
            transparent,
            transparent 2px,
            rgba(46, 164, 79, 0.03) 2px, /* 0.08 */
            rgba(46, 164, 79, 0.03) 4px /* 0.08 */
        );
    background-size: 40px 40px;
    z-index: -1;
    pointer-events: none;
    opacity: 0.6;
}

/* 深色模式适配 */
@media (prefers-color-scheme: dark) {
    body::before {
        background: 
            repeating-linear-gradient(
                0deg,
                transparent,
                transparent 2px,
                rgba(46, 164, 79, 0.08) 2px,
                rgba(46, 164, 79, 0.08) 4px
            ),
            repeating-linear-gradient(
                90deg,
                transparent,
                transparent 2px,
                rgba(46, 164, 79, 0.05) 2px,
                rgba(46, 164, 79, 0.05) 4px
            );
        opacity: 0.4;
    }
}

/* 移动端优化 */
@media (max-width: 768px) {
    body::before {
        background-size: 60px 60px;
        opacity: 0.4;
    }
}

现代噪点纸质感

/* 现代噪点纸质感 */
body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    /* 使用SVG生成噪点纹理,无需外部图片 */
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='0.08'/%3E%3C/svg%3E");
    background-color: #f9f9f9; /* 极淡的暖灰底色 */
    z-index: -1;
    pointer-events: none;
    opacity: 1;
}

@media (prefers-color-scheme: dark) {
    body::before {
        background-color: #1a1a1a; /* 深灰底色 */
        /* 深色模式下噪点稍微亮一点,增加层次 */
        background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='0.1'/%3E%3C/svg%3E");
    }
}

@media (max-width: 768px) {
    body::before {
        /* 移动端稍微减少噪点密度,看起来更干净 */
        background-size: 150px 150px;
    }
}

极简几何点阵

/* 极简几何点阵 */
body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #f8fafc; /* 极淡的冷灰色 */
    background-image: radial-gradient(#94a3b8 1px, transparent 1px);
    background-size: 30px 30px; /* 点之间的间距 */
    z-index: -1;
    pointer-events: none;
    opacity: 1;
}

@media (prefers-color-scheme: dark) {
    body::before {
        background-color: #0f172a; /* 深蓝灰底色 */
        background-image: radial-gradient(#334155 1px, transparent 1px); /* 深色的点 */
    }
}

@media (max-width: 768px) {
    body::before {
        /* 移动端把点阵放大,减少视觉噪音 */
        background-size: 40px 40px;
    }
}

极光弥散背景

/* 极光弥散背景 */
body {
    background-color: #f8fafc; /* 浅色模式底色 */
}
body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    /* 四角柔和光斑:紫、蓝、粉、靛 */
    background-image: 
        radial-gradient(at 0% 0%, rgba(192, 132, 252, 0.15) 0px, transparent 50%),
        radial-gradient(at 100% 0%, rgba(96, 165, 250, 0.15) 0px, transparent 50%),
        radial-gradient(at 0% 100%, rgba(244, 114, 182, 0.15) 0px, transparent 50%),
        radial-gradient(at 100% 100%, rgba(129, 140, 248, 0.15) 0px, transparent 50%);
    filter: blur(40px); /* 关键:高斯模糊制造弥散感 */
    z-index: -1;
    pointer-events: none;
    opacity: 0.8;
}

/* 深色模式适配 */
@media (prefers-color-scheme: dark) {
    body {
        background-color: #0f172a; /* 深色模式底色 */
    }
    body::before {
        /* 深色模式下加深颜色,模拟发光 */
        background-image: 
            radial-gradient(at 0% 0%, rgba(139, 92, 246, 0.25) 0px, transparent 50%),
            radial-gradient(at 100% 0%, rgba(56, 189, 248, 0.25) 0px, transparent 50%),
            radial-gradient(at 0% 100%, rgba(236, 72, 153, 0.2) 0px, transparent 50%),
            radial-gradient(at 100% 100%, rgba(99, 102, 241, 0.2) 0px, transparent 50%);
        filter: blur(60px); /* 模糊范围更大 */
        opacity: 0.6;
    }
}

/* 移动端优化 */
@media (max-width: 768px) {
    body::before {
        filter: blur(30px); /* 减少模糊以提升移动端性能 */
        opacity: 0.6;
    }
}

NodeSeek 背景

<body class="grid-bg">
    <!-- 页面内容 -->
</body>
/* 基础方格背景(浅色模式) */
.grid-bg {
    background-color: #fffcf8;
    background-image: 
        linear-gradient(#d4d4d4 1px, transparent 1px),
        linear-gradient(90deg, #d4d4d4 1px, transparent 1px);
    background-size: 32px 32px;
}

/* 深色模式 */
.dark-mode .grid-bg {
    background-color: #272727;
    background-image: 
        linear-gradient(#555 1px, transparent 1px),
        linear-gradient(90deg, #555 1px, transparent 1px);
    background-size: 32px 32px;
}

/* 菱形背景(可选) */
.grid-diamond {
    background-color: #fff;
    background-image: 
        linear-gradient(135deg, #d4d4d4 25%, transparent 25%),
        linear-gradient(225deg, #d4d4d4 25%, transparent 25%),
        linear-gradient(45deg, #d4d4d4 25%, transparent 25%),
        linear-gradient(315deg, #d4d4d4 25%, #f5f5f5 25%);
    background-position: 0 0, 0 0, 32px 32px, 32px 32px;
    background-size: 64px 64px;
}

菱形背景

/* 菱形背景 */
body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: 
        repeating-linear-gradient(
            45deg,
            transparent,
            transparent 10px,
            rgba(52, 168, 83, 0.04) 10px,
            rgba(52, 168, 83, 0.04) 20px
        ),
        repeating-linear-gradient(
            -45deg,
            transparent,
            transparent 10px,
            rgba(66, 133, 244, 0.03) 10px,
            rgba(66, 133, 244, 0.03) 20px
        );
    background-size: 100% 100%;
    z-index: -1;
    pointer-events: none;
    opacity: 0.6;
}

/* 深色模式适配 */
@media (prefers-color-scheme: dark) {
    body::before {
        background: 
            repeating-linear-gradient(
                45deg,
                transparent,
                transparent 10px,
                rgba(52, 168, 83, 0.06) 10px,
                rgba(52, 168, 83, 0.06) 20px
            ),
            repeating-linear-gradient(
                -45deg,
                transparent,
                transparent 15px,
                rgba(66, 133, 244, 0.04) 15px,
                rgba(66, 133, 244, 0.04) 30px
            );
        opacity: 0.4;
    }
}

/* 移动端优化 */
@media (max-width: 768px) {
    body::before {
        opacity: 0.4;
    }
}

水彩晕染背景

/* 水彩晕染背景 */
body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: 
        radial-gradient(ellipse at 20% 20%, rgba(137, 196, 244, 0.15) 0%, transparent 40%),
        radial-gradient(ellipse at 80% 80%, rgba(244, 137, 235, 0.12) 0%, transparent 40%),
        radial-gradient(ellipse at 40% 60%, rgba(137, 244, 195, 0.1) 0%, transparent 40%),
        radial-gradient(ellipse at 60% 20%, rgba(244, 194, 137, 0.1) 0%, transparent 40%);
    background-blend-mode: overlay;
    filter: blur(2px);
    z-index: -1;
    pointer-events: none;
    opacity: 0.8;
}

/* 深色模式适配 */
@media (prefers-color-scheme: dark) {
    body::before {
        background: 
            radial-gradient(ellipse at 20% 20%, rgba(100, 150, 220, 0.2) 0%, transparent 40%),
            radial-gradient(ellipse at 80% 80%, rgba(220, 100, 200, 0.15) 0%, transparent 40%),
            radial-gradient(ellipse at 40% 60%, rgba(100, 220, 150, 0.15) 0%, transparent 40%);
        filter: blur(3px);
        opacity: 0.4;
    }
}

/* 移动端优化 */
@media (max-width: 768px) {
    body::before {
        filter: blur(1px);
        opacity: 0.5;
    }
}

霓虹渐变背景

/* 霓虹渐变背景 */
body::before {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: 
        radial-gradient(
            ellipse at center,
            #00ff88 0%,
            transparent 90%
        ),
        radial-gradient(
            ellipse at 80% 20%,
            #ff0055 0%,
            transparent 70%
        );
    background-blend-mode: screen;
    filter: contrast(300%) brightness(150%);
    z-index: -1;
    pointer-events: none;
    opacity: 0.3;
}

/* 深色模式适配 */
@media (prefers-color-scheme: dark) {
    body::before {
        background: 
            radial-gradient(
                ellipse at center,
                #00ff88 0%,
                transparent 80%
            ),
            radial-gradient(
                ellipse at 20% 80%,
                #ff0055 0%,
                transparent 60%
            );
        filter: contrast(400%) brightness(200%);
        opacity: 0.6;
        mix-blend-mode: overlay;
    }
}

/* 移动端优化 */
@media (max-width: 768px) {
    body::before {
        filter: contrast(200%) brightness(120%);
        opacity: 0.6;
    }
}

颗粒质感霓虹渐变背景

/* 颗粒质感霓虹渐变 */
body::before {
    content: '';
    position: fixed;
    top: -50%;
    left: -50%;
    width: 220%;
    height: 220%;
    background: 
        radial-gradient(
            ellipse at center,
            #00ff88 0%,
            transparent 60%
        ),
        radial-gradient(
            ellipse at 50% 40%,
            #ff0044 0%,
            transparent 40%
        );
    background-blend-mode: screen;
    filter: contrast(300%) brightness(150%);
    z-index: -1;
    pointer-events: none;
    opacity: 0.35;
    animation: rotateAndShift 8s ease-in-out infinite;
}

/* 静态颗粒纹理层 */
body::after {
    content: '';
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
    pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
    opacity: 1;
    mix-blend-mode: overlay;
}

/* 旋转和位移动画 */
@keyframes rotateAndShift {
    0%, 100% {
        transform: translate(0, 0) rotate(0deg);
        filter: contrast(300%) brightness(150%) hue-rotate(0deg);
    }
    25% {
        transform: translate(5%, -5%) rotate(5deg);
        filter: contrast(320%) brightness(160%) hue-rotate(15deg);
    }
    50% {
        transform: translate(-5%, 5%) rotate(-5deg);
        filter: contrast(340%) brightness(170%) hue-rotate(30deg);
    }
    75% {
        transform: translate(3%, 3%) rotate(3deg);
        filter: contrast(320%) brightness(160%) hue-rotate(15deg);
    }
}

/* 深色模式适配 */
@media (prefers-color-scheme: dark) {
    body::before {
        background: 
            radial-gradient(
                ellipse at center,
                #00ff88 0%,
                transparent 80%
            ),
            radial-gradient(
                ellipse at 20% 80%,
                #ff0055 0%,
                transparent 60%
            );
        filter: contrast(400%) brightness(200%);
        opacity: 0.6;
        mix-blend-mode: overlay;
        animation: rotateAndShift 6s ease-in-out infinite;
    }
    /* 深色模式增强颗粒对比度 */
    body::after {
        opacity: 0.12;
        mix-blend-mode: soft-light;
    }
}

/* 移动端优化 */
@media (max-width: 768px) {
    body::before {
        filter: contrast(200%) brightness(120%);
        opacity: 0.6;
        animation: rotateAndShift 10s ease-in-out infinite;
    }
}

✅️延迟版颗粒质感霓虹渐变背景

/* ==========================================
   颗粒质感霓虹延迟渐变背景
   ========================================== */

/* 背景伪元素容器 */
body::before,
body::after {
    content: '';
    position: fixed;
    z-index: -1;
    pointer-events: none;
    opacity: 0;
}

/* 主渐变层:霓虹色彩混合 */
body::before {
    top: -50%;
    left: -50%;
    width: 220%;
    height: 220%;
    background: 
        radial-gradient(ellipse at center, #00ff88 0%, transparent 60%),
        radial-gradient(ellipse at 50% 40%, #ff0044 0%, transparent 40%);
    background-blend-mode: screen;
    filter: contrast(300%) brightness(150%);
    animation: 
        fadeInBackground 1.2s ease-out 0.2s forwards,
        rotateAndShift 8s ease-in-out 1.4s infinite;
}

/* 噪点纹理层:增加颗粒质感 */
body::after {
    inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
    mix-blend-mode: overlay;
    animation: fadeInNoise 1.2s ease-out 0.2s forwards;
}

/* 渐显动画 */
@keyframes fadeInBackground {
    to { opacity: 0.35; }
}

@keyframes fadeInNoise {
    to { opacity: 1; }
}

/* 动态旋转位移动画 */
@keyframes rotateAndShift {
    0%, 100% {
        transform: translate(0, 0) rotate(0deg);
        filter: contrast(300%) brightness(150%) hue-rotate(0deg);
    }
    25% {
        transform: translate(5%, -5%) rotate(5deg);
        filter: contrast(320%) brightness(160%) hue-rotate(15deg);
    }
    50% {
        transform: translate(-5%, 5%) rotate(-5deg);
        filter: contrast(340%) brightness(170%) hue-rotate(30deg);
    }
    75% {
        transform: translate(3%, 3%) rotate(3deg);
        filter: contrast(320%) brightness(160%) hue-rotate(15deg);
    }
}

/* 深色模式增强效果 */
@media (prefers-color-scheme: dark) {
    body::before {
        background: 
            radial-gradient(ellipse at center, #00ff88 0%, transparent 80%),
            radial-gradient(ellipse at 20% 80%, #ff0055 0%, transparent 60%);
        filter: contrast(400%) brightness(200%);
        mix-blend-mode: overlay;
        animation: 
            fadeInBackgroundDark 1.2s ease-out 0.2s forwards,
            rotateAndShift 6s ease-in-out 1.4s infinite;
    }
    
    body::after {
        mix-blend-mode: soft-light;
        animation: fadeInNoiseDark 1.2s ease-out 0.2s forwards;
    }
    
    @keyframes fadeInBackgroundDark {
        to { opacity: 0.6; }
    }
    
    @keyframes fadeInNoiseDark {
        to { opacity: 0.12; }
    }
}

/* 移动端性能优化适配 */
@media (max-width: 768px) {
    body::before {
        filter: contrast(200%) brightness(120%);
        animation: 
            fadeInBackgroundMobile 1.2s ease-out 0.2s forwards,
            rotateAndShift 10s ease-in-out 1.4s infinite;
    }
    
    @keyframes fadeInBackgroundMobile {
        to { opacity: 0.6; }
    }
}

动态背景 Fragment Shader(片元着色器)版 2026年1月21日

✅️Html 代码 - 添加至 <body> 后

    <!-- 动态背景绘制容器元素 -->
    <canvas id="gl-canvas" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; opacity: 0.4; z-index: -1;"></canvas>

JavaScript 代码 - 添加至 </body> 前

    <!-- 动态背景 JS 脚本 -->
    <script>
        // --- 颜色调色板 ---
        const PALETTE = ['#86DFE9', '#A4EFF4', '#FDFFF0', '#D6F2C7'];

        // --- 顶点着色器 ---
        const VS_SOURCE = `
        attribute vec2 position;
        void main() {
            gl_Position = vec4(position, 0.0, 1.0);
        }
    `;

        // --- 片元着色器 ---
        const FS_SOURCE = `
        #ifdef GL_ES
        precision mediump float;
        #endif

        uniform float u_time;
        uniform vec2 u_resolution;
        uniform vec3 u_color_0;
        uniform vec3 u_color_1;
        uniform vec3 u_color_2;
        uniform vec3 u_color_3;
        uniform float u_rand_1;
        uniform float u_rand_2;

        #define S(a,b,t) smoothstep(a,b,t)

        mat2 Rot(float a) {
            float s = sin(a);
            float c = cos(a);
            return mat2(c, -s, s, c);
        }

        // 噪点生成函数
        vec2 hash( vec2 p ) {
            p = vec2( dot(p,vec2(2127.1,81.17)), dot(p,vec2(1269.5,283.37)) );
            return fract(sin(p)*43758.5453);
        }

        float noise( in vec2 p ) {
            vec2 i = floor( p );
            vec2 f = fract( p );
            vec2 u = f*f*(3.0-2.0*f);
            return mix( mix( dot( -1.0+2.0*hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), 
                                dot( -1.0+2.0*hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
                            mix( dot( -1.0+2.0*hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), 
                                dot( -1.0+2.0*hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
        }

        void main() {
            vec2 uv = gl_FragCoord.xy/u_resolution.xy;
            vec2 tuv = uv;
            
            // 缩放控制 - 数值越小纹理越大
            tuv *= 1.3;  // 原值 2.2
            tuv -= .5;

            // 动态扭曲与旋转
            float degree = noise(vec2(u_time * 0.1, tuv.x*tuv.y));
            tuv *= Rot( radians( ( degree - 0.5 ) * 540. + 180. ));

            // 波浪扭曲
            float frequency = 3.; 
            float amplitude = 100.;
            float speed = 2.0;
            tuv.x += sin( tuv.y * frequency + speed ) / amplitude;
            tuv.y += sin( tuv.x * frequency * 1.2 + speed ) / ( amplitude * .5 );

            // 颜色层混合
            vec3 layer1 = mix( u_color_0, u_color_1, S( -0.6, .6, ( tuv * Rot( radians( u_rand_1 ))).x));
            vec3 layer2 = mix( u_color_2, u_color_3, S( -0.6, .6, ( tuv * Rot( radians( u_rand_2 ))).x));
            float verticalMix = S( 0.6, -0.1, tuv.y + noise(tuv * 0.5) * 0.3); 
            
            vec3 finalComp = mix(layer1, layer2, verticalMix);

            // --- 胶片颗粒感 ---
            float grain = fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453);
            float grainStrength = 0.12; // 改变颗粒强弱 - 0.01细腻>0.2粗糙
            finalComp += (grain - 0.5) * grainStrength;

            gl_FragColor = vec4( finalComp, 1.0 );
        }
    `;

        // --- WebGL 初始化 ---
        function createShader(gl, type, source) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                console.error('Shader compile error:', gl.getShaderInfoLog(shader));
                gl.deleteShader(shader);
                return null;
            }
            return shader;
        }

        function createProgram(gl, vsSource, fsSource) {
            const vs = createShader(gl, gl.VERTEX_SHADER, vsSource);
            const fs = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
            if (!vs || !fs) return null;
            const program = gl.createProgram();
            gl.attachShader(program, vs);
            gl.attachShader(program, fs);
            gl.linkProgram(program);
            if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
                console.error('Program link error:', gl.getProgramInfoLog(program));
                return null;
            }
            return program;
        }

        function hexToRgb(hex) {
            const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
            return result ? [
                parseInt(result[1], 16) / 255,
                parseInt(result[2], 16) / 255,
                parseInt(result[3], 16) / 255
            ] : [0, 0, 0];
        }

        const canvas = document.getElementById('gl-canvas');
        const gl = canvas.getContext('webgl', {
            alpha: false
        });

        if (!gl) {
            console.warn('WebGL not supported');
        }

        const program = createProgram(gl, VS_SOURCE, FS_SOURCE);
        gl.useProgram(program);

        // 定义覆盖全屏的矩形
        const positions = new Float32Array([
            -1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
            -1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
        ]);
        const positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

        const positionLocation = gl.getAttribLocation(program, 'position');
        gl.enableVertexAttribArray(positionLocation);
        gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

        // 获取变量地址
        const uTimeLoc = gl.getUniformLocation(program, 'u_time');
        const uResLoc = gl.getUniformLocation(program, 'u_resolution');
        const uRand1Loc = gl.getUniformLocation(program, 'u_rand_1');
        const uRand2Loc = gl.getUniformLocation(program, 'u_rand_2');
        const colorLocs = [
            gl.getUniformLocation(program, 'u_color_0'),
            gl.getUniformLocation(program, 'u_color_1'),
            gl.getUniformLocation(program, 'u_color_2'),
            gl.getUniformLocation(program, 'u_color_3'),
        ];

        // 传入颜色
        function setColors(palette) {
            palette.forEach((hex, index) => {
                if (colorLocs[index]) {
                    gl.uniform3fv(colorLocs[index], hexToRgb(hex));
                }
            });
        }
        setColors(PALETTE);

        // 传入随机旋转角度
        let rand1 = Math.random() * 360;
        let rand2 = Math.random() * 360;
        gl.uniform1f(uRand1Loc, rand1);
        gl.uniform1f(uRand2Loc, rand2);

        // 窗口大小调整与性能优化 (限制 DPR)
        function resize() {
            const displayWidth = window.innerWidth;
            const displayHeight = window.innerHeight;
            // 限制最大像素比为 1.5 以优化性能
            const dpr = Math.min(window.devicePixelRatio || 1, 1.5);

            canvas.width = displayWidth * dpr;
            canvas.height = displayHeight * dpr;
            gl.viewport(0, 0, canvas.width, canvas.height);
            gl.uniform2f(uResLoc, canvas.width, canvas.height);
        }
        window.addEventListener('resize', resize);
        resize();

        let startTime = performance.now();

        function render(time) {
            const currentTime = (time - startTime) * 0.001;
            gl.uniform1f(uTimeLoc, currentTime);
            gl.drawArrays(gl.TRIANGLES, 0, 6);
            requestAnimationFrame(render);
        }
        requestAnimationFrame(render);
    </script>

✅️JavaScript 代码 - 优化强制的重排和淡入效果 - 添加至 </body> 前

    <!-- 动态背景 JS 脚本 -->
    <script>
        (function() {
            'use strict';

            // --- 配置参数 ---
            const CONFIG = {
                PALETTE: ['#86DFE9', '#A4EFF4', '#FDFFF0', '#D6F2C7'],
                INIT_DELAY: 100, // 延迟初始化时间,避免阻塞首屏
                FADE_IN_DURATION: 1200 // 淡入动画时长
            };

            // --- 顶点着色器 ---
            const VS_SOURCE = `
        attribute vec2 position;
        void main() {
            gl_Position = vec4(position, 0.0, 1.0);
        }
    `;

            // --- 片元着色器 ---
            const FS_SOURCE = `
        #ifdef GL_ES
        precision mediump float;
        #endif

        uniform float u_time;
        uniform vec2 u_resolution;
        uniform vec3 u_color_0;
        uniform vec3 u_color_1;
        uniform vec3 u_color_2;
        uniform vec3 u_color_3;
        uniform float u_rand_1;
        uniform float u_rand_2;

        #define S(a,b,t) smoothstep(a,b,t)

        mat2 Rot(float a) {
            float s = sin(a);
            float c = cos(a);
            return mat2(c, -s, s, c);
        }

        // 噪点生成函数
        vec2 hash( vec2 p ) {
            p = vec2( dot(p,vec2(2127.1,81.17)), dot(p,vec2(1269.5,283.37)) );
            return fract(sin(p)*43758.5453);
        }

        float noise( in vec2 p ) {
            vec2 i = floor( p );
            vec2 f = fract( p );
            vec2 u = f*f*(3.0-2.0*f);
            return mix( mix( dot( -1.0+2.0*hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), 
                                dot( -1.0+2.0*hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
                            mix( dot( -1.0+2.0*hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), 
                                dot( -1.0+2.0*hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
        }

        void main() {
            vec2 uv = gl_FragCoord.xy/u_resolution.xy;
            vec2 tuv = uv;
			// 缩放控制 - 数值越小纹理越模糊
            tuv *= 1.3; // 原值 2.2
            tuv -= .5;

            float degree = noise(vec2(u_time * 0.1, tuv.x*tuv.y));
            tuv *= Rot( radians( ( degree - 0.5 ) * 540. + 180. ));

            float frequency = 3.; 
            float amplitude = 100.;
            float speed = 2.0;
            tuv.x += sin( tuv.y * frequency + speed ) / amplitude;
            tuv.y += sin( tuv.x * frequency * 1.2 + speed ) / ( amplitude * .5 );

            vec3 layer1 = mix( u_color_0, u_color_1, S( -0.6, .6, ( tuv * Rot( radians( u_rand_1 ))).x));
            vec3 layer2 = mix( u_color_2, u_color_3, S( -0.6, .6, ( tuv * Rot( radians( u_rand_2 ))).x));
            float verticalMix = S( 0.6, -0.1, tuv.y + noise(tuv * 0.5) * 0.3); 
            
            vec3 finalComp = mix(layer1, layer2, verticalMix);

            // --- 胶片颗粒感 ---
            float grain = fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453);
            float grainStrength = 0.12; // 改变颗粒强弱 - 0.01细腻>0.2粗糙
            finalComp += (grain - 0.5) * grainStrength;

            gl_FragColor = vec4( finalComp, 1.0 ); // 片元始终不透明 透明度由 canvas CSS opacity 控制
        }
    `;

            // --- WebGL 初始化 ---
            function createShader(gl, type, source) {
                const shader = gl.createShader(type);
                gl.shaderSource(shader, source);
                gl.compileShader(shader);
                if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                    console.error('Shader compile error:', gl.getShaderInfoLog(shader));
                    gl.deleteShader(shader);
                    return null;
                }
                return shader;
            }

            function createProgram(gl, vsSource, fsSource) {
                const vs = createShader(gl, gl.VERTEX_SHADER, vsSource);
                const fs = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
                if (!vs || !fs) return null;
                const program = gl.createProgram();
                gl.attachShader(program, vs);
                gl.attachShader(program, fs);
                gl.linkProgram(program);
                if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
                    console.error('Program link error:', gl.getProgramInfoLog(program));
                    return null;
                }
                return program;
            }

            function hexToRgb(hex) {
                const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
                return result ? [
                    parseInt(result[1], 16) / 255,
                    parseInt(result[2], 16) / 255,
                    parseInt(result[3], 16) / 255
                ] : [0, 0, 0];
            }

            // --- 背景初始化逻辑 ---
            function initBackground() {
                const canvas = document.getElementById('gl-canvas');
                if (!canvas) {
                    console.warn('Canvas element #gl-canvas not found.');
                    return;
                }

                // 读取 HTML 中设置的最终透明度
                const targetOpacity = window.getComputedStyle(canvas).opacity;

                // 将初始状态隐藏
                canvas.style.opacity = '0';

                try {
                    const gl = canvas.getContext('webgl', {
                        alpha: true, // 启用透明通道 支持 CSS 背景透视
                        antialias: false
                    });

                    if (!gl) {
                        console.warn('WebGL not supported');
                        canvas.style.opacity = targetOpacity;
                        return;
                    }

                    const program = createProgram(gl, VS_SOURCE, FS_SOURCE);
                    if (!program) {
                        console.error('Failed to create shader program');
                        canvas.style.opacity = targetOpacity;
                        return;
                    }

                    gl.useProgram(program);

                    // 定义覆盖全屏的矩形
                    const positions = new Float32Array([
                        -1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
                        -1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
                    ]);
                    const positionBuffer = gl.createBuffer();
                    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
                    gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

                    const positionLocation = gl.getAttribLocation(program, 'position');
                    gl.enableVertexAttribArray(positionLocation);
                    gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

                    // 获取变量地址
                    const uTimeLoc = gl.getUniformLocation(program, 'u_time');
                    const uResLoc = gl.getUniformLocation(program, 'u_resolution');
                    const uRand1Loc = gl.getUniformLocation(program, 'u_rand_1');
                    const uRand2Loc = gl.getUniformLocation(program, 'u_rand_2');
                    const colorLocs = [
                        gl.getUniformLocation(program, 'u_color_0'),
                        gl.getUniformLocation(program, 'u_color_1'),
                        gl.getUniformLocation(program, 'u_color_2'),
                        gl.getUniformLocation(program, 'u_color_3'),
                    ];

                    // 传入颜色
                    function setColors(palette) {
                        palette.forEach((hex, index) => {
                            if (colorLocs[index]) {
                                gl.uniform3fv(colorLocs[index], hexToRgb(hex));
                            }
                        });
                    }
                    setColors(CONFIG.PALETTE);

                    // 传入随机旋转角度
                    let rand1 = Math.random() * 360;
                    let rand2 = Math.random() * 360;
                    gl.uniform1f(uRand1Loc, rand1);
                    gl.uniform1f(uRand2Loc, rand2);

                    // 窗口大小调整与性能优化 限制 DPR 1.5
                    let width, height;

                    function resize() {
                        const displayWidth = window.innerWidth;
                        const displayHeight = window.innerHeight;
                        const dpr = Math.min(window.devicePixelRatio || 1, 1.5);

                        width = displayWidth * dpr;
                        height = displayHeight * dpr;

                        if (canvas.width !== width || canvas.height !== height) {
                            canvas.width = width;
                            canvas.height = height;
                            gl.viewport(0, 0, width, height);
                            gl.uniform2f(uResLoc, width, height);
                        }
                    }
                    window.addEventListener('resize', resize);
                    resize();

                    let startTime = performance.now();

                    function render(time) {
                        const currentTime = (time - startTime) * 0.001;
                        gl.uniform1f(uTimeLoc, currentTime);
                        gl.drawArrays(gl.TRIANGLES, 0, 6);
                        requestAnimationFrame(render);
                    }
                    requestAnimationFrame(render);

                    // --- 触发淡入效果 ---
                    requestAnimationFrame(() => {
                        canvas.style.transition = `opacity ${CONFIG.FADE_IN_DURATION}ms ease-in-out`;
                        // 设置为 HTML 中定义的透明度 0.4
                        canvas.style.opacity = targetOpacity;
                    });

                } catch (error) {
                    console.error('WebGL 初始化发生错误:', error);
                    canvas.style.opacity = targetOpacity; // 出错时也要恢复可见性
                }
            }

            // --- 启动初始化流程 ---
            function start() {
                // 延迟初始化,避免阻塞关键渲染路径
                setTimeout(() => {
                    initBackground();
                }, CONFIG.INIT_DELAY);
            }

            // 在 DOM 加载完成后启动
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', start);
            } else {
                start();
            }

        })();
    </script>

✅️将动态背景脚本添加至公用 script.js 文件中

第一步:添加配置和着色器代码,在文件顶部 “// assets/script.js” 注释下方添加。

// =============================
// 动态 WebGL 背景模块
// =============================
const WebGLBackground = (() => {
    'use strict';

    // --- 配置参数 ---
    const CONFIG = {
        PALETTE: ['#86DFE9', '#A4EFF4', '#FDFFF0', '#D6F2C7'],
        INIT_DELAY: 100,
        FADE_IN_DURATION: 1200
    };

    // --- 顶点着色器 ---
    const VS_SOURCE = `
        attribute vec2 position;
        void main() {
            gl_Position = vec4(position, 0.0, 1.0);
        }
    `;

    // --- 片元着色器 ---
    const FS_SOURCE = `
        #ifdef GL_ES
        precision mediump float;
        #endif
        uniform float u_time;
        uniform vec2 u_resolution;
        uniform vec3 u_color_0;
        uniform vec3 u_color_1;
        uniform vec3 u_color_2;
        uniform vec3 u_color_3;
        uniform float u_rand_1;
        uniform float u_rand_2;
        #define S(a,b,t) smoothstep(a,b,t)
        mat2 Rot(float a) {
            float s = sin(a);
            float c = cos(a);
            return mat2(c, -s, s, c);
        }
        vec2 hash( vec2 p ) {
            p = vec2( dot(p,vec2(2127.1,81.17)), dot(p,vec2(1269.5,283.37)) );
            return fract(sin(p)*43758.5453);
        }
        float noise( in vec2 p ) {
            vec2 i = floor( p );
            vec2 f = fract( p );
            vec2 u = f*f*(3.0-2.0*f);
            return mix( mix( dot( -1.0+2.0*hash( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), 
                                dot( -1.0+2.0*hash( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
                            mix( dot( -1.0+2.0*hash( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), 
                                dot( -1.0+2.0*hash( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
        }
        void main() {
            vec2 uv = gl_FragCoord.xy/u_resolution.xy;
            vec2 tuv = uv;
            tuv *= 1.3;
            tuv -= .5;
            float degree = noise(vec2(u_time * 0.1, tuv.x*tuv.y));
            tuv *= Rot( radians( ( degree - 0.5 ) * 540. + 180. ));
            float frequency = 3.; 
            float amplitude = 100.;
            float speed = 2.0;
            tuv.x += sin( tuv.y * frequency + speed ) / amplitude;
            tuv.y += sin( tuv.x * frequency * 1.2 + speed ) / ( amplitude * .5 );
            vec3 layer1 = mix( u_color_0, u_color_1, S( -0.6, .6, ( tuv * Rot( radians( u_rand_1 ))).x));
            vec3 layer2 = mix( u_color_2, u_color_3, S( -0.6, .6, ( tuv * Rot( radians( u_rand_2 ))).x));
            float verticalMix = S( 0.6, -0.1, tuv.y + noise(tuv * 0.5) * 0.3); 
            vec3 finalComp = mix(layer1, layer2, verticalMix);
            float grain = fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453);
            float grainStrength = 0.12;
            finalComp += (grain - 0.5) * grainStrength;
            gl_FragColor = vec4( finalComp, 1.0 );
        }
    `;

    // --- WebGL 初始化工具函数 ---
    function createShader(gl, type, source) {
        const shader = gl.createShader(type);
        gl.shaderSource(shader, source);
        gl.compileShader(shader);
        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            console.error('Shader compile error:', gl.getShaderInfoLog(shader));
            gl.deleteShader(shader);
            return null;
        }
        return shader;
    }

    function createProgram(gl, vsSource, fsSource) {
        const vs = createShader(gl, gl.VERTEX_SHADER, vsSource);
        const fs = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
        if (!vs || !fs) return null;
        const program = gl.createProgram();
        gl.attachShader(program, vs);
        gl.attachShader(program, fs);
        gl.linkProgram(program);
        if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
            console.error('Program link error:', gl.getProgramInfoLog(program));
            return null;
        }
        return program;
    }

    function hexToRgb(hex) {
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? [
            parseInt(result[1], 16) / 255,
            parseInt(result[2], 16) / 255,
            parseInt(result[3], 16) / 255
        ] : [0, 0, 0];
    }

    // --- 核心背景逻辑 ---
    function initBackground() {
        const canvas = document.getElementById('gl-canvas');
        if (!canvas) {
            console.warn('Canvas element #gl-canvas not found.');
            return;
        }

        const targetOpacity = window.getComputedStyle(canvas).opacity;
        canvas.style.opacity = '0';

        try {
            const gl = canvas.getContext('webgl', {
                alpha: true,
                antialias: false
            });

            if (!gl) {
                console.warn('WebGL not supported');
                canvas.style.opacity = targetOpacity;
                return;
            }

            const program = createProgram(gl, VS_SOURCE, FS_SOURCE);
            if (!program) {
                console.error('Failed to create shader program');
                canvas.style.opacity = targetOpacity;
                return;
            }

            gl.useProgram(program);

            const positions = new Float32Array([
                -1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
                -1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
            ]);
            const positionBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

            const positionLocation = gl.getAttribLocation(program, 'position');
            gl.enableVertexAttribArray(positionLocation);
            gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

            const uTimeLoc = gl.getUniformLocation(program, 'u_time');
            const uResLoc = gl.getUniformLocation(program, 'u_resolution');
            const uRand1Loc = gl.getUniformLocation(program, 'u_rand_1');
            const uRand2Loc = gl.getUniformLocation(program, 'u_rand_2');
            const colorLocs = [
                gl.getUniformLocation(program, 'u_color_0'),
                gl.getUniformLocation(program, 'u_color_1'),
                gl.getUniformLocation(program, 'u_color_2'),
                gl.getUniformLocation(program, 'u_color_3'),
            ];

            function setColors(palette) {
                palette.forEach((hex, index) => {
                    if (colorLocs[index]) {
                        gl.uniform3fv(colorLocs[index], hexToRgb(hex));
                    }
                });
            }
            setColors(CONFIG.PALETTE);

            let rand1 = Math.random() * 360;
            let rand2 = Math.random() * 360;
            gl.uniform1f(uRand1Loc, rand1);
            gl.uniform1f(uRand2Loc, rand2);

            let width, height;
            function resize() {
                const displayWidth = window.innerWidth;
                const displayHeight = window.innerHeight;
                const dpr = Math.min(window.devicePixelRatio || 1, 1.5);
                width = displayWidth * dpr;
                height = displayHeight * dpr;
                if (canvas.width !== width || canvas.height !== height) {
                    canvas.width = width;
                    canvas.height = height;
                    gl.viewport(0, 0, width, height);
                    gl.uniform2f(uResLoc, width, height);
                }
            }
            window.addEventListener('resize', resize);
            resize();

            let startTime = performance.now();

            function render(time) {
                const currentTime = (time - startTime) * 0.001;
                gl.uniform1f(uTimeLoc, currentTime);
                gl.drawArrays(gl.TRIANGLES, 0, 6);
                requestAnimationFrame(render);
            }
            requestAnimationFrame(render);

            requestAnimationFrame(() => {
                canvas.style.transition = `opacity ${CONFIG.FADE_IN_DURATION}ms ease-in-out`;
                canvas.style.opacity = targetOpacity;
            });

        } catch (error) {
            console.error('WebGL 初始化发生错误:', error);
            canvas.style.opacity = targetOpacity;
        }
    }

    // 暴露启动方法
    return {
        start: () => {
            setTimeout(() => {
                initBackground();
            }, CONFIG.INIT_DELAY);
        }
    };
})();

第二步:在 DOMContentLoaded 中调用,找到 script.js 文件中的document.addEventListener("DOMContentLoaded", function ()代码块,在函数内部initReplyForm();下一行添加 WebGLBackground.start();

WebGLBackground.start();