dar*_*i0h 11 javascript html5 image zoom
这个问题类似于这个问题:放大一个点(使用缩放和平移) 或者甚至是这个:图像缩放以鼠标位置为中心 但我不想在画布上做它而是正常图像(或者更确切地说是图像的容器div).所以缩放应该像谷歌地图一样.我实际上是黑客/增强iDangerous Swiper zoom(http://idangero.us/swiper/),这是我的出发点,这就是我到目前为止所做的:https: //jsfiddle.net/xta2ccdt/3 /
仅使用鼠标滚轮进行缩放.第一次放大时它可以完美地缩放,但我无法弄清楚如何在第一次放大后计算每个缩放.
这是我的代码:JS:
$(document).ready(function(){
$("#slideContainer").on("mousewheel DOMMouseScroll", function (e) {
e.preventDefault();
var delta = e.delta || e.originalEvent.wheelDelta;
var zoomOut;
if (delta === undefined) {
//we are on firefox
delta = e.originalEvent.detail;
zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0;
zoomOut = !zoomOut;
} else {
zoomOut = delta ? delta < 0 : e.originalEvent.deltaY > 0;
}
var touchX = e.type === 'touchend' ? e.changedTouches[0].pageX : e.pageX;
var touchY = e.type === 'touchend' ? e.changedTouches[0].pageY : e.pageY;
var scale = 1, translateX, translateY;
if(zoomOut){
//we are zooming out
//not interested in this yet
}else{
//we are zooming in
scale = scale + 0.5;
var dimensionMultiplier = scale - 0.5;//when image is scaled up offsetWidth/offsetHeight doesn't take this into account so we must multiply by scale to get the correct width/height
var slideWidth = $("#slide")[0].offsetWidth * dimensionMultiplier;
var slideHeight = $("#slide")[0].offsetHeight * dimensionMultiplier;
var offsetX = $("#slide").offset().left;//distance from the left of the viewport to the slide
var offsetY = $("#slide").offset().top;//distance from the top of the viewport to the slide
var diffX = offsetX + slideWidth / 2 - touchX;//this is distance from the mouse to the center of the image
var diffY = offsetY + slideHeight / 2 - touchY;//this is distance from the mouse to the center of the image
//how much to translate by x and y so that poin on image is alway under the mouse
//we must multiply by 0.5 because the difference between previous and current scale is always 0.5
translateX = ((diffX) * (0.5));
translateY = ((diffY) * (0.5));
}
$("#slide").css("transform", 'translate3d(' + translateX + 'px, ' + translateY + 'px,0) scale(' + scale + ')').css('transition-duration', '300ms');
});
});
Run Code Online (Sandbox Code Playgroud)
HTML:
<div id="slideContainer">
<div id="slide">
<img src="http://content.worldcarfans.co/2008/6/medium/9080606.002.1M.jpg"></img>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
CSS:
#slideContainer{
width:500px;
height:500px;
overflow:hidden;
}
#slide{
width:100%;
height:100%;
}
img{
width:auto;
height:auto;
max-width:100%;
}
Run Code Online (Sandbox Code Playgroud)
我还想知道如果我从当前的那些中减去之前的translateX和translateY值,我可以根据需要放大相同的点,它会完美缩放,但是如果我放大一个点然后改变鼠标位置和缩放再次,它将不再按照预期进行缩放.示例:https://jsfiddle.net/xta2ccdt/4/
如果我改变鼠标位置,并计算旧鼠标位置和新鼠标位置之间的X和Y差异,并将其添加到差异计算中,它将第二次正确缩放.但第三次看起来差异仍然从总计算中减去,这将导致翻译再次移动图像,之后如果我们将鼠标放在相同的位置,它将再次正确缩放.所以我想我每次计算新的"差异"时都会添加旧鼠标位置和新鼠标位置之间的差异,这种作用,不再像我停止添加鼠标位置差异那样跳跃,但它仍然没有放大相同的位置,每次新的缩放都会使图像移动(偏移)一小部分.我认为这是因为每次都有一个新的缩放值,但是偏移不是线性的,它每次都接近于零,我无法弄清楚如何抵消偏移.以下是新示例:https://jsfiddle.net/xta2ccdt/5/示例中的 新图片:旧图片不再可用:https://jsfiddle.net/xta2ccdt/14/
Man*_*tto 12
您接近它,但最好分别存储x,y和比例并根据这些值计算变换.它使事情变得更容易+节省资源(不需要一遍又一遍地查找dom属性),
我把代码放到了一个很好的模块中:
function ScrollZoom(container,max_scale,factor){
var target = container.children().first()
var size = {w:target.width(),h:target.height()}
var pos = {x:0,y:0}
var zoom_target = {x:0,y:0}
var zoom_point = {x:0,y:0}
var scale = 1
target.css('transform-origin','0 0')
target.on("mousewheel DOMMouseScroll",scrolled)
function scrolled(e){
var offset = container.offset()
zoom_point.x = e.pageX - offset.left
zoom_point.y = e.pageY - offset.top
e.preventDefault();
var delta = e.delta || e.originalEvent.wheelDelta;
if (delta === undefined) {
//we are on firefox
delta = e.originalEvent.detail;
}
delta = Math.max(-1,Math.min(1,delta)) // cap the delta to [-1,1] for cross browser consistency
// determine the point on where the slide is zoomed in
zoom_target.x = (zoom_point.x - pos.x)/scale
zoom_target.y = (zoom_point.y - pos.y)/scale
// apply zoom
scale += delta*factor * scale
scale = Math.max(1,Math.min(max_scale,scale))
// calculate x and y based on zoom
pos.x = -zoom_target.x * scale + zoom_point.x
pos.y = -zoom_target.y * scale + zoom_point.y
// Make sure the slide stays in its container area when zooming out
if(pos.x>0)
pos.x = 0
if(pos.x+size.w*scale<size.w)
pos.x = -size.w*(scale-1)
if(pos.y>0)
pos.y = 0
if(pos.y+size.h*scale<size.h)
pos.y = -size.h*(scale-1)
update()
}
function update(){
target.css('transform','translate('+(pos.x)+'px,'+(pos.y)+'px) scale('+scale+','+scale+')')
}
}
Run Code Online (Sandbox Code Playgroud)
通过电话使用它
new ScrollZoom($('#container'),4,0.5)
Run Code Online (Sandbox Code Playgroud)
参数是: