放大鼠标滚轮点(使用比例和平移) [英] Zoom in on a mousewheel point (using scale and translate)

查看:119
本文介绍了放大鼠标滚轮点(使用比例和平移)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题类似于以下问题:放大一点(使用比例和翻译)
甚至是这一点:图像缩放以鼠标位置为中心
但我不想在画布上进行,而是在正常图像(或者更确切地说是图像的容器div)上进行。
因此缩放应该是谷歌地图。
我实际上是在黑客攻击/增强iDangerous Swiper zoom( http://idangero.us/swiper/),这是我的出发点,这就是我到目前为止所得到的:
https ://jsfiddle.net/xta2ccdt/3/

This question is similar to this one: Zoom in on a point (using scale and translate) or even this one: Image zoom centered on mouse position but I don't want to do it on a canvas but a normal image (or rather the container div of the image). So zooming should be as google maps. I am actually hacking/enhancing iDangerous Swiper zoom (http://idangero.us/swiper/), and that is my starting point, and this is is what I got so far: https://jsfiddle.net/xta2ccdt/3/

仅使用鼠标滚轮进行缩放。第一次放大时它会完美地缩放,但我无法弄清楚如何在第一次放大后计算每个缩放。

Zoom only with the mouse wheel. The first time you zoom in it zooms perfectly, but I can't figure out how to calculate every zoom after first one.

这是我的代码:
JS :

Here's my code: 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');
  });


});

HTML:

<div id="slideContainer">
  <div id="slide">
    <img src="http://content.worldcarfans.co/2008/6/medium/9080606.002.1M.jpg"></img>
  </div>
</div>

CSS:

#slideContainer{
  width:500px;
  height:500px;
  overflow:hidden;
}
#slide{
  width:100%;
  height:100%;
}
img{
  width:auto;
  height:auto;
  max-width:100%;
}

我还想出是否从当前的值中减去以前的translateX和translateY值,我可以根据需要放大相同的点,它会完美缩放,但如果我放大一个点,然后改变鼠标位置并再次放大,它将不再按照预期进行缩放。示例: https://jsfiddle.net/xta2ccdt/4/

I also figured out if I subtract previous translateX and translateY values from the current ones, I can zoom on the same point as much as I want and it will zoom perfectly, but if I zoom on one point and then change the mouse position and zoom in again, it will no longer zoom as it's supposed to. Example: https://jsfiddle.net/xta2ccdt/4/

如果我改变鼠标位置,并计算旧鼠标位置和新鼠标位置之间的X和Y差异,并将其添加到差异计算中,它将第二次正确缩放。但第三次看起来差异仍然从总计算中减去,这将导致翻译再次将图像移开,之后如果我们将鼠标保持在相同的位置,它将再次正确缩放。
所以我想我每次计算新的差异时都会添加旧鼠标位置和新旧鼠标位置之间的差异,而且这种作品不再像我停止添加时那样跳跃鼠标位置差异,但它仍然没有放大相同的位置,每个新的缩放它移动(偏移)图像少量。我认为这是因为每次都有一个新的缩放值,但是偏移不是线性的,它每次都接近于零,我无法弄清楚如何抵消偏移。
以下是新示例: https://jsfiddle.net/xta2ccdt/5/
示例中的新图片:旧图片不再可用: https://jsfiddle.net / xta2ccdt / 14 /

If I change mouse position, and calculate the X and Y difference between old and new mouse position and add that into the diff calculation it will zoom correctly the second time. But the third time looks like that difference still gets subtracted from the total calculation and this will cause the translate to move the image away again, after that if we hold the mouse in the same position it will zoom correctly again. So I figured I'll just add the difference between old and new mouse position every time I calculate the new "diff", and this kind of works, there is no longer a jump like it was when I stopped adding the mouse position difference, but it's still not zooming on the same position, with each new zoom it moves (offsets) the image by a small amount. I figure this is because there is a new zoom value each time, but the offset is not linear, it's everytime smaller approaching zero, and I can't figure out how to offset the offset. Here is the new example: https://jsfiddle.net/xta2ccdt/5/ New image in the example: old one is no longer available: https://jsfiddle.net/xta2ccdt/14/

推荐答案

你接近它,但是最好存储x,y和分别缩放并根据这些值计算变换。它使事情变得更容易+节省资源(不需要反复查找dom属性),

You were close to it, however it's better to store the x,y and scale separately and calculate the transforms based on those values. It makes things alot easier + saves resources (no need to lookup the dom properties over and over),

我已将代码放入一个很好的模块中:

I've put the code into a nice module:

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+')')
    }
}

通过致电

new ScrollZoom($('#container'),4,0.5)

参数为:


  1. container:要缩放的元素的包装器。脚本将
    查找容器的第一个子节点并将变换
    应用于它。

  2. max_scale:最大比例(4 = 400%缩放)

  3. factor:缩放速度(1 =每个鼠标滚轮刻度+ 100%缩放)

JSFiddle

这篇关于放大鼠标滚轮点(使用比例和平移)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆