Vue中js+css鼠标悬停拖动、移动小图片,大图片也移动

效果图:

页面代码:

            <div class="rightcon" id="box_BigImg" >
				 	<img :src="url" />   //主要显示的大图片
			</div> 
			<div class="leftcon" id="left">
				<img :src="url" />  //右下角小图
				<div class="slide_box" id="box"></div>  //鼠标移动的图层
			</div>

记得在data中定义变量url(图片路径)

css:

#box_BigImg{
	width: 70%;
	height: 95%;
	position: relative;
	margin: auto auto;
	box-shadow: 3px 3px 10px 0 #111111; /*给图片施加阴影效果 */
}
.leftcon {
width: 170px;
height: 170px;
bottom: 0;
right: 0;
position: absolute;
margin: 10px 10px;
box-shadow: 3px 3px 10px 0 #111111; /*给图片施加阴影效果 */
-webkit-box-shadow: 3px 3px 10px 0 #111111; /*兼容性处理*/
-moz-box-shadow: 3px 3px 10px 0 #111111;
}
.leftcon img {
width: 100%;
height: 100%;
position: relative;
z-index: 999;
}
.leftcon .slide_box {
display: none; /*将小方块盒子隐藏*/
position: absolute;
z-index: 9999;
top: 0;
left: 0;
width: 85px;
height: 85px;
background: #000;
opacity: 0.3;
cursor: move; /*改变鼠标的形状*/
}
.rightcon {
/*display: none; 将右边div隐藏*/
width: 100%;
height: 100%;
/*margin-top: 100px;*/
/*float: left;*/
overflow: hidden;
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.rightcon img {
width: 200%;
height: 200%;
position: absolute;
left: 0px;
top: 0px;
}

js:

        var leftone = document.getElementById('left');
		var rightone = document.getElementById('box_BigImg');
		var box = document.getElementById('box');
		var rimg = rightone.getElementsByTagName("img")[0];
		function getPosition(e){ //这里的参数e就是代表event
			 //首先我们要去判断事件源,获取事件源,也就是e
			 var e=e||window.event; //实现兼容
			 //理解:
			 //这个表达式写全是这样:var e=event?event||window.event;
			 //如果存在event,那么var e=event;而如果不存在event,
			 //那么var e=window.event.那么可以看出确实能实现兼容
			 var top = e.clientY-leftone.offsetTop-box.offsetHeight/2; 
			 //计算小图容器里的鼠标坐标(要减去最外层的偏移)
			 var left = e.clientX-leftone.offsetLeft-box.offsetWidth/2;
			 //这里为什么除以2?是因为我们不除以2的话,事件源也就是鼠标就在这个小滑块的的右下角,并不美观
			 //我们要让鼠标位于滑块的中心,所以宽高各减去一半
			 
			  //边界判断
			  //获取小滑块最大纵向移动距离
			  var maxtop = leftone.offsetHeight - box.offsetHeight; 
			  //获取小滑块最大横向移动距离
			  var maxleft = leftone.offsetWidth - box.offsetWidth; 
			  var mintop = 0; //获取小滑块最小纵向移动距离
			  var minleft = 0; //获取小滑块最大纵向移动距离
			  var mvtop; //定义小滑块的纵向移动距离
			  var mvleft; //定义小滑块的横向移动距离
			  // 判断
			  if (top<mintop) {
			  box.style.top = mintop + "px";
			   mvtop = mintop;
			    //理解:
				 //top是鼠标到浏览器的垂直距离-左边div顶部到浏览器的垂直距离-小滑块的高度的一半。
				 //那么现在鼠标在小滑块的中心,也就是说,top就等于小滑块的顶部到左边div的垂直距离
				 //如果top<0,就是说小滑块和左边div顶部重合,就让小滑块的top值为0,即鼠标继续向上移动,
				 //小滑块不在移动,从而让小滑块的移动范围不能超过左边div的宽高范围
				 //下方同理
			  }else if(top>maxtop){
			   box.style.top = maxtop + "px";
			   mvtop = maxtop;
			 //如果top>maxtop,就是说小滑块和左边div底部重合,就让小滑块的top值为maxtop,
			 //即鼠标继续向下移动,小滑块不在移动,从而让小滑块的移动范围不能超过左边div的宽高范围
			  }else{
			   box.style.top = top + "px";
			   mvtop = top;
			   //不超过边界,则小滑块的垂直移动距离就等于top,即小滑块的顶部到左边div的垂直距离
			  }
			  if(left<minleft){
			   box.style.left = minleft + "px";
			   mvleft = minleft
			  }else if(left>maxleft){
			   box.style.left = maxleft + "px";
			   mvleft = maxleft
			  }else{
			   box.style.left = left + "px";
			   mvleft = left;
			  }
			 //因为右边div的图片是左边div的图片的两倍,而左边div和右边div都是小滑块的宽高的两倍,
			 //而要让右边div放大左边的小滑块的包围图片,所以右边大图的定位坐标是小滑块的两倍,这样才能进行映射
			 //右侧图片跟着运动:左侧小滑块移动多少,右侧跟着移动他的2倍即可
			  rimg.style.top = -mvtop*10 + "px";
			  rimg.style.left = -mvleft*14 + "px";
		}
		//鼠标移动效果
		leftone.onmousemove = function(e){
			 this.showmyCanvas=false
			 var e=e||window.event; //判断事件源
			 box.style.display = "block";
			 getPosition(e);
			 rightone.style.display = "block";
		}
		leftone.onmouseenter = function(e){
			this.showmyCanvas = false
			console.log(this.showmyCanvas)
		}
		//鼠标移出效果
		leftone.onmouseleave = function(e){
			this.showmyCanvas=true
			var e=e||window.event; //判断事件源
			box.style.display = "none";
			//rightone.style.display = "none"; //鼠标移出后大图隐藏
		}

优化后:

(把原图的大小不改变显示在div中,超出的部分隐藏,右下角鼠标移动小图时,大图移动位置显示指定位置)

首先改变css和html内容达到原图可以原大小显示(这里的大图原图会很大很大,我这里是6622x4677大小)

html:

<div class="div_main" ref="div_h">
  	<div id="box_BigImg" >
		<img :src="url1" />
	</div>
	<div id="left">
		<img :src="url1" />
		<div ref="box_h">
			<div class="slide_box" :style="wideHigh" id="box"></div>
		</div>
	</div>
</div>

css:

.div_main{
	display: flex;
	width: 100%;
	height: calc(100% - 51px);
	background: #fff;
	border-top: 2px #8a8f8d33 solid;
}
#box_BigImg{
	width: 84%;
	height: 95%;
	position: relative;
	margin: auto auto;
	overflow:hidden;
	box-shadow: 3px 3px 10px 0 #111111; /*给图片施加阴影效果 */
}
#box_BigImg img {
	position: absolute;
}
#left{
	width: 170px;
	height: 170px;
	bottom: 0;
	right: 0;
	position: absolute;
	overflow:hidden;
	margin: 10px 10px;
	box-shadow: 3px 3px 10px 0 #111111; 
	-webkit-box-shadow: 3px 3px 10px 0 #111111;
	-moz-box-shadow: 3px 3px 10px 0 #111111;
}
#left img{
	position: absolute;
	width: 100%;
	height: 100%;
}
.slide_box {
    display: none; /*将小方块盒子隐藏*/
    position: absolute;
    z-index: 9999;
    top: 0;
    left: 0;
    background: #000;
    opacity: 0.3;
    cursor: move; /*改变鼠标的形状*/
}

js:

data () {
	 return {
        wideHigh:{
		    height:'',	
		    width:''
		},
        imgInfo: {}, // 存图片的宽高信息
      	box_y:1,
      	box_x:1
     }
}
mounted(){
			//左边图片的原图的宽高
			let img = new Image()
	      	img.src = this.url1
	      	const vm = this
	      	img.onload = function () {
				vm.$set(vm.imgInfo, 'width', img.width)
				vm.$set(vm.imgInfo, 'height', img.height)
			}
	      	//原图的宽高和大图div的宽高比例
            //vm.$refs.div_h.offsetHeight是获取大div的高度,div_h对应html中的ref
			let y=(img.height/vm.$refs.div_h.offsetHeight).toFixed(1)
			let x=(img.width/vm.$refs.div_h.offsetWidth).toFixed(1)
			//鼠标图层的宽高
			vm.wideHigh.height=(vm.$refs.box_h.clientWidth/y).toFixed(1)+'px',
            //赋值给html样式需要px单位
			vm.wideHigh.width=(vm.$refs.box_h.clientWidth/x).toFixed(1)+'px',
			vm.box_y=(vm.$refs.box_h.clientWidth/y).toFixed(1)
			vm.box_x=(vm.$refs.box_h.clientWidth/x).toFixed(1)
			this.mouseAmplification()	  
  		},
methods: {
//鼠标经过
	mouseAmplification(){
		var leftone = document.getElementById('left');
		var rightone = document.getElementById('box_BigImg');
		var box = document.getElementById('box');
		var rimg = rightone.getElementsByTagName("img")[0];
		let that=this
		function getPosition(e){ //这里的参数e就是代表event
			 //首先我们要去判断事件源,获取事件源,也就是e
			 var e=e||window.event; //实现兼容
			 //理解:
			 //这个表达式写全是这样:var e=event?event||window.event;
			 //如果存在event,那么var e=event;而如果不存在event,
			 //那么var e=window.event.那么可以看出确实能实现兼容
			 var top = e.clientY-leftone.offsetTop-box.offsetHeight/2; 
			 //计算小图容器里的鼠标坐标(要减去最外层的偏移)
			 var left = e.clientX-leftone.offsetLeft-box.offsetWidth/2;
			 //这里为什么除以2?是因为我们不除以2的话,事件源也就是鼠标就在这个小滑块的的右下角,并不美观
			 //我们要让鼠标位于滑块的中心,所以宽高各减去一半
			 
			  //边界判断
			  //获取小滑块最大纵向移动距离
			  var maxtop = leftone.offsetHeight - box.offsetHeight; 
			  //获取小滑块最大横向移动距离
			  var maxleft = leftone.offsetWidth - box.offsetWidth; 
			  var mintop = 0; //获取小滑块最小纵向移动距离
			  var minleft = 0; //获取小滑块最大纵向移动距离
			  var mvtop; //定义小滑块的纵向移动距离
			  var mvleft; //定义小滑块的横向移动距离
			  // 判断
			  if (top<mintop) {
			  box.style.top = mintop + "px";
			   mvtop = mintop;
			    //理解:
				 //top是鼠标到浏览器的垂直距离-小图div顶部到浏览器的垂直距离-小滑块的高度的一半。
				 //那么现在鼠标在小滑块的中心,也就是说,top就等于小滑块的顶部到小图div的垂直距离
				 //如果top<0,就是说小滑块和小图div顶部重合,就让小滑块的top值为0,即鼠标继续向上移动,
				 //小滑块不在移动,从而让小滑块的移动范围不能超过小图div的宽高范围
				 //下方同理
			  }else if(top>maxtop){
			   box.style.top = maxtop + "px";
			   mvtop = maxtop;
			 //如果top>maxtop,就是说小滑块和小图div底部重合,就让小滑块的top值为maxtop,
			 //即鼠标继续向下移动,小滑块不在移动,从而让小滑块的移动范围不能超过小图div的宽高范围
			  }else{
			   box.style.top = top + "px";
			   mvtop = top;
			   //不超过边界,则小滑块的垂直移动距离就等于top,即小滑块的顶部到小图div的垂直距离
			  }
			  if(left<minleft){
			   box.style.left = minleft + "px";
			   mvleft = minleft
			  }else if(left>maxleft){
			   box.style.left = maxleft + "px";
			   mvleft = maxleft
			  }else{
			   box.style.left = left + "px";
			   mvleft = left;
			  }
			 //左侧大图片跟着运动:右侧小滑块移动多少,左侧跟着移动他的多少倍即可
             //所以上方需要计算那么多的比例值,就是因为要计算大图div与小图鼠标移动图层的比例来得出需要移动多少倍数才能精细
			    let y=Math.ceil(that.$refs.div_h.offsetHeight/that.box_y)
			    let x=Math.ceil(that.$refs.div_h.offsetWidth/that.box_x)
			    rimg.style.top = -mvtop*y + "px";
			    rimg.style.left = -mvleft*x + "px";
		}
		//鼠标移动效果
		leftone.onmousemove = function(e){
			 var e=e||window.event; //判断事件源
			 box.style.display = "block";
			 getPosition(e);
			 rightone.style.display = "block";
		}
		//鼠标移出效果
		leftone.onmouseleave = function(e){
			var e=e||window.event; //判断事件源
			box.style.display = "none";
			//rightone.style.display = "none"; //鼠标移出后大图隐藏
		}
	},
}

 结果:

再优化:(现在右下角移动是根据鼠标移动的,但是鼠标移出就无法停留在指定的位置上) 

把鼠标移动这段代码替换成鼠标拖拽:
//鼠标移动效果
		leftone.onmousemove = function(e){
			 var e=e||window.event; //判断事件源
			 box.style.display = "block";
			 getPosition(e);
			 rightone.style.display = "block";
		}
		//鼠标移出效果
		leftone.onmouseleave = function(e){
			var e=e||window.event; //判断事件源
			box.style.display = "none";
			//rightone.style.display = "none"; //鼠标移出后大图隐藏
		}
替换成:
 box.style.display = "block";
 rightone.style.display = "block";
  // 拖动小滑块事件,让大图移动到指定位置
 box.ondragend = function(e){
    // console.log('拖拽结束');
    getPosition(e);
 }

参考:https://www.jb51.net/article/164121.htm

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值