在鼠标移动时放大图像:到达所有角落
Zoom on an image on mouse move: reaching all corners
我正在研究缩放功能。此缩放是一个固定框,具有 window 大小的 100%,并且在图像内部具有固定框宽度的 200%。
此缩放需要像这样工作:
- 当光标位于 window 的中心时,图像应位于中心。
- 当光标在右上角时,图片应该停留在window的右上角(所以用角到达图片)
- 当光标在中间下角时,图片应该水平居中并到达总底部,这样我们就可以看到图片的中间下部。
- 以此类推
我接近了,但无法完美到达角落。这是我的代码片段(请参阅 onmousemove 函数中的注释):
var Zoom = function(imageZoom) {
this.urlImage = imageZoom;
this.img = undefined;
this.$img = undefined;
this.init = function() {
this.loaders("on");
this.calcs();
};
this.calcs = function() {
var self = this;
this.img = new Image();
this.img.onload = function() {
self.build();
};
this.img.src = this.urlImage;
};
this.loaders = function(status) {
switch(status) {
case "on":
$('#loader').fadeIn(200);
break;
case "off":
$('#loader').fadeOut(200);
break;
}
};
this.build = function() {
var self = this;
this.$img = $(self.img);
$('#zoom').fadeIn(200).append(this.$img);
this.$img.on('mousedown', function(e) {
e.preventDefault();
});
// this is the problematic function
$('body').on('mousemove', function(e) {
e.preventDefault();
// calc the percents of the window where
var px = 100 * e.pageX / $(window).width();
var py = 100 * e.pageY / $(window).height();
// calc of the percent pixel of the image
var fx = self.$img.width() * px / 100;
var fy = self.$img.height() * py / 100;
// render it left / 2 and top / 1.5 (the 1.5 value is imaginary!!)
self.$img.css({'transform': 'translate('+ -(fx/2) +'px, '+ -(fy/1.5)+'px)'});
});
self.loaders("off");
};
};
var zoom = new Zoom("http://dummyimage.com/2000x1230/000/fff");
zoom.init();
#zoom {
position: fixed;;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000000;
display: none;
}
#zoom img {
width: 200%;
height: auto;
position: absolute;
cursor: crosshair;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loader">Loading</div>
<div id="zoom"></div>
问题是我放了 fx/1.5
因为 fx/2
不起作用。但是水平值非常有效。
我可以配置什么值来到达所有角落?为什么左边的值(像素除以 2)在顶部值不工作时工作得很好?
我想你可以通过 CSS 修改来实现你想要的。如果您尝试在 onmousemove 事件中同时使用 clip、transform translate 和 transform scale,则可以按照问题中指定的方式移动图像。请让我知道,如果这是期望的行为,谢谢。
var divPos = {left:0,top:0};
var offset = $("#loader").offset();
$(document).mousemove(function(e){
divPos = {
left: e.pageX - offset.left,
top: e.pageY - offset.top
};
console.log("x:" + divPos.left + " y: " + divPos.top);
});
var Zoom = function(imageZoom) {
this.urlImage = imageZoom;
this.img = undefined;
this.$img = undefined;
this.init = function() {
this.loaders("on");
this.calcs();
};
this.calcs = function() {
var self = this;
this.img = new Image();
this.img.onload = function() {
self.build();
};
this.img.src = this.urlImage;
};
this.loaders = function(status) {
switch(status) {
case "on":
$('#loader').fadeIn(200);
break;
case "off":
$('#loader').fadeOut(200);
break;
}
};
this.build = function() {
var self = this;
this.$img = $(self.img);
$('#zoom').fadeIn(200).append(this.$img);
this.$img.on('mousedown', function(e) {
e.preventDefault();
});
// this is the problematic function
$('body').on('mousemove', function(e) {
e.preventDefault();
var width = $(self.img).width();
var height = $(self.img).height();
// img center calculation
var imgCenterX = width/2;
var imgCenterY = height/2;
// translate calculation
var tx = imgCenterX-divPos.left;
var ty = imgCenterY-divPos.top;
// clip calculation
var c0 = divPos.top/2;
var c1 = divPos.left/2 + width/2;
var c2 = divPos.top/2 + height/2;
var c3 = divPos.left/2;
console.log(c0 + ',' + c1 + ',' + c2 + ',' + c3);
var t = 'translate('+ tx +'px, '+ ty +'px)';
var c = 'rect('+ c0 +'px,'+ c1 +'px,'+ c2 +'px,'+ c3 +'px)';
self.$img.css({'transform': t + ' scale(2,2)'});
self.$img.css({'clip': c});
});
self.loaders("off");
};
};
var zoom = new Zoom("http://dummyimage.com/2000x1230/000/fff");
zoom.init();
#zoom {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000000;
display: none;
}
#zoom img {
width: 100%;
height: 100%;
position: absolute;
cursor: crosshair;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loader">Loading</div>
<div id="zoom"></div>
你们真的很亲密。获取垂直百分比时,您只需要计算 image.height - window.height
。
这也适用于不同的图像纵横比,因为它在计算时会考虑图像高度。宽度不是问题,因为它总是 window 宽度的两倍。
var Zoom = function(imageZoom) {
this.urlImage = imageZoom;
this.img = undefined;
this.$img = undefined;
this.init = function() {
this.loaders("on");
this.calcs();
};
this.calcs = function() {
var self = this;
this.img = new Image();
this.img.onload = function() {
self.build();
};
this.img.src = this.urlImage;
};
this.loaders = function(status) {
switch (status) {
case "on":
$('#loader').fadeIn(200);
break;
case "off":
$('#loader').fadeOut(200);
break;
}
};
this.build = function() {
var self = this;
this.$img = $(self.img);
$('#zoom').fadeIn(200).append(this.$img);
this.$img.on('mousedown', function(e) {
e.preventDefault();
});
// this is the problematic function
$('body').on('mousemove', function(e) {
e.preventDefault();
var wx = $(window).width();
var wy = $(window).height();
var iy = self.$img.height();
var px = e.pageX;
var py = e.pageY;
var tx = -1 * (px / wx) * wx;
var ty = -1 * (py / wy) * (iy - wy);
self.$img.css({
'transform': 'translate(' + tx + 'px, ' + ty + 'px)'
});
});
self.loaders("off");
};
};
var zoom = new Zoom("http://dummyimage.com/2000x1200/000/fff");
zoom.init();
#zoom {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000000;
display: none;
}
#zoom img {
width: 200%;
height: 100%;
height: auto;
position: absolute;
cursor: crosshair;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
body {
margin: 0;
}
* {
box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loader">Loading</div>
<div id="zoom"></div>
作为奖励:
如果你想摆脱图像宽高比高时留下的空白 space (jsfiddle), you can make sure the image height is at least equal to window height (jsfiddle)。但是,在这种情况下您需要设置 width: auto
,因此图像的宽度不会总是 window 的两倍。
我正在研究缩放功能。此缩放是一个固定框,具有 window 大小的 100%,并且在图像内部具有固定框宽度的 200%。
此缩放需要像这样工作:
- 当光标位于 window 的中心时,图像应位于中心。
- 当光标在右上角时,图片应该停留在window的右上角(所以用角到达图片)
- 当光标在中间下角时,图片应该水平居中并到达总底部,这样我们就可以看到图片的中间下部。
- 以此类推
我接近了,但无法完美到达角落。这是我的代码片段(请参阅 onmousemove 函数中的注释):
var Zoom = function(imageZoom) {
this.urlImage = imageZoom;
this.img = undefined;
this.$img = undefined;
this.init = function() {
this.loaders("on");
this.calcs();
};
this.calcs = function() {
var self = this;
this.img = new Image();
this.img.onload = function() {
self.build();
};
this.img.src = this.urlImage;
};
this.loaders = function(status) {
switch(status) {
case "on":
$('#loader').fadeIn(200);
break;
case "off":
$('#loader').fadeOut(200);
break;
}
};
this.build = function() {
var self = this;
this.$img = $(self.img);
$('#zoom').fadeIn(200).append(this.$img);
this.$img.on('mousedown', function(e) {
e.preventDefault();
});
// this is the problematic function
$('body').on('mousemove', function(e) {
e.preventDefault();
// calc the percents of the window where
var px = 100 * e.pageX / $(window).width();
var py = 100 * e.pageY / $(window).height();
// calc of the percent pixel of the image
var fx = self.$img.width() * px / 100;
var fy = self.$img.height() * py / 100;
// render it left / 2 and top / 1.5 (the 1.5 value is imaginary!!)
self.$img.css({'transform': 'translate('+ -(fx/2) +'px, '+ -(fy/1.5)+'px)'});
});
self.loaders("off");
};
};
var zoom = new Zoom("http://dummyimage.com/2000x1230/000/fff");
zoom.init();
#zoom {
position: fixed;;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000000;
display: none;
}
#zoom img {
width: 200%;
height: auto;
position: absolute;
cursor: crosshair;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loader">Loading</div>
<div id="zoom"></div>
问题是我放了 fx/1.5
因为 fx/2
不起作用。但是水平值非常有效。
我可以配置什么值来到达所有角落?为什么左边的值(像素除以 2)在顶部值不工作时工作得很好?
我想你可以通过 CSS 修改来实现你想要的。如果您尝试在 onmousemove 事件中同时使用 clip、transform translate 和 transform scale,则可以按照问题中指定的方式移动图像。请让我知道,如果这是期望的行为,谢谢。
var divPos = {left:0,top:0};
var offset = $("#loader").offset();
$(document).mousemove(function(e){
divPos = {
left: e.pageX - offset.left,
top: e.pageY - offset.top
};
console.log("x:" + divPos.left + " y: " + divPos.top);
});
var Zoom = function(imageZoom) {
this.urlImage = imageZoom;
this.img = undefined;
this.$img = undefined;
this.init = function() {
this.loaders("on");
this.calcs();
};
this.calcs = function() {
var self = this;
this.img = new Image();
this.img.onload = function() {
self.build();
};
this.img.src = this.urlImage;
};
this.loaders = function(status) {
switch(status) {
case "on":
$('#loader').fadeIn(200);
break;
case "off":
$('#loader').fadeOut(200);
break;
}
};
this.build = function() {
var self = this;
this.$img = $(self.img);
$('#zoom').fadeIn(200).append(this.$img);
this.$img.on('mousedown', function(e) {
e.preventDefault();
});
// this is the problematic function
$('body').on('mousemove', function(e) {
e.preventDefault();
var width = $(self.img).width();
var height = $(self.img).height();
// img center calculation
var imgCenterX = width/2;
var imgCenterY = height/2;
// translate calculation
var tx = imgCenterX-divPos.left;
var ty = imgCenterY-divPos.top;
// clip calculation
var c0 = divPos.top/2;
var c1 = divPos.left/2 + width/2;
var c2 = divPos.top/2 + height/2;
var c3 = divPos.left/2;
console.log(c0 + ',' + c1 + ',' + c2 + ',' + c3);
var t = 'translate('+ tx +'px, '+ ty +'px)';
var c = 'rect('+ c0 +'px,'+ c1 +'px,'+ c2 +'px,'+ c3 +'px)';
self.$img.css({'transform': t + ' scale(2,2)'});
self.$img.css({'clip': c});
});
self.loaders("off");
};
};
var zoom = new Zoom("http://dummyimage.com/2000x1230/000/fff");
zoom.init();
#zoom {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000000;
display: none;
}
#zoom img {
width: 100%;
height: 100%;
position: absolute;
cursor: crosshair;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loader">Loading</div>
<div id="zoom"></div>
你们真的很亲密。获取垂直百分比时,您只需要计算 image.height - window.height
。
这也适用于不同的图像纵横比,因为它在计算时会考虑图像高度。宽度不是问题,因为它总是 window 宽度的两倍。
var Zoom = function(imageZoom) {
this.urlImage = imageZoom;
this.img = undefined;
this.$img = undefined;
this.init = function() {
this.loaders("on");
this.calcs();
};
this.calcs = function() {
var self = this;
this.img = new Image();
this.img.onload = function() {
self.build();
};
this.img.src = this.urlImage;
};
this.loaders = function(status) {
switch (status) {
case "on":
$('#loader').fadeIn(200);
break;
case "off":
$('#loader').fadeOut(200);
break;
}
};
this.build = function() {
var self = this;
this.$img = $(self.img);
$('#zoom').fadeIn(200).append(this.$img);
this.$img.on('mousedown', function(e) {
e.preventDefault();
});
// this is the problematic function
$('body').on('mousemove', function(e) {
e.preventDefault();
var wx = $(window).width();
var wy = $(window).height();
var iy = self.$img.height();
var px = e.pageX;
var py = e.pageY;
var tx = -1 * (px / wx) * wx;
var ty = -1 * (py / wy) * (iy - wy);
self.$img.css({
'transform': 'translate(' + tx + 'px, ' + ty + 'px)'
});
});
self.loaders("off");
};
};
var zoom = new Zoom("http://dummyimage.com/2000x1200/000/fff");
zoom.init();
#zoom {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000000;
display: none;
}
#zoom img {
width: 200%;
height: 100%;
height: auto;
position: absolute;
cursor: crosshair;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
body {
margin: 0;
}
* {
box-sizing: border-box;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="loader">Loading</div>
<div id="zoom"></div>
作为奖励:
如果你想摆脱图像宽高比高时留下的空白 space (jsfiddle), you can make sure the image height is at least equal to window height (jsfiddle)。但是,在这种情况下您需要设置 width: auto
,因此图像的宽度不会总是 window 的两倍。