欢送关注我的公众号:前端侦探
明天来用 CSS 实现一个带圆角的环形 loading 动画,成果是这样的
先不思考动画,其实就是这样一个图形
那么,如何来绘制呢?上面花两分钟一起看看吧
一、CSS 实现思路
首先,看到这环形逐步隐没的成果,也就是透明度突变的成果,必定要联想到 锥形突变
conic-gradient() – CSS:层叠样式表 | MDN (mozilla.org)
通过锥形突变,能够很轻松的实现这样一个成果,通明到纯色的突变
loading{background: conic-gradient(transparent 10%, royalblue 90%)
}
成果如下
而后,整体是一个环形,能够通过径向突变配合 mask
遮罩实现
radial-gradient() – CSS:层叠样式表 | MDN (mozilla.org)
mask – CSS: Cascading Style Sheets | MDN (mozilla.org)
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)
/* Keyword values */
mask-composite: add; /* 叠加(默认)*/
mask-composite: subtract; /* 减去,排除掉下层的区域 */
mask-composite: intersect; /* 相交,只显示重合的中央 */
mask-composite: exclude; /* 排除,只显示不重合的中央 */
置信在很多图形设计软件中都见到相似的操作(上面是 photoshop)
这个属性的值(规范和非标准)十分多,-webkit-mask-composite 与规范下的值有所不同,属性值十分多,如下(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 实现鼠标追随镂空成果
回到这里,思考一下🤔,怎么来绘制这样一个图形?
形态是一样的,只是和后面的步骤略微有些差别
首先还是绘制环形突变,能够先绘制锥形突变和环形突变,如下
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)
}
自定义色彩起来是不是更加直观?
四、动画和安利
动画很简略,就是一个有限旋转的线性动画,这个没什么好说的
loading{animation: rotate 1s linear infinite;}
@keyframes rotate{
to{transform: rotate(360deg);
}
}
这样就实现了文章结尾成果
对于线上 demo,这里安利一下我开发的 xy-ui 组件库(目前正在重构中 …),外面 loading
组件就用到了这个实现
https://xy-ui.codelabo.cn
很多乏味的 CSS 小技巧都能够在这个组件库中找到,欢送 star & fork 👏🏻👏🏻👏🏻
五、总结和阐明
以上就是本文的全部内容了,稍显啰嗦,不过也是为了提供更多的思路,上面总结一下实现重点
- 整个实现其实用到了锥形突变和径向突变
- 失常思路是背景绘制出通明锥形突变,而后通过 mask 遮罩裁剪出环形
- 不过这种思路改色彩略微麻烦一点,能够通过 CSS 变量传递,简化代码
- 色彩在背景中不够直观,能够思考将实现细节放到 mask 中
- mask 遮罩合成能够实现图形的合成与裁剪,能够更灵便的布尔运算
- 举荐一下我的组件库 xy-ui,能够学到更多乏味的 CSS 小技巧
最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤,同时也欢送喜爱 CSS 的各位关注我,加我微信XboxYan
,一起交换,共同进步。
欢送关注我的公众号:前端侦探