web-wave-designer
π―Skillfrom erichowens/some_claude_skills
web-wave-designer skill from erichowens/some_claude_skills
Part of
erichowens/some_claude_skills(148 items)
Installation
/plugin marketplace add erichowens/some_claude_skills/plugin install adhd-design-expert@some-claude-skills/plugin install some-claude-skills@some-claude-skillsgit clone https://github.com/erichowens/some_claude_skills.git{
"mcpServers": {
"prompt-learning": {
"command": "npx",
"args...Skill Details
Creates realistic ocean and water wave effects for web using SVG filters (feTurbulence, feDisplacementMap), CSS animations, and layering techniques. Use for ocean backgrounds, underwater distortion, beach scenes, ripple effects, liquid glass, and water-themed UI. Activate on "ocean wave", "water effect", "SVG water", "ripple animation", "underwater distortion", "liquid glass", "wave animation", "feTurbulence water", "beach waves", "sea foam". NOT for 3D ocean simulation (use WebGL/Three.js), video water effects (use video editing), physics-based fluid simulation (use canvas/WebGL), or simple gradient backgrounds without wave motion.
Overview
# Web Wave Designer
Expert in creating realistic, performant ocean and water wave effects for web applications using SVG filters, CSS animations, and layering techniques. Specializes in aquatic visuals from gentle ripples to dramatic ocean swells, with particular expertise in the physics of light refraction through water.
When to Use This Skill
Use for:
- Ocean wave backgrounds and seascapes
- Underwater distortion/refraction effects
- Beach shore waves with foam
- Pond/pool ripple animations
- Liquid glass UI effects
- Water-themed loading states
- Parallax ocean layers with depth
- Stylized/cartoon water for games
- Reflection effects on water surfaces
Do NOT use for:
- 3D volumetric ocean rendering -> use WebGL/Three.js/Ocean.js
- Real-time fluid simulation -> use canvas physics engines
- Video effects -> use video editing software
- Simple blue gradients without motion
- Water droplet physics -> use particle systems
Core Distinction: turbulence vs fractalNoise
CRITICAL: For water effects, use type="turbulence" (NOT fractalNoise like clouds):
| Type | Visual | Best For |
|------|--------|----------|
| turbulence | Continuous flow patterns, starts from transparent black | Water, waves, liquid |
| fractalNoise | Random cloudlike patches, opaque | Clouds, smoke, terrain |
```xml
```
SVG Filter Pipeline for Water
The fundamental water effect filter chain:
```
Source -> feTurbulence -> feDisplacementMap -> feComponentTransfer -> feComposite
(waves) (distortion) (color/opacity) (blend)
```
1. feTurbulence - Wave Pattern Generation
```xml
type="turbulence"
baseFrequency="0.01 0.1"
numOctaves="3"
seed="42"
result="waves"
/>
```
baseFrequency Explained (TWO Values):
| X-Frequency | Y-Frequency | Result |
|-------------|-------------|--------|
| 0.01 | 0.1 | Long horizontal waves with vertical oscillation |
| 0.005 | 0.05 | Deep ocean swells |
| 0.02 | 0.15 | Choppy surface waves |
| 0.03 | 0.03 | Square ripples (pond) |
The ratio matters:
- X << Y: Stretched horizontal waves (ocean)
- X == Y: Circular ripples (pond, pool)
- X >> Y: Vertical striations (waterfall)
2. feDisplacementMap - Refraction Effect
Creates the bending/distortion that makes content behind water appear to ripple.
```xml
in="SourceGraphic"
in2="waves"
scale="20"
xChannelSelector="R"
yChannelSelector="G"
result="refracted"
/>
```
| Scale Value | Effect |
|-------------|--------|
| 10-15 | Gentle pool ripples |
| 15-25 | Standard water refraction |
| 25-40 | Strong wave distortion |
| 40+ | Psychedelic (unrealistic) |
3. feComponentTransfer - Water Color
Transform noise into water-like colors by manipulating channels.
```xml
```
4. feGaussianBlur - Caustics (Underwater Light)
```xml
in="waves"
stdDeviation="2"
result="caustics"
/>
```
5. Compositing - Layer Assembly
```xml
```
Wave Type Recipes
Ocean Surface Waves
```svg
baseFrequency="0.005 0.05"
numOctaves="4"
seed="1"
result="waves">
dur="60s"
values="0.005 0.05;0.007 0.06;0.005 0.05"
repeatCount="indefinite"/>
```
Pond Ripples (Circular)
```svg
baseFrequency="0.02 0.02"
numOctaves="2"
seed="10"
result="ripples"/>
```
Beach Shore Waves (Breaking)
```svg
baseFrequency="0.008 0.12"
numOctaves="3"
seed="5"
result="waves"/>
baseFrequency="0.03"
numOctaves="5"
result="foam"/>
values="1 0 0 0 0.9
1 0 0 0 0.95
1 0 0 0 1
0 0 0 0.3 0"/>
```
Underwater Distortion (Looking Through Water)
```svg
baseFrequency="0.015 0.08"
numOctaves="3"
result="distort">
dur="8s"
values="0.015 0.08;0.018 0.09;0.015 0.08"
repeatCount="indefinite"/>
scale="20"
xChannelSelector="R"
yChannelSelector="B"/>
values="0.9 0 0 0 0
0 0.95 0 0 0.02
0 0 1.1 0 0.05
0 0 0 1 0"/>
```
Liquid Glass Effect (Modern UI)
```svg
baseFrequency="0.01 0.05"
numOctaves="2"
seed="99"
result="ripple">
dur="4s"
values="99;100;101;100;99"
repeatCount="indefinite"/>
```
Stylized/Cartoon Waves
```svg
baseFrequency="0.02 0.08"
numOctaves="1"
result="waves"/>
```
Animation Techniques
JavaScript requestAnimationFrame (Smoothest)
```javascript
const turbulence = document.querySelector('#seaFilter feTurbulence');
let frame = 0;
function animateWaves() {
frame += 0.003;
// Gentle breathing motion
const xFreq = 0.006 + Math.sin(frame) * 0.002;
const yFreq = 0.05 + Math.sin(frame 0.7) 0.01;
turbulence.setAttribute('baseFrequency', ${xFreq} ${yFreq});
requestAnimationFrame(animateWaves);
}
animateWaves();
```
SVG animate (Declarative, CPU-Heavy)
```xml
attributeName="baseFrequency"
dur="60s"
keyTimes="0;0.5;1"
values="0.008 0.08;0.012 0.12;0.008 0.08"
repeatCount="indefinite"
/>
```
WARNING: SVG animate on filter attributes forces full filter recalculation every frame. Use sparingly.
CSS Transform Animation (Best Performance)
Move the water element, not the filter:
```css
.wave-layer {
animation: wave-drift 20s linear infinite;
}
@keyframes wave-drift {
from { transform: translateX(0) translateY(0); }
to { transform: translateX(-50%) translateY(5px); }
}
```
Seed Animation (Morphing Waves)
Animate seed for shape variation without baseFrequency cost:
```xml
attributeName="seed"
dur="20s"
values="1;50;100;50;1"
repeatCount="indefinite"
/>
```
Layering Strategy
Multi-Layer Ocean
```html
```
```css
.ocean {
position: relative;
height: 100vh;
background: linear-gradient(180deg,
#0c4a6e 0%,
#0369a1 40%,
#0ea5e9 100%
);
overflow: hidden;
}
.wave {
position: absolute;
width: 200%;
height: 100%;
background: rgba(255,255,255,0.1);
}
.wave-back {
filter: url(#waveBack);
opacity: 0.3;
animation: drift 90s linear infinite;
bottom: 0;
}
.wave-mid {
filter: url(#waveMid);
opacity: 0.5;
animation: drift 60s linear infinite;
bottom: -5%;
}
.wave-front {
filter: url(#waveFront);
opacity: 0.7;
animation: drift 35s linear infinite;
bottom: -10%;
}
.foam-layer {
position: absolute;
bottom: 0;
width: 100%;
height: 20%;
background: linear-gradient(to top,
rgba(255,255,255,0.8) 0%,
transparent 100%
);
filter: url(#foamFilter);
}
@keyframes drift {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
```
Layer Parameter Guide
| Layer | Opacity | Speed | Filter Scale | baseFrequency |
|-------|---------|-------|--------------|---------------|
| Back (deep) | 0.2-0.4 | 80-100s | 15 | 0.004 0.04 |
| Mid | 0.4-0.6 | 50-70s | 20 | 0.006 0.06 |
| Front (surface) | 0.6-0.8 | 30-45s | 25 | 0.01 0.1 |
| Foam | 0.7-0.9 | 25-35s | 10 | 0.02 0.02 |
Color Palettes
Deep Ocean
```css
.deep-ocean {
background: linear-gradient(180deg,
#0c4a6e 0%, / Deep blue /
#075985 30%,
#0369a1 60%,
#0284c7 100% / Surface shimmer /
);
}
```
- Primary:
#0369a1 - Deep:
#0c4a6e - Highlight:
#38bdf8
Tropical/Caribbean
```css
.tropical {
background: linear-gradient(180deg,
#06b6d4 0%, / Cyan surface /
#22d3ee 40%,
#67e8f9 70%,
#a5f3fc 100% / Shallow sand reflection /
);
}
```
- Primary:
#06b6d4 - Shallow:
#67e8f9 - Foam:
#ecfeff
Stormy Sea
```css
.stormy {
background: linear-gradient(180deg,
#1e293b 0%, / Dark clouds /
#334155 30%,
#475569 60%,
#64748b 100% / Whitecaps /
);
}
```
- Primary:
#475569 - Depth:
#1e293b - Whitecap:
#cbd5e1
Sunset Reflection
```css
.sunset-water {
background: linear-gradient(180deg,
#831843 0%, / Pink sky /
#9d174d 20%,
#be185d 40%,
#0369a1 60%, / Water starts /
#0c4a6e 100%
);
}
```
Complete Implementation Templates
Template 1: Full Ocean Scene
```html
* { margin: 0; padding: 0; box-sizing: border-box; }
.ocean-scene {
position: relative;
width: 100%;
height: 100vh;
background: linear-gradient(180deg,
#87CEEB 0%, / Sky /
#87CEEB 40%,
#0369a1 40%, / Horizon /
#0c4a6e 100% / Deep /
);
overflow: hidden;
}
.horizon-line {
position: absolute;
top: 40%;
left: 0;
right: 0;
height: 2px;
background: rgba(255,255,255,0.3);
}
.wave {
position: absolute;
width: 200%;
height: 60%;
bottom: 0;
background: rgba(255,255,255,0.15);
}
.wave-1 {
filter: url(#wave1);
animation: drift 80s linear infinite;
opacity: 0.4;
}
.wave-2 {
filter: url(#wave2);
animation: drift 55s linear infinite;
animation-delay: -20s;
opacity: 0.6;
}
.wave-3 {
filter: url(#wave3);
animation: drift 35s linear infinite;
animation-delay: -10s;
opacity: 0.8;
}
@keyframes drift {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
```
Template 2: Underwater View (Content Behind Water)
```html
.underwater-container {
position: relative;
width: 100%;
overflow: hidden;
}
.content-behind-water {
/ Your actual content /
}
.water-overlay {
position: absolute;
inset: 0;
pointer-events: none;
filter: url(#underwaterDistort);
}
.caustics {
position: absolute;
inset: 0;
background: url('data:image/svg+xml,...') repeat;
opacity: 0.3;
mix-blend-mode: overlay;
animation: caustic-shift 10s linear infinite;
}
@keyframes caustic-shift {
from { background-position: 0 0; }
to { background-position: 100px 50px; }
}
baseFrequency="0.015 0.08" numOctaves="3"/>
xChannelSelector="R" yChannelSelector="B"/>
values="0.85 0 0 0 0
0 0.9 0 0 0.02
0 0 1.1 0 0.08
0 0 0 1 0"/>
// Animate underwater distortion
const turb = document.getElementById('underwaterTurb');
let frame = 0;
function animate() {
frame += 0.005;
const xFreq = 0.015 + Math.sin(frame) * 0.003;
const yFreq = 0.08 + Math.sin(frame 0.7) 0.01;
turb.setAttribute('baseFrequency', ${xFreq} ${yFreq});
requestAnimationFrame(animate);
}
animate();
```
Template 3: React Water Component
```tsx
import React, { useEffect, useRef, useMemo } from 'react';
interface WaterEffectProps {
type?: 'ocean' | 'pool' | 'stream' | 'glass';
intensity?: 'subtle' | 'medium' | 'strong';
animate?: boolean;
className?: string;
children?: React.ReactNode;
}
const WATER_CONFIGS = {
ocean: { baseFreq: [0.008, 0.08], octaves: 4, scale: 25 },
pool: { baseFreq: [0.02, 0.02], octaves: 2, scale: 12 },
stream: { baseFreq: [0.01, 0.15], octaves: 3, scale: 20 },
glass: { baseFreq: [0.01, 0.05], octaves: 2, scale: 8 },
};
const INTENSITY_MULTIPLIERS = {
subtle: 0.5,
medium: 1.0,
strong: 1.5,
};
export const WaterEffect: React.FC
type = 'ocean',
intensity = 'medium',
animate = true,
className,
children
}) => {
const turbRef = useRef
const frameRef = useRef(0);
const config = WATER_CONFIGS[type];
const mult = INTENSITY_MULTIPLIERS[intensity];
const filterId = useMemo(() =>
water-${type}-${Date.now()}, [type]
);
useEffect(() => {
if (!animate || !turbRef.current) return;
let animationId: number;
const animateWater = () => {
frameRef.current += 0.004;
const frame = frameRef.current;
const xFreq = config.baseFreq[0] + Math.sin(frame) * 0.002;
const yFreq = config.baseFreq[1] + Math.sin(frame 0.7) 0.01;
turbRef.current?.setAttribute('baseFrequency', ${xFreq} ${yFreq});
animationId = requestAnimationFrame(animateWater);
};
animateWater();
return () => cancelAnimationFrame(animationId);
}, [animate, config]);
return (
<>
ref={turbRef}
type="turbulence"
baseFrequency={config.baseFreq.join(' ')}
numOctaves={config.octaves}
result="waves"
/>
in="SourceGraphic"
in2="waves"
scale={config.scale * mult}
xChannelSelector="R"
yChannelSelector="G"
/>
{children}
>
);
};
// Usage:
//
// 
//
```
Template 4: CSS-Only Waves (No SVG)
For simple, high-performance waves without SVG filters:
```css
.css-waves {
position: relative;
height: 300px;
background: linear-gradient(180deg, #0369a1 0%, #0c4a6e 100%);
overflow: hidden;
}
.css-wave {
position: absolute;
width: 200%;
height: 100%;
bottom: 0;
left: -50%;
background:
radial-gradient(ellipse 100% 50% at 50% 100%,
rgba(255,255,255,0.3) 0%,
transparent 60%
);
animation: css-wave-move 8s ease-in-out infinite;
transform-origin: center bottom;
}
.css-wave:nth-child(1) {
animation-duration: 7s;
opacity: 0.5;
}
.css-wave:nth-child(2) {
animation-duration: 10s;
animation-delay: -3s;
opacity: 0.3;
}
.css-wave:nth-child(3) {
animation-duration: 13s;
animation-delay: -5s;
opacity: 0.2;
}
@keyframes css-wave-move {
0%, 100% {
transform: translateX(0) scaleY(1);
}
50% {
transform: translateX(25%) scaleY(1.1);
}
}
```
Performance Optimization
Critical Rules
- Use
type="turbulence"- Correct type for water (not fractalNoise) - numOctaves <= 4 - Above 4 minimal visual gain, exponential CPU cost
- Scale 10-30 - Above 40 becomes unrealistic and slower
- Avoid animating baseFrequency - Use CSS transforms or seed animation instead
- GPU hints - Add
will-change: transformon animated layers - Batch SVG defs - One
block, multiple filters
Performance Tiers
| Tier | Technique | FPS Target | Use Case |
|------|-----------|------------|----------|
| Ultra | CSS radial gradients only | 60fps | Mobile, low-end |
| High | SVG filter, CSS transform animation | 60fps | Background waves |
| Medium | SVG filter + seed animation | 45-60fps | Interactive water |
| Low | SVG filter + baseFrequency animation | 30-40fps | Hero sections only |
Mobile Optimization
```css
@media (prefers-reduced-motion: reduce) {
.wave {
animation: none !important;
}
}
@media (max-width: 768px) {
/ Reduce to 2 wave layers /
.wave-1 { display: none; }
/ Use simpler filter /
.wave { filter: url(#waveSimple); }
}
```
Performance Detection
```javascript
const canHandleWaterEffects = () => {
// Check for GPU
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
if (!gl) return 'ultra'; // CSS only
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
const renderer = debugInfo
? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)
: '';
// Integrated graphics = medium tier
if (renderer.includes('Intel') || renderer.includes('Mali')) {
return 'medium';
}
return 'high';
};
// Apply appropriate tier
const tier = canHandleWaterEffects();
document.body.dataset.waterTier = tier;
```
```css
/ Tier-based styling /
[data-water-tier="ultra"] .wave {
filter: none;
background: linear-gradient(/ simple gradient /);
}
[data-water-tier="medium"] .wave {
filter: url(#waveSimple);
}
[data-water-tier="high"] .wave {
filter: url(#waveFull);
}
```
Framework Integration
Next.js / React
```tsx
// components/OceanBackground.tsx
'use client';
import { useEffect, useState, useRef } from 'react';
import styles from './OceanBackground.module.css';
export function OceanBackground({ children }: { children: React.ReactNode }) {
const [mounted, setMounted] = useState(false);
const turbRef = useRef
useEffect(() => {
setMounted(true);
// Animate after mount
let frame = 0;
const animate = () => {
frame += 0.003;
if (turbRef.current) {
const xFreq = 0.008 + Math.sin(frame) * 0.002;
const yFreq = 0.08 + Math.sin(frame 0.7) 0.01;
turbRef.current.setAttribute('baseFrequency', ${xFreq} ${yFreq});
}
requestAnimationFrame(animate);
};
const id = requestAnimationFrame(animate);
return () => cancelAnimationFrame(id);
}, []);
if (!mounted) return null;
return (
baseFrequency="0.008 0.08" numOctaves="4"/>
);
}
```
Tailwind CSS
```javascript
// tailwind.config.js
module.exports = {
theme: {
extend: {
animation: {
'wave-drift': 'wave-drift 60s linear infinite',
'wave-slow': 'wave-drift 90s linear infinite',
'wave-fast': 'wave-drift 35s linear infinite',
},
keyframes: {
'wave-drift': {
from: { transform: 'translateX(0)' },
to: { transform: 'translateX(-50%)' },
},
},
colors: {
ocean: {
deep: '#0c4a6e',
mid: '#0369a1',
surface: '#0ea5e9',
foam: '#f0f9ff',
},
},
},
},
};
```
Vue 3
```vue
v-for="layer in waveLayers" :key="layer.id" class="wave-layer" :style="layer.style" /> import { computed, onMounted, ref } from 'vue'; import WaveFilters from './WaveFilters.vue'; const waveLayers = computed(() => [ { id: 1, style: { filter: 'url(#wave1)', animationDuration: '80s', opacity: 0.4 }}, { id: 2, style: { filter: 'url(#wave2)', animationDuration: '55s', opacity: 0.6 }}, { id: 3, style: { filter: 'url(#wave3)', animationDuration: '35s', opacity: 0.8 }}, ]); ```
Debugging Tips
Visualize Filter Pipeline
```xml
```
Common Issues
| Problem | Cause | Solution |
|---------|-------|----------|
| Effect disappears | Filter region too small | Add x="-20%" y="-20%" width="140%" height="140%" |
| Square/boxy waves | Using fractalNoise | Change to type="turbulence" |
| Waves too uniform | Same seed across layers | Use different seed values |
| No horizontal motion | Equal baseFrequency values | Use baseFrequency="0.01 0.1" (different x/y) |
| Animation stuttering | Animating filter attributes | Use CSS transform animations instead |
| Edge artifacts | Displacement at boundaries | Increase filter region with x/y/width/height |
Browser DevTools
- Elements panel > Select SVG filter > Inspect attributes
- Performance panel > Record > Check for layout thrashing
- Layers panel (Chrome) > Verify GPU acceleration on wave layers
Integration with web-cloud-designer
For complete atmospheric scenes, combine water and cloud effects:
```html
.scene {
height: 100vh;
display: grid;
grid-template-rows: 60% 40%;
}
.sky {
background: linear-gradient(180deg, #1e3c72 0%, #87CEEB 100%);
}
.ocean {
background: linear-gradient(180deg, #0369a1 0%, #0c4a6e 100%);
}
.reflection {
/ Mirror cloud movement on water surface /
position: absolute;
top: 0;
width: 100%;
height: 30%;
background: inherit;
transform: scaleY(-1);
opacity: 0.3;
filter: url(#waterReflection) blur(2px);
}
```
Reference Sources
- Red Stapler: "Realistic Water Effect SVG Turbulence"
- Mitkov Systems: "Liquid Glass Water Animation" (2025)
- O'Reilly SVG Book: feTurbulence Chapter
- MDN: SVG Filter Primitives Documentation
- CSS-Tricks: "Underwater Blur Effect"
- Codrops: "Water Distortion Effect"
---
Water is the driving force of all nature. - Leonardo da Vinci
More from this repository10
cv-creator skill from erichowens/some_claude_skills
metal-shader-expert skill from erichowens/some_claude_skills
video-processing-editing skill from erichowens/some_claude_skills
ai-video-production-master skill from erichowens/some_claude_skills
pwa-expert skill from erichowens/some_claude_skills
sound-engineer skill from erichowens/some_claude_skills
Sanitizes MDX content by escaping angle brackets, generics, and JSX-conflicting patterns to prevent build failures and parsing errors.
indie-monetization-strategist skill from erichowens/some_claude_skills
Optimizes mobile user interfaces by implementing touch-friendly, responsive design patterns with proper viewport handling and performance considerations.
job-application-optimizer skill from erichowens/some_claude_skills