1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8">
5<meta name="viewport" content="width=device-width, initial-scale=1.0">
6<title>Wave Animation</title>
7<style>
8 * { margin: 0; padding: 0; box-sizing: border-box; }
9
10 body {
11 background-color: #3a3a3a;
12 display: flex;
13 justify-content: center;
14 align-items: center;
15 min-height: 100vh;
16 }
17
18 .card {
19 width: 500px;
20 height: 500px;
21 border-radius: 16px;
22 background: linear-gradient(to bottom, #fffef8 0%, #f0f4ff 40%, #e8eef8 70%, #dde8f5 100%);
23 overflow: hidden;
24 position: relative;
25 border: 2px solid rgba(255,255,255,0.9);
26 }
27
28 canvas {
29 position: absolute;
30 bottom: 0;
31 left: 0;
32 width: 100%;
33 height: 100%;
34 }
35</style>
36</head>
37<body>
38<div class="card">
39 <canvas id="waveCanvas"></canvas>
40</div>
41
42<script>
43 const canvas = document.getElementById('waveCanvas');
44 const ctx = canvas.getContext('2d');
45
46 function resize() {
47 canvas.width = canvas.offsetWidth;
48 canvas.height = canvas.offsetHeight;
49 }
50 resize();
51
52 let t = 0;
53
54 function drawWave() {
55 ctx.clearRect(0, 0, canvas.width, canvas.height);
56
57 const W = canvas.width;
58 const H = canvas.height;
59
60 // Background gradient for the card
61 const bgGrad = ctx.createLinearGradient(0, 0, 0, H);
62 bgGrad.addColorStop(0, '#fffef8');
63 bgGrad.addColorStop(0.4, '#f0f4ff');
64 bgGrad.addColorStop(0.7, '#e8eef8');
65 bgGrad.addColorStop(1, '#dde8f5');
66 ctx.fillStyle = bgGrad;
67 ctx.fillRect(0, 0, W, H);
68
69 // Wave 1 - back wave (lighter, higher)
70 const baseY1 = H * 0.72;
71 const amp1 = 28;
72 const freq1 = 2 * Math.PI / W;
73 const speed1 = t * 0.6;
74
75 ctx.beginPath();
76 ctx.moveTo(0, H);
77 for (let x = 0; x <= W; x++) {
78 const y = baseY1 + amp1 * Math.sin(freq1 * x * 1.5 + speed1 + Math.PI);
79 ctx.lineTo(x, y);
80 }
81 ctx.lineTo(W, H);
82 ctx.closePath();
83
84 const grad1 = ctx.createLinearGradient(0, baseY1 - amp1, 0, H);
85 grad1.addColorStop(0, 'rgba(180, 205, 235, 0.5)');
86 grad1.addColorStop(1, 'rgba(160, 195, 230, 0.7)');
87 ctx.fillStyle = grad1;
88 ctx.fill();
89
90 // Wave 2 - front wave (more opaque, lower)
91 const baseY2 = H * 0.78;
92 const amp2 = 22;
93 const speed2 = t * 0.8;
94
95 ctx.beginPath();
96 ctx.moveTo(0, H);
97 for (let x = 0; x <= W; x++) {
98 const y = baseY2 + amp2 * Math.sin(freq1 * x * 1.2 + speed2);
99 ctx.lineTo(x, y);
100 }
101 ctx.lineTo(W, H);
102 ctx.closePath();
103
104 const grad2 = ctx.createLinearGradient(0, baseY2 - amp2, 0, H);
105 grad2.addColorStop(0, 'rgba(190, 215, 240, 0.6)');
106 grad2.addColorStop(1, 'rgba(170, 200, 235, 0.85)');
107 ctx.fillStyle = grad2;
108 ctx.fill();
109
110 // Subtle horizontal band / mist effect in middle
111 const mistGrad = ctx.createLinearGradient(0, H * 0.55, 0, H * 0.72);
112 mistGrad.addColorStop(0, 'rgba(220, 230, 245, 0)');
113 mistGrad.addColorStop(0.5, 'rgba(210, 225, 242, 0.15)');
114 mistGrad.addColorStop(1, 'rgba(200, 220, 240, 0)');
115 ctx.fillStyle = mistGrad;
116 ctx.fillRect(0, H * 0.55, W, H * 0.17);
117
118 t += 0.04;
119 requestAnimationFrame(drawWave);
120 }
121
122 drawWave();
123</script>
124</body>
125</html>