那么如何绘制一个镂空的圆呢?先介绍一种方法。
其实很简单,只需要一个足够大的投影就可以了,原理如下:

这里可以用伪元素::before来绘制,结构更加精简。用代码实现就是:
.wrap::before{
content:‘’;
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
left: 50%;
top: 50%;
transform: translate(-50%,-50%); /默认居中/
box-shadow: 0 0 0 999vw rgba(0, 0, 0, .5); /足够大的投影/
}
可以得到这样的效果:

二、借助 CSS 变量传递鼠标位置
按照以往的经验,可能会在 js 中直接修改元素的 style 属性,类似这样
img.addEventListener(‘mousemove’, (ev) => {
img.style.left = ‘…’;
img.style.top = ‘…’;
})
但是这样交互与业务逻辑混杂在一起,不利于后期维护。其实,我们只需要鼠标的坐标,在 CSS 中也能完全实现跟随的效果。
这里借助 CSS 变量,那一切就好办了!假设鼠标的坐标是 [–x,–y](范围是[0, 1]),那么遮罩的坐标就可以使用 calc计算了。
.wrap::before{
left: calc(var(–x) * 100%);
top: calc(var(–y) * 100%);
}
然后鼠标坐标的获取可以使用 JS 来计算,也比较容易,如下:
img.addEventListener(‘mousemove’, (ev) => {
img.style.setProperty(‘–x’, ev.offsetX / ev.target.offsetWidth);
img.style.setProperty(‘–y’, ev.offsetY / ev.target.offsetHeight);
})
这样,半透明效果的镂空效果就完成了。

完整代码可以访问:https://codepen.io/xboxyan/pen/VwzRaNZ
三、渐变也能实现半透明的效果
除了上述阴影扩展的方式,CSS 径向渐变也能实现这样的效果。
绘制一个从透明到半透明的渐变,如下:
.wrap::before{
content: ‘’;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: radial-gradient( circle at center, transparent 50px, rgba(0,0,0,.5) 51px);
}
可以得到这样的效果:

然后,把鼠标坐标映射上去就可以了。从这里就可以看出 CSS 变量的好处,无需修改 JS,只需要在CSS中修改渐变中心点的位置就可以实现了
.wrap::before{
background: radial-gradient( circle at calc(var(–x) * 100% ) calc(var(–y) * 100% ), transparent 50px, rgba(0,0,0,.5) 51px);
}

四、背景模糊的效果尝试
CSS 中有一个专门针对背景(元素后面区域)的属性:backdrop-filter。
backdrop-filter链接:https://developer.mozilla.org/zh-CN/docs/Web/CSS/backdrop-filter
使用方式和 filter完全一致!
backdrop-filter: blur(10px);
下面是 MDN 中的一个示意效果:

backdrop-filter是让当前元素所在区域后面的内容模糊,要想看到效果,需要元素本身半透明或者完全透明;而filter是让当前元素自身模糊。
有兴趣的可以查看这篇文章:CSS backdrop-filter简介与苹果iOS毛玻璃效果 « 张鑫旭-鑫空间-鑫生活 (zhangxinxu.com)
文章链接:https://www.zhangxinxu.com/wordpress/2019/11/css-backdrop-filter/
需要注意的是,这种模糊与背景的半透明度没有任何关系,哪怕元素本身是透明的,仍然会有效果。例如下面是去除背景后的效果 ,整块都是模糊的。

如果直接运用到上面的例子会怎么样呢?
1. 阴影实现
在上面第一个例子中添加 backdrop-filter
.wrap::before{
content:‘’;
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
left: 50%;
top: 50%;
transform: translate(-50%,-50%); /默认居中/
box-shadow: 0 0 0 999vw rgba(0, 0, 0, .5); /足够大的投影/
backdrop-filter: blur(5px)
}
得到效果如下:

可以看到圆形区域是模糊的,正好和希望的效果相反。其实也好理解,只有圆形区域才是真实的结构,外面都是阴影,所以最后作用的范围也只有圆形部分。
2. 渐变实现
现在在第二个例子中添加 backdrop-filter
.wrap::before{
content: ‘’;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: radial-gradient( circle at calc(var(–x) * 100% ) calc(var(–y) * 100% ), transparent 50px, rgba(0,0,0,.5) 51px);
backdrop-filter: blur(5px)
}`
效果如下:

已经全部都模糊了,只是圆形区域外暗一些。由于::before的尺寸占据整个容器,所以整个背后都变模糊了,圆形外部比较暗是因为半透明渐变的影响。
总之还是不能满足我们的需求,需要寻求新的解决方式。
五、CSS MASK 实现镂空
与其说是让圆形区域不模糊,还不如说是把那块区域给镂空了。就好比之前是一整块磨砂玻璃,然后通过 CSS MASK 打了一个圆孔,这样透过圆孔看到后面肯定是清晰的。
可以对第二个例子稍作修改,通过径向渐变绘制一个透明圆,剩余部分都是纯色的遮罩层,示意如下:

用代码实现就是
.wrap::before{
content: ‘’;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
-webkit-mask: radial-gradient( circle at calc(var(–x, .5) * 100% ) calc(var(–y, .5) * 100% ), transparent 50px, #000 51px);
background: rgba(0,0,0,.3);
backdrop-filter: blur(5px)
}
这样就实现了文章开头的效果:

完整代码可以查看:https://codepen.io/xboxyan/pen/porpoXJ
六、CSS MASK COMPOSITE 实现更丰富的镂空效果
除了使用径向渐变绘制遮罩层以外,还可以通过 CSS MASK COMPOSITE(遮罩合成)的方式来实现。
CSS MASK COMPOSITE 链接:https://developer.mozilla.org/en-US/docs/Web/CSS/mask-composite
标准关键值如下(firefox支持):
/* Keyword values */
mask-composite: add; /* 叠加(默认) */
mask-composite: subtract; /* 减去,排除掉上层的区域 */
mask-composite: intersect; /* 相交,只显示重合的地方 */
mask-composite: exclude; /* 排除,只显示不重合的地方 */
遮罩合成是什么意思呢?可以类比 photoshop 中的形状合成,几乎是一一对应的。

-webkit-mask-composite 与标准下的值有所不同,属性值非常多,如下(chorme 、safari 支持)
-webkit-mask-composite 链接:https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-mask-composite
-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; /只显示不重合的地方/
是不是一脸懵?这里做了一个对应的效果图,如果不太熟练,使用的时候知道有这样一个功能,然后对着找就行了。

最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-acPndPpQ-1715317212791)]
[外链图片转存中…(img-fGyRey6c-1715317212791)]
[外链图片转存中…(img-4wW7OJmV-1715317212791)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

被折叠的 条评论
为什么被折叠?



