一个玻璃进度环的js源代码

通过SVG、CSS和JavaScript实现一个带玻璃效果的进度环,利用动画和渐变提升视觉效果,打造高科技感UI组件。
直达下载
回到上一页
clickgpt_line.png_noView
介绍

我们平时在很多网站或者应用程序里,应该都见过各种各样的进度条,比如下载文件、加载数据时常见的那种。但这段代码特别的地方在于,它不仅展示了进度,而且加上了一层“玻璃”效果,这种透明、模糊的感觉瞬间就提升了整个视觉效果的高级感。

这段代码实现了一个带有玻璃效果的SVG进度环,它看起来非常酷炫,尤其在深色背景下,显得很科技感。通过一些动画和渐变,打造出光滑、透亮的视觉体验。

web_effect_glass_progress_ring_1

今天就和大家分享一下这个效果的实现,顺便写写我是如何解析这段代码的,也给大家一点思路,万一以后面试或者做项目的时候能用到呢。

核心实现思路

我知道,光说不练假把式,直接上源码会更直观。我简单梳理了一下整个代码的实现,主要分为几个部分:基础样式、SVG进度环的设计、动画的控制。接下来我逐步讲解。

1. 样式定义

在CSS中,开发者用了很多变量来管理颜色和动画时间:

    
:root {
    --hue: 223;
    --bg: hsl(var(--hue), 90%, 10%);
    --fg: hsl(var(--hue), 90%, 90%);
    --primary: hsl(var(--hue), 90%, 50%);
    --trans-dur: 0.3s;
    --trans-timing: cubic-bezier(0.65, 0, 0.35, 1);
    font-size: calc(16px + (24 - 16) * (100vw - 320px) / (2560 - 320));
}

这些CSS变量用来定义颜色主题,利用HSL颜色模型,可以很方便地修改整体的色调。--hue是控制色相的,通过调整这个值,能轻松切换环形进度条的颜色。这里的--bg--fg分别是背景和前景色,而--primary是进度环的主色调。

font-size 也非常巧妙,它根据视口宽度进行动态调整,保证在不同屏幕上字体大小都合适。是不是觉得特别细腻?别急,这只是开始。

2. SVG进度环

SVG是核心的部分,这个环形进度条就是通过SVG图形来绘制的。让我们仔细看看这一部分的代码:

    
<svg class="pl" viewBox="0 0 270 270" width="270px" height="270px" role="img" aria-labelledby="pl-percent">
    <g fill="none">
        <g transform="rotate(-90,135,135)">
            <circle class="pl__ring" r="105" cx="135" cy="135" stroke-dasharray="659.74 659.74" stroke-dashoffset="659.74" stroke-width="40" />
            <g filter="url(#glass-glow)" stroke-linecap="round" stroke-width="4" opacity="0.6">
                <circle class="pl__ring-glow1" r="80" cx="135" cy="135" stroke-dasharray="502.66 502.66" stroke-dashoffset="502.66" />
                <circle class="pl__ring-glow2" r="130" cx="135" cy="135" stroke-dasharray="816.82 816.82" stroke-dashoffset="816.82" />
            </g>
        </g>
    </g>
</svg>

这段代码用到了<circle>元素来绘制圆形进度条。几个重要参数:

  • r="105":定义了圆的半径,105px。
  • cx="135"cy="135":定义了圆心的坐标,135px。
  • stroke-dasharray:这个属性控制了圆形边线的绘制方式,659.74是圆周长,它通过控制线条的“虚线”状态来模拟进度。

stroke-dashoffset 是控制进度的核心,它的值根据百分比(--percent)动态变化。当stroke-dashoffset为圆周长时,进度是0%,当它为0时,表示进度完成。

同时,代码中使用了多个滤镜来增强视觉效果,比如模糊和渐变,让整个环看起来有种玻璃的透明质感。尤其是filter="url(#glass-glow)",它在进度环的周围增加了一层微光效果,这样看起来更加真实。

3. 动画效果

有了进度环之后,还需要动画来让它“动起来”,这就是JavaScript的活儿了。我们来看看代码里的JS部分:

    
window.addEventListener("DOMContentLoaded", () => {
    const gpr = new GlassProgressRing(".pl");
    const replayBtn = document.querySelector("#replay");
    replayBtn?.addEventListener("click", gpr.replay.bind(gpr));
});

class GlassProgressRing {
    constructor(el) {
        this.el = document.querySelector(el);
        this.complete = false;
        this.percent = 0;
        this.init();
    }

    init() {
        this.progressDisplay();
        this.loop();
    }

    loop() {
        if (!this.complete) {
            this.progressInc();
            setTimeout(this.loop.bind(this), 17); // 每帧更新进度
        }
    }

    progressInc(amount = 0.01) {
        this.percent += amount;
        if (this.percent >= 1) {
            this.percent = 1;
            this.complete = true;
        }
        this.progressDisplay();
    }

    progressDisplay() {
        this.el.style.setProperty("--percent", this.percent);
        const percentText = `${Math.round(this.percent * 100)}%`;
        const percentEl = this.el.querySelector("[data-percent]");
        percentEl.innerHTML = percentText;
    }

    replay() {
        this.complete = false;
        this.percent = 0;
        this.init();
    }
}

这里,JavaScript控制了整个进度环的动画过程。progressInc()函数是每次递增进度的关键部分,每次增加0.01,也就是1%的进度,直到percent达到1。

关键是setTimeout(),通过每隔17毫秒调用一次loop()函数,实现了进度条的平滑过渡。为什么是17毫秒?因为这相当于每秒60帧,符合大部分屏幕的刷新率,所以动画看起来会特别流畅。

4. 技术难点解析

这个项目其实有几个技术细节需要注意:

  1. SVG的动画控制:通过CSS变量--percentstroke-dashoffset的配合,控制了SVG环形进度条的绘制进度。这种做法非常高效,尤其是在处理矢量图形时,能大幅提升性能。
  2. 渐变和模糊滤镜的运用:这个玻璃效果主要通过<filter><linearGradient>实现,这部分的实现比较复杂,细节上要保证渐变色的过渡自然,滤镜效果适中,才能达到预期的玻璃质感。
  3. 响应式设计:整个代码是自适应的,字体大小、颜色等都使用了CSS变量,可以根据不同的屏幕尺寸动态调整,保证了良好的兼容性。

结语

这段代码不复杂,但是细节处理得非常到位,从颜色到动画再到交互,整体效果非常流畅。通过这段代码,我们不仅能学习到如何利用SVG创建炫酷的UI组件,还能掌握一些CSS动画和滤镜的技巧。

如果你觉得这个进度环有意思,可以把代码复制下来,直接放到自己的项目里玩一玩。如果你愿意再改进一下,比如加点不同的色彩、控制动画速度,甚至是结合业务场景动态显示进度,那这个组件的实际价值会变得更大。

编程学习
编程学习 免费领取编程学习资料 进编程学习交流群
订阅号
视频号
公众号 关注公众号,回复关键字java领取大厂最新面试题
×
编程学习
免费领取编程学习资料 进编程学习交流群