文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

别用图片了,CSS 遮罩合成实现带圆角的环形 loading 动画

2024-11-30 16:13

关注

今天来用 CSS 实现一个带圆角的环形 loading 动画,效果是这样的

先不考虑动画,其实就是这样一个图形

那么,如何来绘制呢?下面花两分钟一起看看吧。

一、CSS实现思路

首先,看到这环形逐渐消失的效果,也就是透明度渐变的效果,肯定要联想到锥形渐变。

conic-gradient() - CSS:层叠样式表 | MDN (mozilla.org)[1]

通过锥形渐变,可以很轻松的实现这样一个效果,透明到纯色的渐变。

loading{
background: conic-gradient(transparent 10%, royalblue 90%)
}

效果如下:

然后,整体是一个环形,可以通过径向渐变配合mask遮罩实现。

radial-gradient() - CSS:层叠样式表 | MDN (mozilla.org)[2]

mask - CSS: Cascading Style Sheets | MDN (mozilla.org)[3]

loading{

-webkit-mask: radial-gradient( closest-side circle, transparent 50%, red 51% 99%, transparent 100%);
}

原理是这样的。

还有一个圆角,可以直接用径向渐变实现。

loading{
background: radial-gradient( closest-side circle, royalblue 99%, transparent 100%) center top/25% 25% no-repeat,
conic-gradient(transparent 10%, royalblue 90%);;
}

其实就是两个相同颜色的渐变叠加到一起形成的,如下:

所以完整代码就是。

loading{
width: 200px;
height: 200px;
background:
radial-gradient( closest-side circle, royalblue 99%, transparent 100%) center top/25% 25% no-repeat,
conic-gradient(transparent 10%, royalblue 90%);
-webkit-mask: radial-gradient( closest-side circle, transparent 50%, red 51% 99%, transparent 100%);
}

二、更好地自定义颜色

上面的实现虽然很好的满足了需求,但是,还是有些CSS设计问题。

比如,我如果需要改变 loading 的颜色,需要改变两个地方。

很明显,这样的实现不太符合 DRY(Don't Repeat Yourself)原则。

有一个比较简单思路可以用 CSS 变量来传递。

loading{
--color: royalblue;
background:
radial-gradient( closest-side circle, var(--color) 99%, transparent 100%) center top/25% 25% no-repeat,
conic-gradient(transparent 10%, var(--color) 90%);
-webkit-mask: radial-gradient( closest-side circle, transparent 50%, red 51% 99%, transparent 100%);
}

这样每次都只需要改变一个变量就行了。

loading.red{
--color: red;
}

除了这种方式以外,其实还有一点需要考虑,为啥背景不能干净一点、纯粹一点呢?换个说法,现在的背景实现对于不了解的同学来讲,可能会很费劲,能否将这些细节隐藏起来,更直观地去自定义颜色呢?比如像这种方式。

loading.red{
background: red;
}

如果要实现这样的效果,就需要将绘制部分全部在mask遮罩中完成,背景只是展示而已。

那么,如何通过mask遮罩实现这样的图形呢?

三、更直观地去自定义颜色

mask​遮罩其实也和 CSS 背景差不多,只是多了一些图形合成操作,其实就是布尔运算,也就是mask-composite。

mask-composite - CSS: Cascading Style Sheets | MDN (mozilla.org)[4]


mask-composite: add;
mask-composite: subtract;
mask-composite: intersect;
mask-composite: exclude;

相信在很多图形设计软件中都见到类似的操作(下面是 photoshop)。

这个属性的值(标准和非标准)非常多,-webkit-mask-composite[5] 与标准下的值有所不同,属性值非常多,如下(chorme 、safari 支持)。

-webkit-mask-composite: clear; 
-webkit-mask-composite: copy;
-webkit-mask-composite: source-over;
-webkit-mask-composite: source-in;
-webkit-mask-composite: source-out;
-webkit-mask-composite: source-atop;
-webkit-mask-composite: destination-over;
-webkit-mask-composite: destination-in;
-webkit-mask-composite: destination-out;
-webkit-mask-composite: destination-atop;
-webkit-mask-composite: xor;

之前在这篇文章中有详细介绍 mask-composite 的用法,有兴趣的可以回顾一下。

CSS mask 实现鼠标跟随镂空效果[6]

回到这里,思考一下🤔,怎么来绘制这样一个图形?

形状是一样的,只是和前面的步骤稍微有些差异。

首先还是绘制环形渐变,可以先绘制锥形渐变和环形渐变,如下:

loading{
background: royalblue;
-webkit-mask:
radial-gradient( closest-side circle, transparent 49%, red 50% 99%, transparent 100%),
conic-gradient(transparent 10%, royalblue 90%);
}

但是这样两个渐变会叠加在一起。

其实我们需要是只显示两者重叠的部分,也就是交叉区域,这个特性在mask-composite​中对应的就是destination-in​或者source-in。

loading{
...
-webkit-mask-composite: source-in;
}

效果如下:

然后是那个圆角,和上面绘制一样。

loading{
...
-webkit-mask:
radial-gradient( closest-side circle, royalblue 99%, transparent 100%) center top/25% 25% no-repeat,
radial-gradient( closest-side circle, transparent 49%, red 50% 99%, transparent 100%),
conic-gradient(transparent 10%, royalblue 90%)
;
-webkit-mask-composite: source-in;
}

如果直接这样,会变成这样。

其实这是因为source-in​导致的,三个图形,最后只显示了三者重叠的区域。但是我们现在需要的是最上面的圆角直接叠加就行了,不需要裁剪,可以用到source-over。

loading{
-webkit-mask-composite: source-over, source-in;
}

效果如下:

下面是完整代码。

loading{
width: 200px;
height: 200px;
background: royalblue;
-webkit-mask:
radial-gradient( closest-side circle, royalblue 99%, transparent 100%) center top/25% 25% no-repeat,
radial-gradient( closest-side circle, transparent 49%, red 50% 99%, transparent 100%),
conic-gradient(transparent 10%, royalblue 90%);
-webkit-mask-composite: source-over, source-in;
}

如果要换颜色,直接更换背景就可以了,还可以是渐变。

loading{
background: conic-gradient(red, orange, red)
}

自定义颜色起来是不是更加直观?

四、动画和xy-ui

动画很简单,就是一个无限旋转的线性动画,这个没什么好说的。

loading{
animation: rotate 1s linear infinite;
}
@keyframes rotate{
to{
transform: rotate(360deg);
}
}

这样就实现了文章开头效果。

关于线上 demo,这里安利一下我开发的xy-ui[7]组件库(目前正在重构中...),里面 loading 组件就用到了这个实现。

https://xy-ui.codelabo.cn。

很多有趣的 CSS 小技巧都可以在这个组件库中找到,欢迎 star & fork 👏🏻👏🏻👏🏻。

五、总结和说明

以上就是本文的全部内容了,稍显啰嗦,不过也是为了提供更多的思路,下面总结一下实现重点。

  1. 整个实现其实用到了锥形渐变和径向渐变。
  2. 正常思路是背景绘制出透明锥形渐变,然后通过 mask 遮罩裁剪出环形。
  3. 不过这种思路改颜色稍微麻烦一点,可以通过 CSS 变量传递,简化代码。
  4. 颜色在背景中不够直观,可以考虑将实现细节放到 mask 中。
  5. mask遮罩合成可以实现图形的合成与裁剪,可以更灵活的布尔运算。
  6. 推荐一下我的组件库 xy-ui,可以学到更多有趣的 CSS 小技巧。

参考资料

[1]conic-gradient() - CSS:层叠样式表 | MDN (mozilla.org): https://developer.mozilla.org/zh-CN/docs/Web/CSS/gradient/conic-gradient。

[2]radial-gradient() - CSS:层叠样式表 | MDN (mozilla.org): https://developer.mozilla.org/zh-CN/docs/Web/CSS/gradient/radial-gradient。

[3]mask - CSS: Cascading Style Sheets | MDN (mozilla.org): https://developer.mozilla.org/en-US/docs/Web/CSS/mask。

[4]mask-composite - CSS: Cascading Style Sheets | MDN (mozilla.org): https://developer.mozilla.org/en-US/docs/Web/CSS/mask-composite。

[5]-webkit-mask-composite: https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FCSS%2F-webkit-mask-composite。

[6]CSS mask 实现鼠标跟随镂空效果: https://juejin.cn/post/7033188994641100831#heading-7。

[7]xy-ui: https://xy-ui.codelabo.cn/components/loading。

来源:前端侦探内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯