CSS遮罩合成实现带圆角的环形loading动画

2023-05-0808:20:06WEB前端开发Comments512 views字数 4002阅读模式

先不考虑动画,其实就是这样一个图形文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

那么,如何来绘制呢?下面花两分钟一起看看吧文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

一、CSS实现思路

首先,看到这环形逐渐消失的效果,也就是透明度渐变的效果,肯定要联想到锥形渐变文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

通过锥形渐变,可以很轻松的实现这样一个效果,透明到纯色的渐变文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

效果如下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

然后,整体是一个环形,可以通过径向渐变配合mask遮罩实现文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

原理是这样的文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

还有一个圆角,可以直接用径向渐变实现文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

其实就是两个相同颜色的渐变叠加到一起形成的,如下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

所以完整代码就是文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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设计问题。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

比如,我如果需要改变 loading 的颜色,需要改变两个地方文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

很明显,这样的实现不太符合 DRY(Don't Repeat Yourself)原则。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

有一个比较简单思路可以用 CSS 变量来传递文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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%);
}

这样每次都只需要改变一个变量就行了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

loading.red{
  --color: red;
}

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

loading.red{
  background: red;
}

如果要实现这样的效果,就需要将绘制部分全部在mask遮罩中完成,背景只是展示而已。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

那么,如何通过mask遮罩实现这样的图形呢?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

mask遮罩其实也和 CSS 背景差不多,只是多了一些图形合成操作,其实就是布尔运算,也就是mask-composite文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

/* Keyword values */
mask-composite: add; /* 叠加(默认) */
mask-composite: subtract; /* 减去,排除掉上层的区域 */
mask-composite: intersect; /* 相交,只显示重合的地方 */
mask-composite: exclude; /* 排除,只显示不重合的地方 */

相信在很多图形设计软件中都见到类似的操作(下面是 photoshop)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

这个属性的值(标准和非标准)非常多,-webkit-mask-composite 与标准下的值有所不同,属性值非常多,如下(chorme 、safari 支持)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

-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; /*只显示不重合的地方*/

回到这里,思考一下?,怎么来绘制这样一个图形?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

形状是一样的,只是和前面的步骤稍微有些差异文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

首先还是绘制环形渐变,可以先绘制锥形渐变和环形渐变,如下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

但是这样两个渐变会叠加在一起文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

其实我们需要是只显示两者重叠的部分,也就是交叉区域,这个特性在mask-composite中对应的就是destination-in或者source-in文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

效果如下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

然后是那个圆角,和上面绘制一样文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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;
}

如果直接这样叠加,会变成这样文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

其实这是因为source-in导致的,三个图形,最后只显示了三者重叠的区域。但是我们现在需要的是最上面的圆角直接叠加就行了,不需要裁剪,可以用到source-over文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

效果如下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

下面是完整代码文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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;
}

如果要换颜色,直接更换背景就可以了,还可以是渐变文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

自定义颜色起来是不是更加直观?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

四、动画和安利

动画很简单,就是一个无限旋转的线性动画,这个没什么好说的文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

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

这样就实现了文章开头效果文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

关于线上 demo,这里安利一下我开发的xy-ui组件库(目前正在重构中...),里面 loading 组件就用到了这个实现文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

https://xy-ui.codelabo.cn文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

很多有趣的 CSS 小技巧都可以在这个组件库中找到,欢迎 star & fork ??????文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

CSS遮罩合成实现带圆角的环形loading动画文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

五、总结和说明

以上就是本文的全部内容了,稍显啰嗦,不过也是为了提供更多的思路,下面总结一下实现重点文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html

  1. 整个实现其实用到了锥形渐变和径向渐变
  2. 正常思路是背景绘制出透明锥形渐变,然后通过 mask 遮罩裁剪出环形
  3. 不过这种思路改颜色稍微麻烦一点,可以通过 CSS 变量传递,简化代码
  4. 颜色在背景中不够直观,可以考虑将实现细节放到 mask 中
  5. mask遮罩合成可以实现图形的合成与裁剪,可以更灵活的布尔运算
  6. 推荐一下我的组件库 xy-ui,可以学到更多有趣的 CSS 小技巧
文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/38751.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/gcs/38751.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定