如何在BlowupJS中保持图像和镜头旋转同步?

3

我使用了blowup.js插件作为基础,并尝试旋转图像,使镜头跟随旋转。但是它并没有起作用。

例如,当我输入rotate(180deg)时,镜头和图像不匹配,如果我删除rotate(180deg)则它们对齐。

有人知道怎么帮我吗?

在JSFiddle中查看示例

var $element = $('#target');
$element.css({
  'transform': 'rotate(180deg)'
}); // 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();

  // Relative coordinates of image
  var relX = e.pageX - $('#target').offset().left;
  var relY = e.pageY - $('#target').offset().top;

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

  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(180deg)" //rotate the image original
  });
})

// Hide magnification lens
$element.mouseleave(function() {
  $blowupLens.css("display", "none");
});
#target {
  margin-left: 160px;
  width: 700;
  height: 500px;
}
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>

<body>
  <img id="target" src="https://iili.io/0hL7ou.png">
</body>

1个回答

2
您可以将镜头逆时针旋转180度,并反转背景位置:
顺便提一下:您不希望在每次鼠标移动时都应用background-image,而是将其移到镜头初始化。

var $element = $('#target');
$element.css({
  'transform': 'rotate(180deg)'
}); // 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();

  // Relative coordinates of image
  var relX = e.pageX - $('#target').offset().left;
  var relY = e.pageY - $('#target').offset().top;

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

  var backPos = "calc(100% - " + zoomX + "px) calc(100% - " + 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(-180deg)" //rotate the image original
  });
})

// Hide magnification lens
$element.mouseleave(function() {
  $blowupLens.css("display", "none");
});
#target {
  margin-left: 160px;
  width: 400;
  height: 250px;
}
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>

<body>
  <img id="target" src="https://iili.io/0hL7ou.png">
</body>

更新: 对于更一般的图像旋转情况,我会在镜头内使用另一个绝对定位的图像,而不是 background-image。这样控制起来更容易:

var $pic = $('#target');

// Constants
const lensD = 70, // lens diameter
  src = $pic.attr("src"),
  tоp = $pic.offset().top,
  lеft = $pic.offset().left;

let angle, scaleX, scaleY;

const $lens = $('<div id="lens"/>')
  .css({
    width: lensD,
    height: lensD
  })
  .appendTo('body');
  
const $lensImage = $(`<img src="${src}">`)
  .on('load', function() {
    scaleX = this.width / ($pic.width() || 1);
    scaleY = this.height / ($pic.height() || 1);
  })
  .appendTo($lens);

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

  // Lens position
  $lens.css({
    transform: (`
      translateX(${e.pageX - lensD/2}px)
      translateY(${e.pageY - lensD/2}px)
    `)
  });

  // Zoomed image position
  $lensImage.css({
    transform: (`
      translateX(${(lеft - e.pageX) * scaleX + lensD/2}px)
      translateY(${(tоp - e.pageY) * scaleY + lensD/2}px)
      rotateZ(${angle}deg)
    `)
  });
});

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

// Hide magnification lens
$pic.mouseleave(function() {
  $lens.css("display", "none");
});

// Rotation (aux)
$('#angle')
  .on('input', function() {
    $('#a').val((angle = $(this).val()) + 'deg');
    $pic.css({
      transform: `rotateZ(${angle}deg)`
    });
    $lensImage.css({
      transform: `rotateZ(${angle}deg)`
    });
  })
  .trigger('input')
  .val();
#a {
  border: 0
}

#target,
#lens img {
  width: 200px;
  height: 100px;
  margin: 40px;
}

#lens {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  display: none;
  margin: 0;
  padding: 0;
  border: solid 3px #0003;
  border-radius: 50%;
  overflow: hidden;
  pointer-events: none;
}

#lens img {
  position: absolute;
  width: auto;
  height: auto;
  margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<fieldset>
  Rotate: <input id="a" readonly><br>
  -180 <input type="range" min="-180" max="180" step="1" value="-9" id="angle"> 180
</fieldset>

<img id="target" src="https://picsum.photos/id/111/400/200">


我喜欢它,看起来秘诀在于backPos的计算,但如果我放置90度,它又不匹配。你知道如何解决吗? - rafaelcb21
1
@rafaelcb21,抱歉忽略了你的评论!我已经更新了我的答案以处理任何旋转。 - Kosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接