效果预览
mask详解
mask属性为一系列mask相关属性的缩写,具体如下
在本文中,主要用到以下属性
- mask-image
- mask-mode
- mask-repeat
- mask-size
mask-image
mask-image允许我们为元素添加一张图片作为元素的遮罩层,该图片的透明度(alpha)或亮度(luminance)会影响到元素的可见性。默认情况下,元素对应遮罩层透明部分会变得不可见,该行为可以通过mask-mode改变。
mask-mode
通过该属性改变遮罩层透明度或亮度对元素可见性的影响。取值如下
-
alpha
遮罩层透明部分会使得元素对应区域不可见。
-
luminance
遮罩图像的亮度值会影响元素内容的可见性。遮罩图像中较暗的部分会导致相应的元素内容变得较暗或透明,较亮的部分则保持不受影响。
-
match-source
如果
mask-image的类型为<mask-source>,则表现为luminance。如果mask-image的类型为<image>则表现为alpha
mask-origin
该属性用来设置遮罩层的起点,常用取值如下
- content-box
mask-position: 0 0在内容区域左上角 - padding-box
mask-position: 0 0在内边距区域左上角 - border-box
mask-position: 0 0在边框区域左上角。该值为默认值。
mask-position
该属性用来设置遮罩层相对mask-origin的位置,取值可为1到2个值,当取两个值时分别表示相对mask-origin水平位置和垂直位置的距离。当有缺省值时,默认为center。如
.maskDiv{
mask-position: top; // 相当于mask-position:top center;
}
mask-repeat
当遮罩层大小比元素本身大小小时,可以通过mask-repeat设置遮罩层的重复方式。取值如下
- repeat(相当于repeat repeat) 默认值,遮罩层会被重复以覆盖绘制区域,直到没有更多空间时,最后一个图像将被裁剪掉。
- repeat-x 遮罩层在x轴方向重复。
- repeat-y 遮罩层在x轴方向重复。
- no-repeat 遮罩层不重复
- space(相当于space space) 图像会尽可能地重复,直到没有更多空间时才会裁剪。第一个和最后一个图像会固定在元素的两侧,图像之间的空白会均匀分布。这里借助background-repeat的图来方便理解
-
round(感觉效果和repeat类似,我不是很理解)(相当于round round)
随着允许的空间增加,重复的图像会被拉伸(没有间隙),直到有足够的空间(剩余空间大于等于图像宽度的一半)可以添加另一个图像。当添加下一个图像时,所有当前的图像会被压缩,以腾出空间。例如:一个原始宽度为260像素的图像,重复三次,可能会被拉伸,直到每个重复的宽度为300像素,然后再添加另一个图像。然后它们会压缩到225像素。
这里给出background-repeat文档地址,方便大家查看效果
mask-size
设置遮罩层的大小,用法类似background-size
实现选中图片效果思路图解
如上图,蓝色填充区域的大小其实就是我们选中样式的长宽,红色框框为重复的mask-image。利用mask-mode: alpha,遮罩层非透明的位置可见,透明位置不可见,我们只要设置红色填充区域为透明,即可实现选中样式。
完整代码
html
<div class="container imgContainer">
<div>
<img src="../img/img1.png"/>
</div>
<div>
<img src="../img/img2.png"/>
</div>
<div>
<img src="../img/img3.png"/>
</div>
<div>
<img src="../img/img4.png"/>
</div>
<div class="imgCursor"></div>
</div>
html,
body{
padding: 0;
margin: 0;
height: 100%;
width: 100%;
background: #84a3af;;
}
*{
box-sizing: border-box;
}
.container{
--padding-length: 35px;
--pointer-size: 50px;
padding: var(--padding-length);
display: grid;
width: 100%;
grid-template-columns: repeat(4,1fr); //创建4列布局,每列占容器的4分之一
gap: var(--padding-length);
position: relative;
div{
cursor: pointer;
img{
width: 100%;
height: 100%;
}
}
.imgCursor{
position: absolute;
transition: top 1s,left 1s;
-webkit-mask: conic-gradient(at var(--pointer-size) var(--pointer-size),transparent 75%,blue 75% 100%) 0 0 / calc(100% - var(--pointer-size)) calc(100% - var(--pointer-size));
mask: conic-gradient(at var(--pointer-size) var(--pointer-size),transparent 75%,blue 75% 100%) 0 0 / calc(100% - var(--pointer-size)) calc(100% - var(--pointer-size));
}
}
const imgs = document.querySelectorAll('.imgContainer img');
const imgCursor = document.querySelector('.imgContainer .imgCursor');
imgs.forEach((item)=>{
item.addEventListener('mouseenter',(e) => {
const cursorGap = 5;
const cursorSize = 5;
const img = e.target;
const imgCursorWidth = img.clientWidth + cursorSize * 2 + 2 *cursorGap;
const imgCursorHeight = img.clientHeight + cursorSize * 2 + 2 * cursorGap;
imgCursor.style.setProperty('width',imgCursorWidth + 'px');
imgCursor.style.setProperty('height',imgCursorHeight + 'px');
const left = img.offsetLeft - cursorSize - cursorGap;
const top = img.offsetTop - cursorSize - cursorGap;
imgCursor.style.setProperty('left',left + 'px');
imgCursor.style.setProperty('top',top + 'px');
imgCursor.style.setProperty('border',`${cursorSize}px solid #fff`);
})
})