先来看看效果图:
需要一些位置计算..
参考https://www.cnblogs.com/wang715100018066/p/13607330.html 的图片详情效果。。显然没有完全一样
但是凑合吧 后面在优化
比较关键的api还是之前计算图片位置的文章 相关的api - getBoundingClientRect
直接上代码吧:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
.priview {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
transition: opacity 0.3s;
will-change: opacity;
cursor: zoom-out;
display: none;
opacity: 0;
background: rgba(0, 0, 0, 0.8) !important;
}
.priview.show {
display: block;
opacity: 1;
}
.priview img {
position: absolute;
width: 500px;
transition: transform 0.3s cubic-bezier(0.2, 0, 0.2, 1) !important;
}
#content {
margin: auto;
text-align: center;
border: 1px solid gainsboro;
}
#content img {
margin: 50px;
}
</style>
<body>
<div id="content">
<img
src="http://biaoblog.run:3000/uploads/1648023950605.gif"
width="400px"
alt=""
id="myImg"
/>
</div>
<div class="priview">
<img class="priviewImg" src="" alt="" />
</div>
</body>
<script>
const getDom = (dom) => {
return document.querySelector(dom);
};
let imgDom = getDom("#myImg");
let priview = getDom(".priview");
let str = "";
for (let i = 0; i < 10; i++) {
str += `<img
src="http://biaoblog.run:3000/uploads/1648023950605.gif"
width="400px"
alt=""
onclick="showPriview(event)"
/>`;
}
document.querySelector("#content").innerHTML = str;
function showPriview(e) {
// 1.先渲染
let rectObject = e.target.getBoundingClientRect();
let priviewStyle = `style="left:${rectObject.left}px;top:${rectObject.top}px;transform:scale(1.02945) translate3d(0px,0px,0);"`;
priview.classList.add("show");
priview.innerHTML = `<img class="priviewImg" src="${imgDom.src}" ${priviewStyle}/>`;
document.body.style.overflow = "hidden";
// 2.计算垂直居中的偏移值 进行动画效果
let priviewImg = getDom(".priviewImg");
let priviewImgObject = priviewImg.getBoundingClientRect();
let windowWidth = document.body.clientWidth;
let windowHeight = document.documentElement.clientHeight; //这里获取可见高度 不能用body.clientHeight 如果有scroll就不准了 只考虑一屏的高度
let leftOfest =
(windowWidth - priviewImg.clientWidth) / 2 - priviewImgObject.left;
let topOfest =
(windowHeight - priviewImg.clientHeight) / 2 - priviewImgObject.top;
priviewImg.style.transform = `scale(1.02945) translate3d(${leftOfest}px,${topOfest}px,0)`;
let priviewShow = getDom(".priview.show");
let priviewImgShow = getDom(".priview.show .priviewImg");
if (priviewShow && priviewImgShow) {
priviewShow.onclick = () => {
priviewImgShow.style.transform = `scale(1.02945) translate3d(0px,0px,0)`;
priviewImgShow.style.background = "transparent";
setTimeout(() => {
document.body.style.overflow = "scroll";
priviewShow.classList.remove("show");
}, 280);
};
}
}
</script>
</html>
后续:进行了一波优化:其实就是加了一个透明度的动画效果....
效果图:
上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
.priview {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
transition: opacity 0.5s;
will-change: opacity;
cursor: zoom-out;
display: none;
background: rgba(0, 0, 0, 0.8) !important;
opacity: 0;
}
.priview.show {
display: block;
}
.priview img {
position: absolute;
width: 500px;
transition: transform 0.3s cubic-bezier(0.2, 0, 0.2, 1) !important;
}
#content {
margin: auto;
text-align: center;
border: 1px solid gainsboro;
}
#content img {
margin: 50px;
}
</style>
<body>
<div id="content"></div>
<div class="priview">
<img class="priviewImg" src="" alt="" />
</div>
</body>
<script>
const getDom = (dom) => {
return document.querySelector(dom);
};
let imgDom = getDom("#myImg");
let priview = getDom(".priview");
let str = "";
for (let i = 0; i < 10; i++) {
str += `<img
src="http://biaoblog.run:3000/uploads/1619422830443.jpg"
width="400px"
alt=""
onclick="showPriview(event)"
id="myImg"
/>`;
}
const sleep = async (time) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, time);
});
};
document.querySelector("#content").innerHTML = str;
async function showPriview(e) {
priview.classList.add("show");
await sleep(10);
priview.style.opacity = 1;
// 1.先渲染
let rectObject = e.target.getBoundingClientRect();
let priviewStyle = `style="left:${rectObject.left}px;top:${rectObject.top}px;transform:scale(1.02945) translate3d(0px,0px,0);"`;
priview.innerHTML = `<img class="priviewImg" src="${e.target.src}" ${priviewStyle}/>`;
document.body.style.overflow = "hidden";
// 2.计算垂直居中的偏移值 进行动画效果
let priviewImg = getDom(".priviewImg");
let priviewImgObject = priviewImg.getBoundingClientRect();
let windowWidth = document.body.clientWidth;
let windowHeight = document.documentElement.clientHeight; //这里获取可见高度 不能用body.clientHeight 如果有scroll就不准了 只考虑一屏的高度
let leftOfest =
(windowWidth - priviewImg.clientWidth) / 2 - priviewImgObject.left;
let topOfest =
(windowHeight - priviewImg.clientHeight) / 2 - priviewImgObject.top;
priviewImg.style.transform = `scale(1.02945) translate3d(${leftOfest}px,${topOfest}px,0)`;
let priviewShow = getDom(".priview.show");
let priviewImgShow = getDom(".priview.show .priviewImg");
e.target.style.opacity = 0;
if (priviewShow && priviewImgShow) {
priviewShow.onclick = async () => {
priviewImgShow.style.transform = `scale(1.02945) translate3d(0px,0px,0)`;
await sleep(300);
e.target.style.opacity = 1;
document.body.style.overflow = "scroll";
priview.style.opacity = 0;
console.log("time1");
await sleep(300);
priviewShow.classList.remove("show");
};
}
}
</script>
</html>