依然是项目需求,图片展示在固定窗口(div)内,窗口内要求可以放大缩小、可以拖拽。
以下代码在Chrome浏览器下测试通过,谢谢伟大的甲方。
demo在线展示:https://knimet.github.io/js-zoom-drag-in-a-window/pic.html
demo地址:https://github.com/knimet/js-zoom-drag-in-a-window
页面代码很简单,div内放置一个img。我这里设置的img初始大小已经大于div了,如果有需要可以设置和div大小相同,即没有放缩:
<div class="pic" style="height:600px;width:600px;overflow:hidden;margin:0 auto">
<img style="display:block;" id="pic" width=1000px height=1000px;>
</div>
接下来是js的部分
【拖拽】
拖拽的需求很明确,图片比外部的div大,而且div设置了overflow:hidden,自然无法完全显示,需要通过拖拽浏览图片的其他部分。基本流程为:鼠标点下,拖拽开始-鼠标移动,图片随之拖拽-鼠标抬起,拖拽结束。
拖拽的原理用一句话概括为:根据鼠标的位置设置图片的位置。在本次需求中,通过设置外边距/负外边距调整图片位置。
(1) 获取元素
var div1 = document.getElementById("pic");
(2) 对元素设置鼠标按下事件
div1.onmousedown = function(ev){
}
(3)初始化偏移量。图片偏移初始为0,因此两个方向的偏移均设置为0.
var offX = 0,offY = 0;
(4) 事件内的处理逻辑如下:记录鼠标点击位置distanceX,distanceY。根据鼠标移动后的位置newX,newY,计算移动的距离,即移动后的位置和移动前位置的差:x1=newX-distanceX,y1=newY-distanceY。计算后得到的x1,y1即为本次鼠标移动的距离。图片被鼠标拖拽,意味着图片随着鼠标的移动而移动,因此图片移动的距离也为x1,y1。
div1.onmousedown = function(ev){
ev.preventDefault(); //阻止浏览器动作,有些浏览器试图拖拽图片的时候,是会把图片单独到一个页面来查看的。
var oevent = ev || event; //兼容性处理
var distanceX = oevent.clientX; //记录鼠标点击x位置
var distanceY = oevent.clientY; //记录鼠标点击y位置
document.onmousemove = function(ev){ //当鼠标点击后,才对document设置mousemove事件
var oevent = ev || event;
x1 = oevent.clientX - distanceX;//oevent.clientX是鼠标移动到的x位置,oevent.clientX-distanceX是移动的距离
y1 = oevent.clientY - distanceY;
distanceX = oevent.clientX; //更新distanceX的位置信息。这一步非常重要非常重要非常重要,因为mousemove事件在鼠标移动时触发,而不是鼠标停止移动后触发
distanceY = oevent.clientY;
div1.style.marginLeft = (x1 + offX) + "px"; //若x1为正,则鼠标向右移动,设置图片的margin-left为正,向右偏移;为负同理向左偏移。
div1.style.marginTop = (y1+ offY) +"px"; //offX和offY为前一次的偏移,本次移动是在前一次的基础上发生的,要加上偏移值才是鼠标本次移动后图片的位置。
offX = x1+offX; //记录此时图片的偏移位置
offY = y1+offY;
};
document.onmouseup = function(){ //鼠标抬起后,就取消document的mousemove事件
document.onmousemove = null;
};
}
【放缩】
放缩的详细需求是,鼠标在div框内滚动滚轴,向前滚动为放大,向后滚动为缩小,div框内滚轴的滚动不带动页面上下滚动。
处理逻辑:对页面设置鼠标滚轴事件,若事件发生在图片上,则改变图片的宽和高,形成放缩效果。
兼容性处理:
if(document.addEventListener){
document.addEventListener('DOMMouseScroll',scrollFunc,false);
}//W3C
window.onmousewheel=document.onmousewheel=scrollFunc;//IE/Opera/Chrome
监听事件:
function scrollFunc(e) {
if(e.target!=document.getElementById("pic")){ //如果事件没发生在pic上,不执行该函数。
return;
}
var oImg = document.getElementById("pic");
var direct = 0;
e = e || window.event;
if (e.wheelDelta) { //IE/Opera/Chrome
if (e.wheelDelta > 0) { //大于0,向前滚,放大
oImg.width = oImg.width * 1.1;
oImg.height = oImg.height * 1.1;
} else { //否则是缩小
oImg.width = oImg.width / 1.1;
oImg.height = oImg.height / 1.1;
}
} else if (e.detail) { //Firefox
if (e.detail > 0) {
oImg.width = oImg.width * 1.1;
oImg.height = oImg.height * 1.1;
} else {
oImg.width = oImg.width / 1.1;
oImg.height = oImg.height / 1.1;
}
}
if(e.preventDefault) { //阻止浏览器自身事件
e.preventDefault();
e.stopPropagation();
}else{
e.returnValue = false;
e.cancelBubble = true;
}
}
【放缩鼠标所在位置】
这个先空着。
其实结合前面两个就可以实现了,根据鼠标位置,再根据鼠标滚轴的方向,放大或缩小图片的width和height,再设置图片的margin保证图片放大/缩小后鼠标所在的位置依旧处于可视范围内原位置。
参考资料:
http://www.jb51.net/article/43049.htm