Skip to content Skip to sidebar Skip to footer

Zoom On An Image On Mouse Move: Reaching All Corners

I'm working on a zoom functionality. This zoom is a fixed box with 100% of the window size and inside an image with the 200% of the width of the fixed box. This zoom needs to work

Solution 1:

You were really close. You just need to calculate for image.height - window.height when getting vertical percentage.

This will also work with different image aspect ratios, since it takes image height into account when making calculations. Width is a non-issue since it is always double the window width.

varZoom = 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 = newImage();
    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 = newZoom("http://dummyimage.com/2000x1200/000/fff");
zoom.init();
#zoom {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1000000;
  display: none;
}
#zoomimg {
  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;
}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divid="loader">Loading</div><divid="zoom"></div>

As a bonus:

If you want to get rid of the empty space left when aspect ratio of the image is high (jsfiddle), you can make sure the image height is at least equal to window height (jsfiddle). But, you will need to set width: auto in this case, so image will not always be twice as wide as window.

Solution 2:

I think you can achieve what you want with CSS modification. If you try to use clip, transform translate and transform scale together in onmousemove event, you can shift the image as specified in your question. Please let me know, if this is desired behavior, thank you.

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);
});

varZoom = 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 = newImage();
    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 calculationvar imgCenterX = width/2;
      var imgCenterY = height/2;
      // translate calculationvar tx = imgCenterX-divPos.left;
      var ty = imgCenterY-divPos.top;

      // clip calculationvar 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 = newZoom("http://dummyimage.com/2000x1230/000/fff");
zoom.init();
#zoom {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 1000000;
            display: none;
}
#zoomimg {
            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;
}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divid="loader">Loading</div><divid="zoom"></div>

Post a Comment for "Zoom On An Image On Mouse Move: Reaching All Corners"