关于商城物品展示的放大镜效果具体实现起来并不困难,只要掌握了图片放大的具体思路将它转化成公式就可以轻松搞定。下面来谈谈具体实现思路。
在自己的html文件的<body>里边构建好自己的实现区域框架,设置css样式,大致效果如下
这是我调的大致效果至于鼠标事件等效果们在js中具体实现。
在这里我们把左侧被放大区域的块起名为header,右侧放大区域的块起名为show,放大区域选中块起名为hover。
一、重定向鼠标在展示图片区域的坐标
我们需要获取到鼠标在选中区域的坐标,但是通过e.pageX/Y我们获取到的水鼠标在当前文本中的坐标。我们要想得到鼠标在当前放大区域的坐标则需要进行对鼠标坐标的初始化:
//要给展示区域监听mousemove事件,在函数中用传入事件对象e
myaddressX = e.pageX - mybox.offsetLeft;
myaddressY = e.pageY - mybox.offsetTop;
其中的myaddressX/Y分别对应鼠标在放大区域初始化后的横纵坐标。
二、给放大区域的选中块添加边界条件
//定义hover相对于header的position偏移量top和left
var myhoverTop, myhoverLeft;
// 设置hover的top和left为鼠标坐标的(X,Y - hover宽高的一半)
// 当鼠标在header的坐标X,Y小于hover的宽高的一半时重置hover的top和left为0
myaddressX < myhover.offsetWidth / 2
? (myhoverLeft = 0)
: (myhoverLeft = myaddressX - myhover.offsetWidth / 2);
myaddressY < myhover.offsetHeight / 2
? (myhoverTop = 0)
: (myhoverTop = myaddressY - myhover.offsetHeight / 2);
// 当鼠标在header的坐标X,Y大于于(header的宽高-hover的宽高的一半)时重置hover的top和left为(header的宽高 - hover的宽高)
myaddressX > myheader.offsetWidth - myhover.offsetWidth / 2
? (myhoverLeft = myheader.offsetWidth - myhover.offsetWidth)
: (myhoverLeft = myhoverLeft);
myaddressY > myheader.offsetHeight - myhover.offsetHeight / 2
? (myhoverTop = myheader.offsetHeight - myhover.offsetHeight)
: (myhoverTop = myhoverTop);
// 定位hover设置其位置样式
myhover.style.top = `${myhoverTop}px`;
myhover.style.left = `${myhoverLeft}px`;
三、实现show内图片的放大效果
// 设置show内的图片
// show内展示的图片的放大比例就是(show/hover)的比例
// 注意:不可以用百分比设置show内图片的大小,因为设置百分比缩放时缩放的比例是图片相对于show的宽高的比例故而导致并不是相对于图片本身
// 因为我们在这儿要实现的是将header里边hover区域内的图片在show里边放大,故而图片放大后的大小是:header的宽高*放大的比例
// 所以在这里使用背景图片的宽高固定值这样就可以实现相对的放大效果
// 图片放大后的放大的宽高的固定值 = header的宽高 * show相对于hover的放大比例
myshow.style.backgroundSize = `${
(myshow.offsetWidth / myhover.offsetWidth) * myheader.offsetWidth
}px`;
// show内图片的位置是(-1 * (hover相对于header的top,left) * 图片放大比例)
myshow.style.backgroundPositionX = `${-myhoverLeft * (myshow.offsetWidth / myhover.offsetWidth)
}px`;
myshow.style.backgroundPositionY = `${-myhoverTop * (myshow.offsetWidth / myhover.offsetWidth)
}px`;
大致的放大镜效果就可以实现了,在这个效果上我们加上其他的效果就可以实现一个粗略的样品选择与放大展示的效果了!具体代码如下(其中的视频和图片资源可以自行添加):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#box {
width: 500px;
height: 600px;
/* margin: 0 auto; */
position: relative;
}
#header {
width: 500px;
height: 500px;
line-height: 500px;
/* background-image: url("./images/1.jpg"); */
position: relative;
}
#hover {
width: 20%;
height: 20%;
background-color: blue;
opacity: 0.3;
display: none;
position: absolute;
cursor:move;
/* top: 0; */
/* left: 0; */
}
#footer {
width: 500px;
height: 100px;
position: relative;
}
.image {
width: 80px;
height: 80px;
float: left;
margin: 10px 10px;
box-sizing: border-box;
background-size: 100%;
}
#border {
width: 80px;
height: 80px;
border: 2px solid black;
margin: 8px;
display: none;
position: absolute;
top: 0;
}
#show {
width: 800px;
height: 800px;
background-color: #ccc;
display: none;
position: absolute;
top: 0;
left: 550px;
}
</style>
</head>
<body>
<div id="box">
<div id="header" style='background: url("./images/1.jpg");'>
<video id="header-first" src="#" width="100%" height="100%" controls muted autoplay></video>
<div id="hover"></div>
</div>
<div id="footer">
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
<div id="border"></div>
</div>
<div id="show"></div>
</div>
<script>
var mybox = document.getElementById("box"),
myimages = document.getElementsByClassName("image"),
myheader = document.getElementById("header"),
myvideos = document.getElementById("header-first")
myshow = document.getElementById("show"),
myborder = document.getElementById("border");
// 给footer添加图片元素并添加效果
for (var i = 0; i < myimages.length; i++) {
// 给foooter的每一个子元素添加图片
myimages[i].style.backgroundImage = `url(./images/${i + 1}.jpg)`;
myimages[i].setAttribute("nth", i);
// 给footer的子元素添加点击事件
myimages[i].onclick = function () {
var j = parseInt(this.getAttribute("nth"));
// 点击任意一个子元素删除header的子元素video
myvideos.remove();
// 同步header与选中footer的背景
myheader.style.backgroundImage = `url(./images/${j + 1}.jpg)`;
// 显示选中图片的边框
myborder.style.display = "block";
myborder.style.left = `${j * 100}px`;
};
}
var myhover = document.getElementById("hover");
myheader.addEventListener("mousemove", function (e) {
// 获取鼠标在myheader中的坐标
myaddressX = e.pageX - mybox.offsetLeft;
myaddressY = e.pageY - mybox.offsetTop;
// console.log(myaddressX,myaddressY);
// console.log(myheader.offsetWidth);
var myhoverTop, myhoverLeft;
// 设置hover的top和left为鼠标坐标的(X,Y - hover宽高的一半)
// 当鼠标在header的坐标X,Y小于hover的宽高的一半时重置hover的top和left为0
myaddressX < myhover.offsetWidth / 2
? (myhoverLeft = 0)
: (myhoverLeft = myaddressX - myhover.offsetWidth / 2);
myaddressY < myhover.offsetHeight / 2
? (myhoverTop = 0)
: (myhoverTop = myaddressY - myhover.offsetHeight / 2);
// 当鼠标在header的坐标X,Y大于于(header的宽高-hover的宽高的一半)时重置hover的top和left为(header的宽高 - hover的宽高)
myaddressX > myheader.offsetWidth - myhover.offsetWidth / 2
? (myhoverLeft = myheader.offsetWidth - myhover.offsetWidth)
: (myhoverLeft = myhoverLeft);
myaddressY > myheader.offsetHeight - myhover.offsetHeight / 2
? (myhoverTop = myheader.offsetHeight - myhover.offsetHeight)
: (myhoverTop = myhoverTop);
// console.log(myaddressX<myhover.offsetWidth/2);
// 定位hover设置其位置样式
myhover.style.top = `${myhoverTop}px`;
myhover.style.left = `${myhoverLeft}px`;
// 设置show内的图片
// show内展示的图片的放大比例就是(show/hover)的比例
// 注意:不可以用百分比设置show内图片的大小,因为设置百分比缩放时缩放的比例是图片相对于show的宽高的比例故而导致并不是相对于图片本身
// 因为我们在这儿要实现的是将header里边hover区域内的图片在show里边放大,故而图片放大后的大小是:header的宽高*放大的比例
// 所以在这里使用背景图片的宽高固定值这样就可以实现相对的放大效果
// 图片放大后的放大的宽高的固定值 = header的宽高 * show相对于hover的放大比例
myshow.style.backgroundSize = `${
(myshow.offsetWidth / myhover.offsetWidth) * myheader.offsetWidth
}px`;
// show内图片的位置是(-(hover相对于header的top,left) * 图片放大比例)
myshow.style.backgroundPositionX = `${-myhoverLeft * (myshow.offsetWidth / myhover.offsetWidth)
}px`;
myshow.style.backgroundPositionY = `${-myhoverTop * (myshow.offsetWidth / myhover.offsetWidth)
}px`;
// console.log((myshow.offsetWidth / myhover.offsetWidth));
});
// myshow.style.display = "block";
// myshow.style.backgroundImage = myheader.style.backgroundImage;
// alert(myheader.style.backgroundImage);
// 鼠标进入header的效果
myheader.onmouseenter = function () {
// 通过border是否显示判断用户是否选择图片
if (myborder.style.display == "block") {
// 当用户选择过图片后显示hover的选中效果和show的放大效果
myhover.style.display = "block";
myshow.style.display = "block";
// alert(myheader.style.backgroundImage);
// 设置show内的图片为header内的图片
myshow.style.backgroundImage = myheader.style.backgroundImage;
// alert(myheader.style.backgroundImage);
}
};
// 鼠标离开header的效果
myheader.onmouseleave = function () {
myhover.style.display = "none";
myshow.style.display = "none";
};
// 遗留问题:myheader的背景图片在没有切换的时候值为空
// console.log(myheader.style.backgroundImage);
// myshow.style.backgroundImage = myheader.style.backgroundImage;
</script>
</body>
</html>