马黑黑 发表于 2022-5-19 12:45

用锥形渐变模拟圆形进度条

<style>
.outer {
        width: 100%;
        font: normal 1em / 1.4em sans-serif;
}
.outer p { margin: 0; padding: 6px 0; }
.progress {
        margin: 10px auto 0;
        width: 200px;
        height: 200px;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 50%;
        background: conic-gradient(from 180deg, red 10%, lightseagreen 10%);
        position: relative;
}
.progress::before {
        position: absolute;
        content: attr(data-per);
        width: 180px;
        height: 180px;
        border-radius: 50%;
        background: #eee;
        font: normal 1em / 180px sans-serif;
        text-align: center;
}
.jindu { background: conic-gradient(from 180deg,red 0%,seagreen 0%); }
</style>

<div class="outer">

<p>锥形渐变(conic-gradient),又称角向渐变,被关注度和使用率不及线性渐变(linear-gradient)和径向渐变(radial-gradient),但它的存在令圆形进度条的实现变复杂为简单,使用单一元素就可以完成。</p>
<p>锥形渐变属性至少需要两个颜色参与,我们的思路可以是这样:用颜色一表示进度,颜色二用作进度条的轨迹。两种颜色共享一个节点,即颜色一的结束点同时又是颜色二的起始点,这样两种颜色界限分明,颜色一就能很好地模拟进度完成量。试看如下效果:</p>

<div class="progress" data-per="10%"></div>

<p>上面的效果是进度完成量为 10% 的样子,可以满意。它是用单元素做出来的,HTML代码是:</p>
<p>&lt;<span style='color:darkred'>div</span> <span style='color: red'>class</span><span style='color: blue'>=</span><span style='color: magenta'>"progress"</span> data-<span style='color: red'>per</span><span style='color: blue'>=</span><span style='color: magenta'>"10%"</span>&gt;&lt;<span style='color: darkred'>/div</span>&gt;</p>
<p>CSS代码只需设定元素及其伪元素,主元素的作用是显示锥形渐变的效果,伪元素则遮盖主元素的中央部分并显示进度百分比。核心代码如下:</p>
<pre>
<span style='color: red;'>.progress </span>{
&nbsp; &nbsp;<span style='color: blue;'>margin</span>: 10px auto 0;
&nbsp; &nbsp;<span style='color: blue;'>width</span>: 200px;
&nbsp; &nbsp;<span style='color: blue;'>height</span>: 200px;
&nbsp; &nbsp;<span style='color: blue;'>display</span>: flex;
&nbsp; &nbsp;<span style='color: blue;'>justify-content</span>: center;
&nbsp; &nbsp;<span style='color: blue;'>align-items</span>: center;
&nbsp; &nbsp;<span style='color: blue;'>border-radius</span>: 50%;
&nbsp; &nbsp;<span style='color: blue;'>background</span>: conic-gradient(from 180deg, red 10%, lightseagreen 10%);
&nbsp; &nbsp;<span style='color: blue;'>position</span>: relative;
}
<span style='color: red;'>.<span style='color: blue;'>progress</span>:<span style='color: blue;'></span>:before </span>{
&nbsp; &nbsp;<span style='color: blue;'>position</span>: absolute;
&nbsp; &nbsp;<span style='color: blue;'>content</span>: attr(data-per);
&nbsp; &nbsp;<span style='color: blue;'>width</span>: 180px;
&nbsp; &nbsp;<span style='color: blue;'>height</span>: 180px;
&nbsp; &nbsp;<span style='color: blue;'>border-radius</span>: 50%;
&nbsp; &nbsp;<span style='color: blue;'>background</span>: #eee;
&nbsp; &nbsp;<span style='color: blue;'>font</span>: normal 1em / 180px sans-serif;
&nbsp; &nbsp;<span style='color: blue;'>text-align</span>: center;
}
</pre>
<p>注意观察主元素的背景设定:<br /><br /><span style="color: blue">background</span>: conic-gradient(from 180deg, red <span style="color: red">10%</span>, lightseagreen <span style="color: red">10%</span>);<br /><br />颜色一和颜色二共享边界,其后都用了 10%,这是关键所在。</p>
<p>而伪元素的存在意义前面已经提到了,所以它也应该拥有自己的背景色,简单设置就好,可根据场景需要选用不同的颜色。</p>
<p>进度条的状态总是动态变化的,这需要用到JS,效果如下(单独代码放在下楼):</p>

<div class="progress jindu" data-per="0%"></div>
<p style="text-align: center"><input id="kaishi" type="button" value=" 开始 " style="outline: none" /></p>

</div>

<script>

let jindu = document.querySelector('.jindu');
let current = 0;
let task = 10;
let TT;

document.querySelector('#kaishi').onclick = function() {
        current = 0;
        TT = setInterval(setProgress,task * 10);
}

function setProgress() {
        current ++;
        if(current >= 100) clearInterval(TT);
        jindu.style.background = `conic-gradient(from 180deg,red ${current}%,seagreen ${current}%)`;
        jindu.setAttribute('data-per',current + '%');
}

</script>

马黑黑 发表于 2022-5-19 12:52

锥形渐变实现圆形进度条的核心代码(请不要在本帖第一页测试):
<style>
/* 圆圈盒子:模拟圆圈进度 */
.progress {
        margin: 50px auto 0;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100px;
        height: 100px;
        border-radius: 50%;
        background: conic-gradient(from 180deg,red 0%,seagreen 0%);
}
/* 伪元素:覆盖父元素中心部分并显示百分比进度 */
.progress::before {
        position: absolute;
        content: attr(data-per);
        width: 90px;
        height: 90px;
        border-radius: 50%;
        background: lightseagreen;
        text-align: center;
        font: normal 15px / 90px sans-serif;
}

</style>

<div class="progress" data-per="0%"></div>

<script>

let progress = document.querySelector('.progress');
let current = 0; //当前进度 单位:秒
let task = 10;//任务总量 单位:秒

//定时器运行函数,task*10 是根据任务设定完成任务用时 单位:毫秒
let TT = setInterval(setProgress,task * 10);

//进度函数:以1步进令进度条平缓变化,步进至100任务完成
function setProgress() {
        current ++;
        if(current >= 100) clearInterval(TT);
        //利用锥形渐变呈现进度:两种颜色共享38线模拟出效果
        progress.style.background = `conic-gradient(from 180deg,red ${current}%,seagreen ${current}%)`;
        //伪元素百分比显示进度
        progress.setAttribute('data-per',current + '%');
}

</script>

红影 发表于 2022-5-19 13:25

这个有趣,数字和进度同步进行着{:4_187:}

红影 发表于 2022-5-19 13:25

这个也是为了做音乐进度的吧{:4_204:}

马黑黑 发表于 2022-5-19 19:28

红影 发表于 2022-5-19 13:25
这个也是为了做音乐进度的吧

这个可以做音乐播放进度条,不过开发这个功能原本不是为了这个,这是由用途的,毕竟圆形进度条很流行呢

马黑黑 发表于 2022-5-19 19:32

红影 发表于 2022-5-19 13:25
这个有趣,数字和进度同步进行着

就是对浏览器有要求,不能是IE。好在IE微软已经宣布停更,估计用它的人也会慢慢减少了吧

红影 发表于 2022-5-20 13:33

马黑黑 发表于 2022-5-19 19:28
这个可以做音乐播放进度条,不过开发这个功能原本不是为了这个,这是由用途的,毕竟圆形进度条很流行呢

哦,通常是用在哪里的呢?

红影 发表于 2022-5-20 13:34

马黑黑 发表于 2022-5-19 19:32
就是对浏览器有要求,不能是IE。好在IE微软已经宣布停更,估计用它的人也会慢慢减少了吧

IE不支持这个的吧。嗯,现在用IE的已经很少了呢。

马黑黑 发表于 2022-5-20 18:06

红影 发表于 2022-5-20 13:34
IE不支持这个的吧。嗯,现在用IE的已经很少了呢。

做的人都彻底抛弃它了

马黑黑 发表于 2022-5-20 18:06

红影 发表于 2022-5-20 13:33
哦,通常是用在哪里的呢?

你看天猫淘宝京东拼多多等APP
页: [1]
查看完整版本: 用锥形渐变模拟圆形进度条