前言
需求要求 实现类似的图片预览效果,ui给出的图片预览周围是会渐隐的,并且图片可以拖动。
一开始的想法是背景图中间这一部分是渐渐透明的,然后图片作为底层放在背景图的下面,然后点击事件进行穿透,图片照样能够拖动,但是ui不给切,那就没办法了,只能通过研究一下css能否解决
实现思路
了解过 ps 的可能会比较清楚,再 ps 当中存在蒙版这个概念,也就是定义一个蒙版,将这个蒙版覆盖在一张图片上面,只有蒙版不为透明的部分,这张图片才是可见的。比方说一张图片长这样:
在我们为他添加了这样的蒙版以后
再ps蒙版中黑色部分表示隐藏图片,白色部分代表展示图片,我们再给他添加一个白底,最后的效果为:
这个效果是不是就和我们想要实现的效果有一点点接近,我们只需要画出一个由黑到白的渐变蒙版
这样边缘部分就会展现底下的白底,也就实现了渐隐的效果。
通过css实现蒙版
那么再css的属性当中,有没有类似于蒙版的属性呢,答案是有的,来了解一下 mask-image (遮罩) 属性
所谓遮罩(mask-image),就是原始图片只显示遮罩图片非透明的部分,在PS中称为“蒙版”。类似于现实世界中一张A4卡纸剪了个洞,我们可以通过洞看卡纸后面的物体,这里卡纸相当于遮罩层,只不过洞是遮罩层不透明的部分,其他部分是遮罩层透明的部分,与我们想象中的正好相反。
mask-image 的 值可以取各种渐变色,或者图片,使用的方法和ps蒙版是相同的,存在颜色的部分会被展示,透明的部分会被隐藏
我们可以使用渐变色或者png图片来实现遮罩的效果,比方说存在一张图片
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
body {
display: flex;
position: relative;
align-items: center;
justify-content: center;
background-color: antiquewhite;
}
#box1{
position: relative;
width: 1000px;
height: 1000px;
-webkit-mask-image: radial-gradient(#FFF 5%, transparent 50%);
-webkit-mask-size: 100% 100%;
}
#box2{
width: 1000px;
height: 1000px;
background: url('./img/pet.jpg');
background-size: 100% 100%;
position: absolute;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
</div>
</div>
</body>
</html>
使用 radial-gradient(#FFF 5%, transparent 50%); 就可以构造一个渐隐的圆,当然你也可以使用线性渐变或者其他渐变属性,这些都是一样的,但是最终遵守的就是根据 mask-image 的特点,透明部分将不会展示,白色(有颜色)部分就会展示,最后得到:
当然也可以使用 png 图片,我们都知道,png 格式的图片是支持存在透明的部分的,将这个特点用在 mask-image 这个属性上面,就可以自定义需要隐藏的部分了。
我现在自己画了一张这样的 png 图片
利用这张图片就可以实现这样的效果
-webkit-mask-image: url('./img/zz2.png');
我们会发现,上面我们所有的 mask-image 属性都是作用在 box1 上的,这样就实现了无论内部的 box2 怎么移动,对应的部分就是会被隐藏,我们可以利用dom操作给box2加上拖拽试试。
这样就成功实现了我们想要的效果。
完整代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
body {
display: flex;
position: relative;
align-items: center;
justify-content: center;
background-color: antiquewhite;
/* background: url('./img/bg.jpeg'); */
background-size: 100% 100%;
}
.aa {
position: absolute;
top: 20px;
left: 20px;
}
.bb {
position: absolute;
top: 20px;
left: 20px;
}
#box1{
position: relative;
width: 1000px;
height: 1000px;
/* -webkit-mask-image: linear-gradient(
90deg,
rgb(227,227,227),
90%,
transparent);
-webkit-mask-image: linear-gradient(
0deg,
rgb(227,227,227),
90%,
transparent); */
mask: radial-gradient(#000 5%, transparent 70%);
-webkit-mask-image: radial-gradient(#FFF 5%, transparent 50%);
-webkit-mask-image: url('./img/zz2.png');
-webkit-mask-size: 100% 100%;
}
#box2{
width: 1000px;
height: 1000px;
background: url('./img/pet.jpg');
background-size: 100% 100%;
position: absolute;
}
</style>
<script type="text/javascript">
window.onload = function(){
/*
* 拖拽box1的元素
* - 拖拽的流程
* 1.当鼠标在被拖拽的元素上按下时开始拖拽 onmousedown
* 2.当鼠标移动时被拖拽的元素跟随鼠标移动 onmousemove
* 3.当鼠标松开时被拖拽的对象固定到当前位置 onmouseup
*/
var img01 = document.getElementById("box2")
drag(img01);
};
/*
* 提取一个专门用来设置拖拽的函数
* 参数,开启拖拽的元素
*/
function drag(obj){
obj.onmousedown = function(event){
//设置box1捕获所有鼠标按下的事件
/*
* setCapture()
* - 只有IE支持,但是在火狐中调用时不会报错
* 而如果使用chrome调用,会报错
*/
obj.setCapture && obj.setCapture();
event = event ||window.event
//div的偏移量,鼠标.clientX-元素.offsetLeft
//div的偏移量,鼠标.clientY-元素.offsetTop
var ol = event.clientX -obj.offsetLeft;
var ot = event.clientY - obj.offsetTop;
//为document绑定一个onmousemove事件
document.onmousemove = function(event){
event = event ||window.event
//当鼠标移动时被拖拽的元素跟随鼠标移动 onmousemove
//获取鼠标的坐标
var left = event.clientX-ol;
var top = event.clientY-ot;
//修改box1的位置
obj.style.left = left+"px";
obj.style.top = top+"px";
};
//为元素绑定一个鼠标松开事件
document.onmouseup = function(){
//当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
//取消document的onmousemove事件
document.onmousemove = null;
document.onmouseup = null;
//当鼠标松开时,取消对事件的捕获
obj.releaseCapture && obj.releaseCapture();
};
/*
* 当我们拖拽一个网页的内容时,浏览器会默认去搜索引擎中搜索内容
* 此时会导致拖拽功能的异常,这是浏览器提供的默认行为
* 如果不希望发生这个行为,则可以通过return false来取消默认行为
*/
return false;
};
};
</script>
</head>
<body>
<div id="box1">
<div id="box2">
</div>
</div>
</body>
</html>