实现波浪按照百分比填充圆形

以下是实现一个可调整波浪高度以填充圆形的前端代码示例:

<!DOCTYPE html>
<html>
<head>
    <style>
        .container {
            width: 200px;
            height: 200px;
            border-radius: 50%;
            overflow: hidden;
            position: relative;
            background: #e0e0e0;
            margin: 50px;
        }
        
        #waveCanvas {
            position: absolute;
            left: 0;
        }
        
        .percent {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 24px;
            color: #333;
            font-family: Arial;
        }
    </style>
</head>
<body>
    <div class="container">
        <canvas id="waveCanvas"></canvas>
        <div class="percent">0%</div>
    </div>

    <script>
        const canvas = document.getElementById('waveCanvas');
        const ctx = canvas.getContext('2d');
        const container = document.querySelector('.container');
        const percentElement = document.querySelector('.percent');

        let progress = 0;
        let phase = 0;
        const waveSpeed = 0.02;
        const waveAmplitude = 10;
        const waveFrequency = 0.02;

        function resizeCanvas() {
            canvas.width = container.clientWidth;
            canvas.height = container.clientHeight;
        }

        function drawWave() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 创建圆形裁剪路径
            ctx.beginPath();
            ctx.arc(canvas.width/2, canvas.height/2, canvas.width/2, 0, 2 * Math.PI);
            ctx.clip();

            // 计算当前波浪位置
            const waveY = canvas.height * (1 - progress/100);
            
            // 绘制波浪路径
            ctx.beginPath();
            ctx.moveTo(0, waveY);
            
            for(let x = 0; x <= canvas.width; x++) {
                const y = waveY + Math.sin(x * waveFrequency + phase) * waveAmplitude;
                ctx.lineTo(x, y);
            }

            ctx.lineTo(canvas.width, canvas.height);
            ctx.lineTo(0, canvas.height);
            ctx.closePath();
            
            // 填充颜色
            ctx.fillStyle = '#4CAF50';
            ctx.fill();

            // 更新相位
            phase += waveSpeed;
        }

        function animate() {
            if(progress < 100) {
                progress += 0.5;
                percentElement.textContent = `${Math.round(progress)}%`;
            }
            
            drawWave();
            requestAnimationFrame(animate);
        }

        // 初始化
        resizeCanvas();
        animate();

        // 窗口调整大小处理
        window.addEventListener('resize', () => {
            resizeCanvas();
            drawWave();
        });
    </script>
</body>
</html>

关键实现原理:

  1. 圆形容器:使用CSS创建圆形容器,通过overflow: hidden确保内容不会超出圆形范围

  2. Canvas绘制

    • 使用Canvas绘制波浪效果
    • 通过arc()创建圆形裁剪路径
    • 使用正弦函数生成波浪形状
  3. 动态控制

    • progress变量控制填充进度(0-100)
    • phase变量实现波浪动画效果
    • 通过requestAnimationFrame实现流畅动画
  4. 波浪计算

    • 波浪Y坐标:canvas.height * (1 - progress/100)
    • 正弦函数生成波浪形状:y = waveY + sin(x * frequency + phase) * amplitude
  5. 自适应处理

    • 监听窗口resize事件
    • 自动调整Canvas尺寸

效果特点:

  • 平滑的波浪动画效果
  • 自动百分比显示
  • 自适应容器大小
  • 流畅的填充动画

可以通过修改以下参数调整效果:

  • waveSpeed:波浪移动速度
  • waveAmplitude:波浪幅度
  • waveFrequency:波浪密度
  • 填充颜色:修改ctx.fillStyle
  • 动画速度:修改progress的递增值

要改为手动控制进度,可以将animate函数中的自动progress修改为通过滑动条或其他交互方式控制。

image

posted @   东八区  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示