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. |