Home > Software engineering >  Zoom calculation with image rotation
Zoom calculation with image rotation

Time:02-16

I am trying to make the zoom work in all 4 directions. However it is only working in the opposite directions, which are 180 and 360 degrees. In the 90 and 270 degrees the zoom behaves strangely and does not fit with the image.

Can anyone help me with the calculation for the zoom to work in all directions? I have tried everything and I can't get it.

var statusRotate = 4;
rotateImage();

function rotateImage() {
    if (statusRotate == 1) {
        imageLen('90', '90');
        statusRotate = 2
    } else if (statusRotate == 2){
        imageLen('180', '-180')
        statusRotate = 3
    } else if (statusRotate == 3){
        imageLen('270', '270')
        statusRotate = 4
    } else if (statusRotate == 4){
        imageLen('360', '360')
        statusRotate = 1
    } 
}

function imageLen(x, y){
    var degrees_image = x;
    var degrees_image_native = y;

    var $element = $('#target');
    $element.css({
        'transform': 'rotate('  degrees_image  'deg)'
    }); // rotate imagem in html

    // Constants
    var $IMAGE_URL    = $element.attr("src");
    var NATIVE_IMG    = new Image();
    NATIVE_IMG.src    = $element.attr("src");

    var lens = document.createElement("div");
    lens.id = "BlowupLens";
    $("body").append(lens);
    $blowupLens = $("#BlowupLens");

    $blowupLens.css({
        "position"          : "absolute",
        "display"           : "none",
        "pointer-events"    : "none",
        "zIndex"            : 999999,
        "width"             : 200,
        "height"            : 200,
        "border"            : "6px solid #FFF",
        "background"        : "#FFF",
        "border-radius"     : "50%",
        "box-shadow"        : "0 8px 17px 0 rgba(0, 0, 0, 0.2)",
        "background-repeat" : "no-repeat",
    });

    // Show magnification lens
    $element.mouseenter(function () {
        $blowupLens.css("display", "block");
    });


    // Mouse motion on image
    $element.mousemove(function (e) {

    // Lens position coordinates
    var lensX = e.pageX - (200 / 2);
    var lensY = e.pageY - (200 / 2);

    var width = $element.width();
    var height = $element.height();

    var left = $('#target').offset().left;
    var top = $('#target').offset().top;

    // Relative coordinates of image
    var relX = e.pageX - left;
    var relY = e.pageY - top;

    var nativeImageWidth = NATIVE_IMG.width;
    var nativeImageHeight = NATIVE_IMG.height;

    // Zoomed image coordinates 
    var zoomX = -Math.floor(relX / width * (NATIVE_IMG.width) - 200 / 2);
    var zoomY = -Math.floor(relY / height * (NATIVE_IMG.height) - 200 / 2);



    if(degrees_image == '90') {
        var backPos = "calc(100% - "   zoomY   "px) calc(100% - "   zoomX   "px)";
        //var backPos = zoomY   "px "   zoomX   "px";
        var backgroundSize = NATIVE_IMG.width   "px "   NATIVE_IMG.height   "px";

        //
    } else if(degrees_image == '180') {
        var backPos = "calc(100% - "   zoomX   "px) calc(100% - "   zoomY   "px)";
        var backgroundSize = NATIVE_IMG.width   "px "   NATIVE_IMG.height   "px";

    } else if(degrees_image == '270') {
        var backPos = zoomY   "px "   zoomX   "px";
        var backgroundSize = NATIVE_IMG.width   "px "   NATIVE_IMG.height   "px";

    } else if(degrees_image == '360') {
        var backPos = zoomX   "px "   zoomY   "px";
        var backgroundSize = NATIVE_IMG.width   "px "   NATIVE_IMG.height   "px";
    }

    // Apply styles to lens
    $blowupLens.css({
        left                  : lensX,
        top                   : lensY,
        "background-image"    : "url("   encodeURI($IMAGE_URL)   ")",
        "background-size"     : backgroundSize,
        "background-position" : backPos,
        "transform"           : 'rotate('  degrees_image_native  'deg)' //rotate the image original
        });
    })

    // Hide magnification lens
    $element.mouseleave(function () {
        $blowupLens.css("display", "none");
    });
}      
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div style="margin-top: 100px;">
  <img id="target" style="margin-left: 160px; width: 600px; height: 500px;" src="https://iili.io/0hL7ou.png">
</div>
        
<button onclick="rotateImage()">Rotate</button>

CodePudding user response:

I have slightly corrected your example:

var statusRotate = 4;
rotateImage();

function rotateImage() {
  if (statusRotate == 1) {
    imageLen('90', '90');
    statusRotate = 2
  } else if (statusRotate == 2) {
    imageLen('180', '-180')
    statusRotate = 3
  } else if (statusRotate == 3) {
    imageLen('270', '270')
    statusRotate = 4
  } else if (statusRotate == 4) {
    imageLen('360', '360')
    statusRotate = 1
  }
}

function imageLen(x, y) {
  var degrees_image = Number(x);
  var degrees_image_native = Number(y);

  var $element = $('#target');
  $element.css({
    'transform': 'rotate('   degrees_image   'deg)'
  }); // rotate imagem in html

  // Constants
  var $IMAGE_URL = $element.attr("src");
  var NATIVE_IMG = new Image();
  NATIVE_IMG.src = $element.attr("src");
  
  if (!$("#BlowupLens").length) { // if not exists
    var lens = document.createElement("div");
    lens.id = "BlowupLens";
    $("body").append(lens);
  }
  $blowupLens = $("#BlowupLens");

  $blowupLens.css({
    "position": "absolute",
    "display": "none",
    "pointer-events": "none",
    "zIndex": 999999,
    "width": 200,
    "height": 200,
    "border": "6px solid #FFF",
    "background": "#FFF",
    "border-radius": "50%",
    "box-shadow": "0 8px 17px 0 rgba(0, 0, 0, 0.2)",
    "background-repeat": "no-repeat",
  });
  
  $element.off('mouseenter'); // remove previous event
  // Show magnification lens
  $element.mouseenter(function() {
    $blowupLens.css("display", "block");
  });

  $element.off('mousemove'); // remove previous event
  // Mouse motion on image
  $element.mousemove(function(e) {

    // Lens position coordinates
    var lensX = e.pageX - (200 / 2);
    var lensY = e.pageY - (200 / 2);

    var width = $element.width();
    var height = $element.height();

    var left = $('#target').offset().left;
    var top = $('#target').offset().top;

    // Relative coordinates of image
    var relX = e.pageX - left;
    var relY = e.pageY - top;
    var nativeImageWidth = NATIVE_IMG.width;
    var nativeImageHeight = NATIVE_IMG.height;

    // Zoomed image coordinates 
    var zoomX = -Math.floor(relX / width * (NATIVE_IMG.width) - 200 / 2);
    var zoomY = -Math.floor(relY / height * (NATIVE_IMG.height) - 200 / 2);


    if (degrees_image === 90) {
      var backPos = `${zoomY}px calc(100% - ${zoomX}px)`;
      var backgroundSize = NATIVE_IMG.width   "px "   NATIVE_IMG.height   "px";
    } else if (degrees_image === 180) {
      var backPos = `calc(100% - ${zoomX}px) calc(100% - ${zoomY}px)`;
      var backgroundSize = NATIVE_IMG.width   "px "   NATIVE_IMG.height   "px";
    } else if (degrees_image === 270) {
      var backPos = `calc(100% - ${zoomY}px) ${zoomX}px`;
      var backgroundSize = NATIVE_IMG.width   "px "   NATIVE_IMG.height   "px";
    } else if (degrees_image === 360) {
      var backPos = `${zoomX}px ${zoomY}px`;
      var backgroundSize = NATIVE_IMG.width   "px "   NATIVE_IMG.height   "px";
    }

    // Apply styles to lens
    $blowupLens.css({
      left: lensX,
      top: lensY,
      "background-image": "url("   encodeURI($IMAGE_URL)   ")",
      "background-size": backgroundSize,
      "background-position": backPos,
      "transform": 'rotate('   degrees_image_native   'deg)' //rotate the image original
    });
  })
  $element.off("mouseleave"); // remove previous event
  // Hide magnification lens
  $element.mouseleave(function() {
    $blowupLens.css("display", "none");
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div style="margin-top: 100px;">
  <img id="target" style="margin-left: 160px; width: 600px; height: 500px;" src="https://iili.io/0hL7ou.png">
</div>

<button onclick="rotateImage()">Rotate</button>

However, I recommend refactoring your example, because it can be simplified and make the code cleaner.

  • Related