web-cloud-designer
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWeb 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 -> Composite1. 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, >5 diminishing returns -->
seed="42" <!-- Change for shape variation (free!) -->
result="noise"
/>| Parameter | Range | Effect |
|---|---|---|
| 0.005-0.02 | Scale of cloud shapes. 0.005 = giant cumulus, 0.02 = small wisps |
| 3-5 | Detail layers. 3 = smooth, 5 = detailed. Above 5 = CPU waste |
| 0-999999 | Shape variation. Change this, NOT baseFrequency for variety |
| fractalNoise | ALWAYS 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"
/>| 参数 | 范围 | 效果 |
|---|---|---|
| 0.005-0.02 | 云形状的缩放比例。0.005 = 大型积云,0.02 = 小卷云 |
| 3-5 | 细节层数。3 = 平滑,5 = 细节丰富。超过5会造成CPU浪费 |
| 0-999999 | 形状变化。如需多样云形,修改该值而非baseFrequency |
| 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 Value | Effect |
|---|---|
| 20-50 | Subtle, wispy cirrus |
| 50-100 | Balanced cumulus |
| 100-170 | Dramatic, 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 (two values) for stretched, directional wisps.
baseFrequencysvg
<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>关键:使用各向异性的(两个值)创建拉伸的定向卷云。
baseFrequencyStratus (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
分层参数指南
| Layer | Opacity | Speed | Scale | blur stdDeviation |
|---|---|---|---|---|
| Back (distant) | 0.2-0.4 | 90-120s | 1.3-1.5x | 5-8 |
| Mid | 0.5-0.7 | 50-80s | 1.0x | 3-5 |
| Front (close) | 0.8-1.0 | 30-50s | 0.7-0.9x | 1-3 |
| 层级 | 透明度 | 速度 | 缩放比例 | 模糊stdDeviation |
|---|---|---|---|---|
| 背景层(远处) | 0.2-0.4 | 90-120s | 1.3-1.5x | 5-8 |
| 中间层 | 0.5-0.7 | 50-80s | 1.0x | 3-5 |
| 前景层(近处) | 0.8-1.0 | 30-50s | 0.7-0.9x | 1-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
关键规则
- numOctaves 5 or fewer - Above 5 provides diminishing visual returns with exponential CPU cost
- Blur BEFORE displacement - 40% more efficient than blur after
- Avoid animating filter properties - Use CSS transforms instead
- Use for variation - Free performance vs. changing baseFrequency
seed - - Only on animated elements, remove when static
will-change: transform - Batch filter definitions - One block, reference by ID
<defs>
- numOctaves不超过5 - 超过5时视觉收益递减,但CPU消耗呈指数增长
- 先模糊后位移 - 比先位移后模糊效率高40%
- 避免动画滤镜属性 - 改用CSS transform动画
- 使用seed实现多样云形 - 相比修改baseFrequency,无性能损耗
- - 仅用于动画元素,静态时移除
will-change: transform - 批量定义滤镜 - 单个块,通过ID引用
<defs>
Performance Tiers
性能层级
| Tier | Technique | FPS Target | Use Case |
|---|---|---|---|
| Ultra | CSS box-shadow only | 60fps | Mobile, low-end |
| High | SVG filter, no animation | 60fps | Static backgrounds |
| Medium | SVG filter + CSS transform animation | 45-60fps | Subtle movement |
| Low | SVG filter + | 30fps | Hero sections only |
| 层级 | 技术 | FPS目标 | 适用场景 |
|---|---|---|---|
| 极致 | 纯CSS盒阴影 | 60fps | 移动端、低端设备 |
| 高性能 | SVG滤镜,无动画 | 60fps | 静态背景 |
| 中等 | SVG滤镜 + CSS transform动画 | 45-60fps | 轻微动态效果 |
| 低性能 | SVG滤镜 + | 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
常见问题
| Problem | Cause | Solution |
|---|---|---|
| Clouds cut off | Filter region too small | Add |
| Jagged edges | Missing blur | Add |
| No variation | Same seed | Use different |
| Performance issues | Too many octaves | Reduce |
| Animation stuttering | Animating filter attrs | Use CSS transform animations instead |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 云被截断 | 滤镜区域过小 | 添加 |
| 边缘锯齿 | 缺少模糊 | 在位移前添加 |
| 云形无变化 | seed值相同 | 使用不同的 |
| 性能问题 | octaves过多 | 将 |
| 动画卡顿 | 动画滤镜属性 | 改用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滤镜原语文档
云是大自然的提醒:即使天空也有纹理。