如何为与其容器比例不同的图像创建平移和缩放效果?

问题描述 投票:0回答:2

我有以下简单的代码,用于平移和缩放图像(从[此处]稍作修改:(https://www.cssscript.com/image-zoom-hover-effect/

    function imageZoom(container, img) {

      container.addEventListener("mousemove", onZoom);
      container.addEventListener("mouseover", onZoom);
      container.addEventListener("mouseleave", offZoom);
      function onZoom(e) {
    
        let offset = container.getBoundingClientRect();
          const x = e.clientX - offset.left;
          const y = e.clientY - offset.top;
          img.style.transformOrigin = `${x}px ${y}px`;
          img.style.transform = "scale(2.5)";
      }
      function offZoom(e) {
          img.style.transformOrigin = `center center`;
          img.style.transform = "scale(1)";
      }
    }

当图像与容器成比例时,此方法效果很好。我需要它来处理方形容器内的随机大小的图像,并能够通过平移和缩放来显示整个图像。

我尝试将 X 和 Y 乘以

        let coefX= img.naturalWidth / container.offsetWidth
        let coefY= img.naturalHeight / container.offsetHeight

分别,但这导致图像完全离开容器。我觉得数学简单明了,但我似乎无法理解它 - 我所做的其他尝试也导致了类似的问题。

javascript image math frontend zooming
2个回答
2
投票

我一直想做出这样的效果。我在网上“发现”了这个。该解决方案仅具有平移功能,没有缩放功能。框架周围还有一个额外的安全区域。

// container, image are defined function panImage(event) { // Adjust this value to control the buffer area around the frame const buffer = 10; const containerRect = container.getBoundingClientRect(); const mouseX = event.clientX - containerRect.left; const mouseY = event.clientY - containerRect.top; const maxX = image.clientWidth - container.clientWidth; const maxY = image.clientHeight - container.clientHeight; const xPercentage = (mouseX - buffer) / (container.clientWidth - buffer * 2); const yPercentage = (mouseY - buffer) / (container.clientHeight - buffer * 2); const offsetX = Math.min(Math.max(0, xPercentage * maxX), maxX); const offsetY = Math.min(Math.max(0, yPercentage * maxY), maxY); image.style.transform = `translate(-${offsetX}px, -${offsetY}px)`; }
#container {
  width: 200px;
  height: 150px;
  overflow: hidden;
  border: 1px solid red;
}

#image {
  transform: translate(0, 0);
  transition: all 0.25s ease;
}
<div id="container" onmousemove="panImage(event)">
  <img id="image" src="https://picsum.photos/412/370">
</div>


0
投票

function ZoomPan(e) { const container = this.getBoundingClientRect(); const mouseX = e.clientX - container.left; const mouseY = e.clientY - container.top; const originX = (mouseX / this.offsetWidth) * 100; const originY = (mouseY / this.offsetHeight) * 100; this.getElementsByClassName("zoom-img")[0].style.transformOrigin = `${originX}% ${originY}%`; } var allContainers = document.getElementsByClassName("zoom-container"); Array.from(allContainers).forEach(function(c) { c.addEventListener("mousemove", ZoomPan); });
.zoom-container {
    width: 200px;
    height: 200px;
    margin: auto;
    overflow: hidden;
}

.zoom-img {
    width: 100%;
    height: 100%;
    cursor: crosshair;
    transition: 0.2s;
    transform: scale(1);
    transform-origin: 0% 0%;
}

    .zoom-img:hover {
        transform: scale(2);
        transition: none;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="zoom-container">
    <img class="zoom-img" src="https://picsum.photos/412/370" alt="" />
</div>

© www.soinside.com 2019 - 2024. All rights reserved.