web-cloud-designer

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Web Cloud Designer

网页云效果设计专家

Expert in creating realistic, performant cloud effects for web applications using SVG filters, CSS animations, and layering techniques. Specializes in atmospheric visuals that enhance user experience without sacrificing performance.
擅长使用SVG滤镜、CSS动画和分层技术为Web应用创建逼真且高性能的云效果。专注于打造氛围感视觉效果,在不牺牲性能的前提下提升用户体验。

When to Use This Skill

何时使用该技能

Use for:
  • Realistic cloud backgrounds and skyboxes
  • Weather-themed UI elements and transitions
  • Parallax cloud scenes with depth
  • Animated atmospheric effects
  • Stylized/cartoon cloud designs
  • Hero section backgrounds with sky themes
  • Loading states with cloud animations
  • Game-style cloud layers
Do NOT use for:
  • 3D volumetric cloud rendering -> use WebGL/Three.js
  • Photo manipulation of real clouds -> use image editing
  • Weather data integration -> use weather API skills
  • Simple gradient skies without cloud shapes
  • Video backgrounds with clouds
适用场景:
  • 逼真的云背景和天空盒
  • 天气主题UI元素与过渡效果
  • 具有深度感的视差云场景
  • 动态氛围感效果
  • 风格化/卡通风格云设计
  • 天空主题的Hero区域背景
  • 带云动画的加载状态
  • 游戏风格云层
不适用场景:
  • 3D体积云渲染 -> 使用 WebGL/Three.js
  • 真实云照片处理 -> 使用图像编辑工具
  • 天气数据集成 -> 使用天气API相关技能
  • 无云形状的简单渐变天空
  • 带云的视频背景

Core Techniques Reference

核心技术参考

SVG Filter Pipeline

SVG滤镜流水线

The fundamental cloud effect uses this filter chain:
Source -> feTurbulence -> feDisplacementMap -> feGaussianBlur -> feDiffuseLighting -> Composite
基础云效果使用以下滤镜链:
Source -> feTurbulence -> feDisplacementMap -> feGaussianBlur -> feDiffuseLighting -> Composite

1. feTurbulence - The Foundation

1. feTurbulence - 基础模块

Generates Perlin noise that forms cloud shapes.
xml
<feTurbulence
  type="fractalNoise"      <!-- fractalNoise for clouds (NOT turbulence) -->
  baseFrequency="0.01"     <!-- 0.005-0.02: lower = larger, rounder shapes -->
  numOctaves="4"           <!-- 3-5: detail level, &gt;5 diminishing returns -->
  seed="42"                <!-- Change for shape variation (free!) -->
  result="noise"
/>
ParameterRangeEffect
baseFrequency
0.005-0.02Scale of cloud shapes. 0.005 = giant cumulus, 0.02 = small wisps
numOctaves
3-5Detail layers. 3 = smooth, 5 = detailed. Above 5 = CPU waste
seed
0-999999Shape variation. Change this, NOT baseFrequency for variety
type
fractalNoiseALWAYS use fractalNoise for clouds (turbulence = fire/water)
生成构成云形状的Perlin噪声。
xml
<feTurbulence
  type="fractalNoise"      <!-- 用于云效果的fractalNoise(不要用turbulence) -->
  baseFrequency="0.01"     <!-- 0.005-0.02:数值越小,云形状越大、越圆润 -->
  numOctaves="4"           <!-- 3-5:细节层级,大于5时收益递减 -->
  seed="42"                <!-- 修改该值可改变云形状(无性能损耗!) -->
  result="noise"
/>
参数范围效果
baseFrequency
0.005-0.02云形状的缩放比例。0.005 = 大型积云,0.02 = 小卷云
numOctaves
3-5细节层数。3 = 平滑,5 = 细节丰富。超过5会造成CPU浪费
seed
0-999999形状变化。如需多样云形,修改该值而非baseFrequency
type
fractalNoise云效果请始终使用fractalNoise(turbulence适用于火/水效果)

2. feDisplacementMap - Shape Distortion

2. feDisplacementMap - 形状扭曲

Creates organic, billowing cloud shapes from the noise.
xml
<feDisplacementMap
  in="SourceGraphic"
  in2="noise"
  scale="80"               <!-- 20-170: distortion intensity -->
  xChannelSelector="R"
  yChannelSelector="G"
/>
Scale ValueEffect
20-50Subtle, wispy cirrus
50-100Balanced cumulus
100-170Dramatic, billowing storm clouds
将噪声转换为自然、蓬松的云形状。
xml
<feDisplacementMap
  in="SourceGraphic"
  in2="noise"
  scale="80"               <!-- 20-170:扭曲强度 -->
  xChannelSelector="R"
  yChannelSelector="G"
/>
Scale值效果
20-50柔和、纤细的卷云
50-100均衡的积云
100-170夸张、蓬松的风暴云

3. feGaussianBlur - Edge Softening

3. feGaussianBlur - 边缘柔化

CRITICAL: Apply BEFORE displacement for performance (per CSS-Tricks).
xml
<feGaussianBlur
  stdDeviation="3"         <!-- 2-8 for cloud softness -->
  result="blurred"
/>
关键: 先应用模糊再进行位移可提升性能(来自CSS-Tricks)。
xml
<feGaussianBlur
  stdDeviation="3"         <!-- 2-8:云的柔化程度 -->
  result="blurred"
/>

4. feDiffuseLighting - Volumetric Depth

4. feDiffuseLighting - 体积感深度

Adds 3D-like shading to flat noise.
xml
<feDiffuseLighting
  in="noise"
  lighting-color="white"
  surfaceScale="2"
  result="light"
>
  <feDistantLight
    azimuth="45"           <!-- Sun angle: 0-360 -->
    elevation="55"         <!-- Sun height: 0-90 -->
  />
</feDiffuseLighting>
为平面噪声添加类3D阴影效果。
xml
<feDiffuseLighting
  in="noise"
  lighting-color="white"
  surfaceScale="2"
  result="light"
>
  <feDistantLight
    azimuth="45"           <!-- 太阳角度:0-360 -->
    elevation="55"         <!-- 太阳高度:0-90 -->
  />
</feDiffuseLighting>

Cloud Type Recipes

云类型实现方案

Cumulus (Puffy, Happy Clouds)

积云(蓬松、活泼的云)

svg
<svg width="100%" height="100%">
  <defs>
    <filter id="cumulus" x="-50%" y="-50%" width="200%" height="200%">
      <feTurbulence type="fractalNoise" baseFrequency="0.008"
                    numOctaves="4" seed="5" result="noise"/>
      <feGaussianBlur in="noise" stdDeviation="4" result="blur"/>
      <feDisplacementMap in="SourceGraphic" in2="blur" scale="60"/>
    </filter>
  </defs>
  <ellipse cx="200" cy="100" rx="150" ry="80"
           fill="white" filter="url(#cumulus)"/>
</svg>
svg
<svg width="100%" height="100%">
  <defs>
    <filter id="cumulus" x="-50%" y="-50%" width="200%" height="200%">
      <feTurbulence type="fractalNoise" baseFrequency="0.008"
                    numOctaves="4" seed="5" result="noise"/>
      <feGaussianBlur in="noise" stdDeviation="4" result="blur"/>
      <feDisplacementMap in="SourceGraphic" in2="blur" scale="60"/>
    </filter>
  </defs>
  <ellipse cx="200" cy="100" rx="150" ry="80"
           fill="white" filter="url(#cumulus)"/>
</svg>

Cirrus (Wispy, High Altitude)

卷云(纤细、高空云)

svg
<filter id="cirrus">
  <feTurbulence type="fractalNoise" baseFrequency="0.02 0.005"
                numOctaves="3" seed="12" result="noise"/>
  <feGaussianBlur in="noise" stdDeviation="2" result="blur"/>
  <feDisplacementMap in="SourceGraphic" in2="blur" scale="25"/>
</filter>
Key: Use anisotropic
baseFrequency
(two values) for stretched, directional wisps.
svg
<filter id="cirrus">
  <feTurbulence type="fractalNoise" baseFrequency="0.02 0.005"
                numOctaves="3" seed="12" result="noise"/>
  <feGaussianBlur in="noise" stdDeviation="2" result="blur"/>
  <feDisplacementMap in="SourceGraphic" in2="blur" scale="25"/>
</filter>
关键:使用各向异性的
baseFrequency
(两个值)创建拉伸的定向卷云。

Stratus (Flat Layers)

层云(扁平云层)

svg
<filter id="stratus">
  <feTurbulence type="fractalNoise" baseFrequency="0.015 0.003"
                numOctaves="3" seed="8" result="noise"/>
  <feGaussianBlur stdDeviation="6" result="blur"/>
  <feDisplacementMap in="SourceGraphic" in2="blur" scale="30"/>
</filter>
svg
<filter id="stratus">
  <feTurbulence type="fractalNoise" baseFrequency="0.015 0.003"
                numOctaves="3" seed="8" result="noise"/>
  <feGaussianBlur stdDeviation="6" result="blur"/>
  <feDisplacementMap in="SourceGraphic" in2="blur" scale="30"/>
</filter>

Cumulonimbus (Storm Clouds)

积雨云(风暴云)

svg
<filter id="storm">
  <feTurbulence type="fractalNoise" baseFrequency="0.006"
                numOctaves="5" seed="99" result="noise"/>
  <feGaussianBlur in="noise" stdDeviation="3" result="blur"/>
  <feDisplacementMap in="SourceGraphic" in2="blur" scale="150"/>
  <feDiffuseLighting in="blur" lighting-color="#8899aa" surfaceScale="3">
    <feDistantLight azimuth="230" elevation="25"/>
  </feDiffuseLighting>
</filter>
svg
<filter id="storm">
  <feTurbulence type="fractalNoise" baseFrequency="0.006"
                numOctaves="5" seed="99" result="noise"/>
  <feGaussianBlur in="noise" stdDeviation="3" result="blur"/>
  <feDisplacementMap in="SourceGraphic" in2="blur" scale="150"/>
  <feDiffuseLighting in="blur" lighting-color="#8899aa" surfaceScale="3">
    <feDistantLight azimuth="230" elevation="25"/>
  </feDiffuseLighting>
</filter>

Stylized/Cartoon Clouds

风格化/卡通云

svg
<filter id="cartoon">
  <feTurbulence type="fractalNoise" baseFrequency="0.012"
                numOctaves="2" seed="3" result="noise"/>
  <feDisplacementMap in="SourceGraphic" in2="noise" scale="40"/>
  <!-- No blur = sharper edges for cartoon look -->
</filter>
svg
<filter id="cartoon">
  <feTurbulence type="fractalNoise" baseFrequency="0.012"
                numOctaves="2" seed="3" result="noise"/>
  <feDisplacementMap in="SourceGraphic" in2="noise" scale="40"/>
  <!-- 不添加模糊 = 卡通风格的锐利边缘 -->
</filter>

Layering Strategy

分层策略

Create depth with multiple cloud layers:
html
<div class="sky">
  <div class="clouds clouds-back"></div>
  <div class="clouds clouds-mid"></div>
  <div class="clouds clouds-front"></div>
</div>
css
.clouds-back {
  filter: url(#cloud-soft);
  opacity: 0.3;
  animation: drift 120s linear infinite;
  transform: scale(1.5);
}

.clouds-mid {
  filter: url(#cloud-medium);
  opacity: 0.6;
  animation: drift 80s linear infinite;
  transform: scale(1);
}

.clouds-front {
  filter: url(#cloud-sharp);
  opacity: 0.9;
  animation: drift 50s linear infinite;
  transform: scale(0.8);
}
通过多层云创建深度感:
html
<div class="sky">
  <div class="clouds clouds-back"></div>
  <div class="clouds clouds-mid"></div>
  <div class="clouds clouds-front"></div>
</div>
css
.clouds-back {
  filter: url(#cloud-soft);
  opacity: 0.3;
  animation: drift 120s linear infinite;
  transform: scale(1.5);
}

.clouds-mid {
  filter: url(#cloud-medium);
  opacity: 0.6;
  animation: drift 80s linear infinite;
  transform: scale(1);
}

.clouds-front {
  filter: url(#cloud-sharp);
  opacity: 0.9;
  animation: drift 50s linear infinite;
  transform: scale(0.8);
}

Layer Parameter Guide

分层参数指南

LayerOpacitySpeedScaleblur stdDeviation
Back (distant)0.2-0.490-120s1.3-1.5x5-8
Mid0.5-0.750-80s1.0x3-5
Front (close)0.8-1.030-50s0.7-0.9x1-3
层级透明度速度缩放比例模糊stdDeviation
背景层(远处)0.2-0.490-120s1.3-1.5x5-8
中间层0.5-0.750-80s1.0x3-5
前景层(近处)0.8-1.030-50s0.7-0.9x1-3

Animation Techniques

动画技术

CSS Keyframes (Recommended - Best Performance)

CSS关键帧(推荐 - 性能最佳)

css
@keyframes drift {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}

@keyframes morph {
  0%, 100% { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
  50% { border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%; }
}

.cloud {
  animation:
    drift 60s linear infinite,
    morph 15s ease-in-out infinite;
}
css
@keyframes drift {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}

@keyframes morph {
  0%, 100% { border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%; }
  50% { border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%; }
}

.cloud {
  animation:
    drift 60s linear infinite,
    morph 15s ease-in-out infinite;
}

SVG Animate (Use Sparingly - CPU Intensive)

SVG动画(谨慎使用 - 占用CPU高)

svg
<feTurbulence baseFrequency="0.01" numOctaves="4">
  <animate
    attributeName="baseFrequency"
    values="0.008;0.012;0.008"
    dur="20s"
    repeatCount="indefinite"
  />
</feTurbulence>
WARNING: Animating filter properties recalculates the entire filter. Use only for hero effects, not background loops.
svg
<feTurbulence baseFrequency="0.01" numOctaves="4">
  <animate
    attributeName="baseFrequency"
    values="0.008;0.012;0.008"
    dur="20s"
    repeatCount="indefinite"
  />
</feTurbulence>
警告: 动画滤镜属性会重新计算整个滤镜。仅用于Hero区域效果,勿用于背景循环。

GSAP (Best Control)

GSAP(控制精度最高)

javascript
gsap.to("#cloud-filter feTurbulence", {
  attr: { baseFrequency: 0.015 },
  duration: 10,
  ease: "sine.inOut",
  yoyo: true,
  repeat: -1
});
javascript
gsap.to("#cloud-filter feTurbulence", {
  attr: { baseFrequency: 0.015 },
  duration: 10,
  ease: "sine.inOut",
  yoyo: true,
  repeat: -1
});

3D Parallax (Billboard Technique)

3D视差(广告牌技术)

css
.cloud-layer {
  transform-style: preserve-3d;
  perspective: 1000px;
}

.cloud {
  transform: translateZ(-100px) scale(1.1);
  /* Further clouds appear smaller, move slower on scroll */
}
css
.cloud-layer {
  transform-style: preserve-3d;
  perspective: 1000px;
}

.cloud {
  transform: translateZ(-100px) scale(1.1);
  /* 远处的云看起来更小,滚动时移动更慢 */
}

Complete Implementation Templates

完整实现模板

Template 1: Simple Sky Background

模板1:简单天空背景

html
<!DOCTYPE html>
<html>
<head>
  <style>
    .sky {
      position: relative;
      width: 100%;
      height: 100vh;
      background: linear-gradient(180deg, #87CEEB 0%, #E0F6FF 100%);
      overflow: hidden;
    }

    .cloud {
      position: absolute;
      background: white;
      border-radius: 50%;
      filter: url(#cloudFilter);
      animation: float linear infinite;
    }

    .cloud-1 { width: 300px; height: 150px; top: 10%; animation-duration: 80s; }
    .cloud-2 { width: 400px; height: 180px; top: 30%; animation-duration: 100s; animation-delay: -30s; }
    .cloud-3 { width: 250px; height: 120px; top: 50%; animation-duration: 70s; animation-delay: -50s; }

    @keyframes float {
      from { transform: translateX(-120%); }
      to { transform: translateX(120vw); }
    }
  </style>
</head>
<body>
  <svg style="position:absolute;width:0;height:0">
    <defs>
      <filter id="cloudFilter" x="-50%" y="-50%" width="200%" height="200%">
        <feTurbulence type="fractalNoise" baseFrequency="0.01" numOctaves="4" seed="5"/>
        <feGaussianBlur stdDeviation="4"/>
        <feDisplacementMap in="SourceGraphic" scale="50"/>
      </filter>
    </defs>
  </svg>

  <div class="sky">
    <div class="cloud cloud-1"></div>
    <div class="cloud cloud-2"></div>
    <div class="cloud cloud-3"></div>
  </div>
</body>
</html>
html
<!DOCTYPE html>
<html>
<head>
  <style>
    .sky {
      position: relative;
      width: 100%;
      height: 100vh;
      background: linear-gradient(180deg, #87CEEB 0%, #E0F6FF 100%);
      overflow: hidden;
    }

    .cloud {
      position: absolute;
      background: white;
      border-radius: 50%;
      filter: url(#cloudFilter);
      animation: float linear infinite;
    }

    .cloud-1 { width: 300px; height: 150px; top: 10%; animation-duration: 80s; }
    .cloud-2 { width: 400px; height: 180px; top: 30%; animation-duration: 100s; animation-delay: -30s; }
    .cloud-3 { width: 250px; height: 120px; top: 50%; animation-duration: 70s; animation-delay: -50s; }

    @keyframes float {
      from { transform: translateX(-120%); }
      to { transform: translateX(120vw); }
    }
  </style>
</head>
<body>
  <svg style="position:absolute;width:0;height:0">
    <defs>
      <filter id="cloudFilter" x="-50%" y="-50%" width="200%" height="200%">
        <feTurbulence type="fractalNoise" baseFrequency="0.01" numOctaves="4" seed="5"/>
        <feGaussianBlur stdDeviation="4"/>
        <feDisplacementMap in="SourceGraphic" scale="50"/>
      </filter>
    </defs>
  </svg>

  <div class="sky">
    <div class="cloud cloud-1"></div>
    <div class="cloud cloud-2"></div>
    <div class="cloud cloud-3"></div>
  </div>
</body>
</html>

Template 2: Layered Parallax Clouds

模板2:分层视差云

html
<style>
  .parallax-sky {
    position: relative;
    height: 100vh;
    background: linear-gradient(to bottom,
      #1e3c72 0%,
      #2a5298 30%,
      #f5af19 90%,
      #f12711 100%
    );
    overflow: hidden;
  }

  .cloud-layer {
    position: absolute;
    width: 200%;
    height: 100%;
    background-repeat: repeat-x;
  }

  .layer-back {
    opacity: 0.3;
    filter: url(#cloudBack) blur(2px);
    animation: scroll 120s linear infinite;
  }

  .layer-mid {
    opacity: 0.5;
    filter: url(#cloudMid);
    animation: scroll 80s linear infinite;
  }

  .layer-front {
    opacity: 0.8;
    filter: url(#cloudFront);
    animation: scroll 45s linear infinite;
  }

  @keyframes scroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
  }
</style>

<svg style="display:none">
  <defs>
    <filter id="cloudBack">
      <feTurbulence type="fractalNoise" baseFrequency="0.005" numOctaves="3" seed="1"/>
      <feDisplacementMap in="SourceGraphic" scale="40"/>
    </filter>
    <filter id="cloudMid">
      <feTurbulence type="fractalNoise" baseFrequency="0.008" numOctaves="4" seed="2"/>
      <feDisplacementMap in="SourceGraphic" scale="60"/>
    </filter>
    <filter id="cloudFront">
      <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" seed="3"/>
      <feDisplacementMap in="SourceGraphic" scale="80"/>
    </filter>
  </defs>
</svg>
html
<style>
  .parallax-sky {
    position: relative;
    height: 100vh;
    background: linear-gradient(to bottom,
      #1e3c72 0%,
      #2a5298 30%,
      #f5af19 90%,
      #f12711 100%
    );
    overflow: hidden;
  }

  .cloud-layer {
    position: absolute;
    width: 200%;
    height: 100%;
    background-repeat: repeat-x;
  }

  .layer-back {
    opacity: 0.3;
    filter: url(#cloudBack) blur(2px);
    animation: scroll 120s linear infinite;
  }

  .layer-mid {
    opacity: 0.5;
    filter: url(#cloudMid);
    animation: scroll 80s linear infinite;
  }

  .layer-front {
    opacity: 0.8;
    filter: url(#cloudFront);
    animation: scroll 45s linear infinite;
  }

  @keyframes scroll {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
  }
</style>

<svg style="display:none">
  <defs>
    <filter id="cloudBack">
      <feTurbulence type="fractalNoise" baseFrequency="0.005" numOctaves="3" seed="1"/>
      <feDisplacementMap in="SourceGraphic" scale="40"/>
    </filter>
    <filter id="cloudMid">
      <feTurbulence type="fractalNoise" baseFrequency="0.008" numOctaves="4" seed="2"/>
      <feDisplacementMap in="SourceGraphic" scale="60"/>
    </filter>
    <filter id="cloudFront">
      <feTurbulence type="fractalNoise" baseFrequency="0.012" numOctaves="4" seed="3"/>
      <feDisplacementMap in="SourceGraphic" scale="80"/>
    </filter>
  </defs>
</svg>

Template 3: React Component

模板3:React组件

tsx
import React, { useMemo } from 'react';

interface CloudProps {
  type?: 'cumulus' | 'cirrus' | 'stratus' | 'storm';
  seed?: number;
  className?: string;
}

const CLOUD_CONFIGS = {
  cumulus: { baseFrequency: '0.008', numOctaves: 4, scale: 60, blur: 4 },
  cirrus: { baseFrequency: '0.02 0.005', numOctaves: 3, scale: 25, blur: 2 },
  stratus: { baseFrequency: '0.015 0.003', numOctaves: 3, scale: 30, blur: 6 },
  storm: { baseFrequency: '0.006', numOctaves: 5, scale: 150, blur: 3 },
};

export const Cloud: React.FC<CloudProps> = ({
  type = 'cumulus',
  seed = Math.floor(Math.random() * 1000),
  className
}) => {
  const filterId = useMemo(() => `cloud-${type}-${seed}`, [type, seed]);
  const config = CLOUD_CONFIGS[type];

  return (
    <>
      <svg style={{ position: 'absolute', width: 0, height: 0 }}>
        <defs>
          <filter id={filterId} x="-50%" y="-50%" width="200%" height="200%">
            <feTurbulence
              type="fractalNoise"
              baseFrequency={config.baseFrequency}
              numOctaves={config.numOctaves}
              seed={seed}
              result="noise"
            />
            <feGaussianBlur in="noise" stdDeviation={config.blur} result="blur"/>
            <feDisplacementMap in="SourceGraphic" in2="blur" scale={config.scale}/>
          </filter>
        </defs>
      </svg>
      <div
        className={className}
        style={{ filter: `url(#${filterId})` }}
      />
    </>
  );
};

// Usage:
// <Cloud type="cumulus" seed={42} className="cloud-shape" />
tsx
import React, { useMemo } from 'react';

interface CloudProps {
  type?: 'cumulus' | 'cirrus' | 'stratus' | 'storm';
  seed?: number;
  className?: string;
}

const CLOUD_CONFIGS = {
  cumulus: { baseFrequency: '0.008', numOctaves: 4, scale: 60, blur: 4 },
  cirrus: { baseFrequency: '0.02 0.005', numOctaves: 3, scale: 25, blur: 2 },
  stratus: { baseFrequency: '0.015 0.003', numOctaves: 3, scale: 30, blur: 6 },
  storm: { baseFrequency: '0.006', numOctaves: 5, scale: 150, blur: 3 },
};

export const Cloud: React.FC<CloudProps> = ({
  type = 'cumulus',
  seed = Math.floor(Math.random() * 1000),
  className
}) => {
  const filterId = useMemo(() => `cloud-${type}-${seed}`, [type, seed]);
  const config = CLOUD_CONFIGS[type];

  return (
    <>
      <svg style={{ position: 'absolute', width: 0, height: 0 }}>
        <defs>
          <filter id={filterId} x="-50%" y="-50%" width="200%" height="200%">
            <feTurbulence
              type="fractalNoise"
              baseFrequency={config.baseFrequency}
              numOctaves={config.numOctaves}
              seed={seed}
              result="noise"
            />
            <feGaussianBlur in="noise" stdDeviation={config.blur} result="blur"/>
            <feDisplacementMap in="SourceGraphic" in2="blur" scale={config.scale}/>
          </filter>
        </defs>
      </svg>
      <div
        className={className}
        style={{ filter: `url(#${filterId})` }}
      />
    </>
  );
};

// 使用示例:
// <Cloud type="cumulus" seed={42} className="cloud-shape" />

Template 4: CSS-Only Box-Shadow Clouds

模板4:纯CSS盒阴影云

For simpler, more performant clouds without SVG filters:
css
.cloud-simple {
  width: 200px;
  height: 60px;
  background: white;
  border-radius: 100px;
  position: relative;
  box-shadow:
    /* Main body shadows for volume */
    inset -10px -10px 30px rgba(0,0,0,0.05),
    inset 10px 10px 30px rgba(255,255,255,0.8),
    /* Outer glow */
    0 10px 40px rgba(0,0,0,0.1);
}

.cloud-simple::before,
.cloud-simple::after {
  content: '';
  position: absolute;
  background: white;
  border-radius: 50%;
}

.cloud-simple::before {
  width: 100px;
  height: 100px;
  top: -50px;
  left: 30px;
}

.cloud-simple::after {
  width: 70px;
  height: 70px;
  top: -30px;
  left: 100px;
}
适用于无需SVG滤镜的更简单、高性能云效果:
css
.cloud-simple {
  width: 200px;
  height: 60px;
  background: white;
  border-radius: 100px;
  position: relative;
  box-shadow:
    /* 主体阴影增加体积感 */
    inset -10px -10px 30px rgba(0,0,0,0.05),
    inset 10px 10px 30px rgba(255,255,255,0.8),
    /* 外部光晕 */
    0 10px 40px rgba(0,0,0,0.1);
}

.cloud-simple::before,
.cloud-simple::after {
  content: '';
  position: absolute;
  background: white;
  border-radius: 50%;
}

.cloud-simple::before {
  width: 100px;
  height: 100px;
  top: -50px;
  left: 30px;
}

.cloud-simple::after {
  width: 70px;
  height: 70px;
  top: -30px;
  left: 100px;
}

Performance Optimization

性能优化

Critical Rules

关键规则

  1. numOctaves 5 or fewer - Above 5 provides diminishing visual returns with exponential CPU cost
  2. Blur BEFORE displacement - 40% more efficient than blur after
  3. Avoid animating filter properties - Use CSS transforms instead
  4. Use
    seed
    for variation
    - Free performance vs. changing baseFrequency
  5. will-change: transform
    - Only on animated elements, remove when static
  6. Batch filter definitions - One
    <defs>
    block, reference by ID
  1. numOctaves不超过5 - 超过5时视觉收益递减,但CPU消耗呈指数增长
  2. 先模糊后位移 - 比先位移后模糊效率高40%
  3. 避免动画滤镜属性 - 改用CSS transform动画
  4. 使用seed实现多样云形 - 相比修改baseFrequency,无性能损耗
  5. will-change: transform
    - 仅用于动画元素,静态时移除
  6. 批量定义滤镜 - 单个
    <defs>
    块,通过ID引用

Performance Tiers

性能层级

TierTechniqueFPS TargetUse Case
UltraCSS box-shadow only60fpsMobile, low-end
HighSVG filter, no animation60fpsStatic backgrounds
MediumSVG filter + CSS transform animation45-60fpsSubtle movement
LowSVG filter +
<animate>
30fpsHero sections only
层级技术FPS目标适用场景
极致纯CSS盒阴影60fps移动端、低端设备
高性能SVG滤镜,无动画60fps静态背景
中等SVG滤镜 + CSS transform动画45-60fps轻微动态效果
低性能SVG滤镜 +
<animate>
30fps仅用于Hero区域

Mobile Considerations

移动端适配

css
@media (prefers-reduced-motion: reduce) {
  .cloud {
    animation: none;
  }
}

@media (max-width: 768px) {
  .cloud-layer {
    /* Reduce to 2 layers on mobile */
  }

  .cloud {
    filter: url(#cloudSimple); /* Fewer octaves */
  }
}
css
@media (prefers-reduced-motion: reduce) {
  .cloud {
    animation: none;
  }
}

@media (max-width: 768px) {
  .cloud-layer {
    /* 移动端减少为2层 */
  }

  .cloud {
    filter: url(#cloudSimple); /* 更少的octaves */
  }
}

Performance Detection

性能检测

javascript
// Detect if device can handle filter animations
const canHandleFilters = () => {
  const canvas = document.createElement('canvas');
  const gl = canvas.getContext('webgl');
  if (!gl) return false;

  const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
  const renderer = debugInfo
    ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
    : '';

  // Reduce effects on integrated graphics
  return !renderer.includes('Intel');
};
javascript
// 检测设备是否能处理滤镜动画
const canHandleFilters = () => {
  const canvas = document.createElement('canvas');
  const gl = canvas.getContext('webgl');
  if (!gl) return false;

  const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
  const renderer = debugInfo
    ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
    : '';

  // 集成显卡上降低效果
  return !renderer.includes('Intel');
};

Framework Integration

框架集成

Next.js / React

Next.js / React

tsx
// components/CloudBackground.tsx
'use client';

import { useEffect, useState } from 'react';

export function CloudBackground() {
  const [reducedMotion, setReducedMotion] = useState(false);

  useEffect(() => {
    const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
    setReducedMotion(mq.matches);
    mq.addEventListener('change', (e) => setReducedMotion(e.matches));
  }, []);

  return (
    <div className="cloud-container">
      {/* SVG defs in portal to document head */}
      {/* Cloud layers */}
    </div>
  );
}
tsx
// components/CloudBackground.tsx
'use client';

import { useEffect, useState } from 'react';

export function CloudBackground() {
  const [reducedMotion, setReducedMotion] = useState(false);

  useEffect(() => {
    const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
    setReducedMotion(mq.matches);
    mq.addEventListener('change', (e) => setReducedMotion(e.matches));
  }, []);

  return (
    <div className="cloud-container">
      {/* SVG defs通过portal挂载到document head */}
      {/* 云层 */}
    </div>
  );
}

Vue 3

Vue 3

vue
<template>
  <div class="sky-background">
    <CloudFilter />
    <div
      v-for="cloud in clouds"
      :key="cloud.id"
      class="cloud"
      :style="cloud.style"
    />
  </div>
</template>

<script setup>
import { computed } from 'vue';
import CloudFilter from './CloudFilter.vue';

const clouds = computed(() =>
  Array.from({ length: 5 }, (_, i) => ({
    id: i,
    style: {
      animationDuration: `${60 + i * 20}s`,
      animationDelay: `${-i * 15}s`,
      top: `${10 + i * 15}%`,
    }
  }))
);
</script>
vue
<template>
  <div class="sky-background">
    <CloudFilter />
    <div
      v-for="cloud in clouds"
      :key="cloud.id"
      class="cloud"
      :style="cloud.style"
    />
  </div>
</template>

<script setup>
import { computed } from 'vue';
import CloudFilter from './CloudFilter.vue';

const clouds = computed(() =>
  Array.from({ length: 5 }, (_, i) => ({
    id: i,
    style: {
      animationDuration: `${60 + i * 20}s`,
      animationDelay: `${-i * 15}s`,
      top: `${10 + i * 15}%`,
    }
  }))
);
</script>

Tailwind CSS

Tailwind CSS

javascript
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      animation: {
        'cloud-drift': 'drift 80s linear infinite',
        'cloud-morph': 'morph 15s ease-in-out infinite',
      },
      keyframes: {
        drift: {
          from: { transform: 'translateX(-100%)' },
          to: { transform: 'translateX(100vw)' },
        },
        morph: {
          '0%, 100%': { borderRadius: '60% 40% 30% 70% / 60% 30% 70% 40%' },
          '50%': { borderRadius: '30% 60% 70% 40% / 50% 60% 30% 60%' },
        },
      },
    },
  },
};
javascript
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      animation: {
        'cloud-drift': 'drift 80s linear infinite',
        'cloud-morph': 'morph 15s ease-in-out infinite',
      },
      keyframes: {
        drift: {
          from: { transform: 'translateX(-100%)' },
          to: { transform: 'translateX(100vw)' },
        },
        morph: {
          '0%, 100%': { borderRadius: '60% 40% 30% 70% / 60% 30% 70% 40%' },
          '50%': { borderRadius: '30% 60% 70% 40% / 50% 60% 30% 60%' },
        },
      },
    },
  },
};

Debugging Tips

调试技巧

Visualize Filter Steps

可视化滤镜步骤

xml
<!-- Output each filter step to see what's happening -->
<filter id="debug">
  <feTurbulence result="step1"/>
  <feGaussianBlur in="step1" result="step2"/>
  <feDisplacementMap in="SourceGraphic" in2="step2" result="step3"/>

  <!-- Tile outputs to see each step -->
  <feTile in="step1" result="tile1"/>
  <feOffset in="tile1" dx="0" dy="0"/>
</filter>
xml
<!-- 输出每个滤镜步骤查看效果 -->
<filter id="debug">
  <feTurbulence result="step1"/>
  <feGaussianBlur in="step1" result="step2"/>
  <feDisplacementMap in="SourceGraphic" in2="step2" result="step3"/>

  <!-- 平铺输出查看每个步骤 -->
  <feTile in="step1" result="tile1"/>
  <feOffset in="tile1" dx="0" dy="0"/>
</filter>

Common Issues

常见问题

ProblemCauseSolution
Clouds cut offFilter region too smallAdd
x="-50%" y="-50%" width="200%" height="200%"
Jagged edgesMissing blurAdd
feGaussianBlur
before displacement
No variationSame seedUse different
seed
values
Performance issuesToo many octavesReduce
numOctaves
to 3-4
Animation stutteringAnimating filter attrsUse CSS transform animations instead
问题原因解决方案
云被截断滤镜区域过小添加
x="-50%" y="-50%" width="200%" height="200%"
边缘锯齿缺少模糊在位移前添加
feGaussianBlur
云形无变化seed值相同使用不同的
seed
性能问题octaves过多
numOctaves
减少到3-4
动画卡顿动画滤镜属性改用CSS transform动画

Reference Sources

参考来源

  • CSS-Tricks: "Drawing Realistic Clouds with SVG and CSS"
  • LogRocket: "Animated Cloud Generator with SVG CSS"
  • Codrops: "SVG Filter Effects with feTurbulence"
  • Click to Release: "CSS 3D Clouds" (billboard technique)
  • Nephele Cloud Generator tool
  • MDN: SVG Filter Primitives documentation

Clouds are nature's way of reminding us that even the sky has texture.
  • CSS-Tricks: "Drawing Realistic Clouds with SVG and CSS"
  • LogRocket: "Animated Cloud Generator with SVG CSS"
  • Codrops: "SVG Filter Effects with feTurbulence"
  • Click to Release: "CSS 3D Clouds"(广告牌技术)
  • Nephele云生成工具
  • MDN: SVG滤镜原语文档

云是大自然的提醒:即使天空也有纹理。