Wavy Background
A cool background effect with waves that move.
Hero waves are cool
Leverage the power of canvas to create a beautiful hero section
<script lang="ts">
import { WavyBackground } from '.';
</script>
<WavyBackground className="max-w-4xl mx-auto pb-40">
<p class="inter-var text-center text-2xl font-bold text-white md:text-4xl lg:text-7xl">
Hero waves are cool
</p>
<p class="inter-var mt-4 text-center text-base font-normal text-white md:text-lg">
Leverage the power of canvas to create a beautiful hero section
</p>
</WavyBackground>
Installation
Install Dependencies
npm i svelte-motion clsx tailwind-merge
Add util file
src/lib/utils/cn.ts
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
Copy the source code
src/lib/components/ui/WavyBackground/WavyBackground.svelte
<script lang="ts">
import { cn } from '@/utils';
import { createNoise3D } from 'simplex-noise';
import { onMount } from 'svelte';
import { writable } from 'svelte/store';
export let className: string | undefined = undefined;
export let containerClassName: string | undefined = undefined;
export let colors: string[] | undefined = undefined;
export let waveWidth: number | undefined = undefined;
export let backgroundFill: string | undefined = undefined;
export let blur: number | undefined = 10;
export let speed: 'slow' | 'fast' | undefined = 'fast';
export let waveOpacity: number | undefined = 0.5;
// export let [key: string]: any;
const noise = createNoise3D();
let w: number, h: number, nt: number, i: number, x: number, ctx: any, canvas: any;
// const canvasRef = writable<HTMLCanvasElement>();
let canvasRef: HTMLCanvasElement;
const getSpeed = () => {
switch (speed) {
case 'slow':
return 0.001;
case 'fast':
return 0.002;
default:
return 0.001;
}
};
const init = () => {
console.log(canvasRef);
canvas = canvasRef;
ctx = canvas.getContext('2d');
console.log('ctx', ctx);
w = ctx.canvas.width = window.innerWidth;
h = ctx.canvas.height = window.innerHeight;
ctx.filter = `blur(${blur}px)`;
nt = 0;
window.onresize = function () {
w = ctx.canvas.width = window.innerWidth;
h = ctx.canvas.height = window.innerHeight;
ctx.filter = `blur(${blur}px)`;
};
render();
};
const waveColors = colors ?? ['#38bdf8', '#818cf8', '#c084fc', '#e879f9', '#22d3ee'];
const drawWave = (n: number) => {
nt += getSpeed();
for (i = 0; i < n; i++) {
ctx.beginPath();
ctx.lineWidth = waveWidth || 50;
ctx.strokeStyle = waveColors[i % waveColors.length];
for (x = 0; x < w; x += 5) {
var y = noise(x / 800, 0.3 * i, nt) * 100;
ctx.lineTo(x, y + h * 0.5); // adjust for height, currently at 50% of the container
}
ctx.stroke();
ctx.closePath();
}
};
let animationId: number;
const render = () => {
ctx.fillStyle = backgroundFill || 'black';
ctx.globalAlpha = waveOpacity || 0.5;
ctx.fillRect(0, 0, w, h);
drawWave(5);
animationId = requestAnimationFrame(render);
};
onMount(() => {
init();
return () => {
cancelAnimationFrame(animationId);
};
});
</script>
<div class={cn('flex h-screen flex-col items-center justify-center', containerClassName)}>
<canvas class="absolute inset-0 z-0" bind:this={canvasRef} id="canvas"></canvas>
<div class={cn('relative z-10', className)} {...$$props}>
<slot />
</div>
</div>
src/lib/components/ui/WavyBackground/index.ts
import WavyBackground from './WavyBackground.svelte';
export { WavyBackground };
Props
WavyBackground
Prop | Type | Description |
---|---|---|
className | string | undefined | The CSS class to apply to the content container. |
containerClassName | string | undefined | The CSS class to apply to the main container. |
colors | string[] | undefined | An array of colors to use for the waves. |
waveWidth | number | undefined | The width of the waves. |
backgroundFill | string | undefined | The background color. |
blur | number | undefined | Default: 10. The amount of blur to apply to the waves. |
speed | "slow" | "fast" | undefined | Default: "fast". The speed of the wave animation. |
waveOpacity | number | undefined | Default: 0.5. The opacity of the waves. |