【问题标题】:Panzoom to element on click单击时缩放到元素
【发布时间】:2020-10-12 08:59:37
【问题描述】:

我希望迪士尼乐园的地图在您单击它时平移/缩放到黄色方块。我是 web 开发新手,所以任何关于如何使用 CSS/JavaScript/jQuery 实现它的指针都将不胜感激。

编辑:我将示例替换为更接近实际应用的内容,以避免混淆。

代码笔: https://codepen.io/dan-freeman/pen/mdVWYox

HTML

<img src="https://i.redd.it/64xwakxpbae21.jpg">
<div class="pin">Click me!</div>-

CSS

img {
    width: 800px;
    height: auto;
}

.pin {
    position: absolute;
    height: 75px;
    width: 75px;
    top: 300px; /*Solution should use these coordinates*/
    left: 550px;
    background-color: yellow;
}

点击前 点击后

【问题讨论】:

  • @OP 如果你不介意我问,你用什么来生成带有盒子阴影的 Chrome 预览?看起来很不错!

标签: javascript html jquery css css-transforms


【解决方案1】:

我为您的案例创建了一个示例。这从字面上解决了您的问题。您可以在.zoom 类中给出您想要的比例大小。我给了它 1.5。

const pins = document.querySelectorAll(".pin");
const figure = document.querySelector(".figure");
const mapImage = document.querySelector("#mapImage");

pins.forEach(p => {
  p.addEventListener("click", e => {

    figure.style.transformOrigin = `${e.target.getBoundingClientRect().left - e.target.getBoundingClientRect().width / 2}px ${e.target.getBoundingClientRect().top - e.target.getBoundingClientRect().height / 2}px`;


    if (figure.classList.contains("zoom")) {
      figure.style.transition = "transform-origin 0.3s, transform 0.3s";
    } else {
      figure.style.transition = "transform 0.3s";
    }

    figure.classList.add("zoom");
  });
});

document.addEventListener("click", (e) => {
  pins.forEach((p) => {
    let isClickInside = p.contains(event.target);
    if (!isClickInside &&
      !event.target.classList.contains("pin")
    ) {
      figure.style.transition = "transform-origin 0.3s, transform 0.3s";
      figure.style.transformOrigin = '50% 50%';
      figure.classList.remove("zoom");
    }
  });
});
.container {
  width: 800px;
  overflow: hidden;
}

figure {
  width: 100%;
  position: relative;
  transform-origin: 50% 50%;
}

figure img {
  width: 100%;
}

.pin {
  position: absolute;
  height: 75px;
  width: 75px;
  background-color: yellow;
  transition: 0.3s;
  transform-origin: 50% 50%;
}

.pin1 {
  top: 300px;
  left: 550px;
}

.pin2 {
  top: 100px;
  left: 250px;
}

.zoom {
  transform: scale(1.5);
}
<div class="container">
  <figure class="figure">
    <img id="mapImage" src="https://i.redd.it/64xwakxpbae21.jpg">

    <div class="pin pin1">Click me!</div>
    <div class="pin pin2">Another Pin</div>
  </figure>
</div>

另一个:

const pins = document.querySelectorAll(".pin");
const mapImage = document.querySelector("#mapImage");

pins.forEach(p => {
  p.addEventListener("click", e => {

    pins.forEach(pin => {
      pin.classList.remove("pinZoom");
    });

    mapImage.style.transformOrigin = `${e.target.getBoundingClientRect().left - e.target.getBoundingClientRect().width / 2}px ${e.target.getBoundingClientRect().top - e.target.getBoundingClientRect().height / 2}px`;


    if (mapImage.classList.contains("zoom")) {
      mapImage.style.transition = "transform-origin 0.3s, transform 0.3s";
    } else {
      mapImage.style.transition = "transform 0.3s";
    }


    mapImage.classList.add("zoom");
    p.classList.add("pinZoom");

  });
});

document.addEventListener("click", (e) => {
  pins.forEach((p) => {
    let isClickInside = p.contains(event.target);
    if (!isClickInside &&
      !event.target.classList.contains("pin")
    ) {
      mapImage.style.transformOrigin = '50% 50%';
      mapImage.classList.remove("zoom");
      p.classList.remove("pinZoom");
    }
  });
});
figure{
  position: relative;
  width: 800px;
  height: auto;
  overflow: hidden;
}

figure img {
  width: 100%;
  transform-origin: 50% 50%;
}

.pin {
  position: absolute;
  height: 75px;
  width: 75px;
  background-color: yellow;
  transition: 0.3s;
  transform-origin: 50% 50%;
}

.pin1 {
  top: 300px;
  left: 550px;
}

.pin2 {
  top: 100px;
  left: 250px;
}

.zoom {
  transform: scale(1.5);
}

.pinZoom {
  transform: scale(1.3);
}
<figure>
  <img id="mapImage" src="https://i.redd.it/64xwakxpbae21.jpg">
</figure>

<div class="pin pin1">Click me!</div>
<div class="pin pin2">Another Pin</div>

我还使用js-image-zoom 库创建了另一个示例,无需单击。您可以设置缩放、缩放位置、偏移量、缩放宽度和缩放样式。请参阅文档。

var options = {
  width: 800,
  zoomWidth: 800,
  /*
  offset: {
    vertical: 0,
    horizontal: 10
  },
  scale: 2.0,
  */
  zoomPosition: 'original', /* right, top, bottom, left */
};

new ImageZoom(document.getElementById("img-container"), options);
.pin {
  position: absolute;
  height: 75px;
  width: 75px;
  top: 300px;
  left: 550px;
  background-color: yellow;
}

#img-container {
  position: relative;
}
<div id="img-container" style="width: 400px">
  <img src="https://i.redd.it/64xwakxpbae21.jpg" />
<div>

<script src="https://unpkg.com/js-image-zoom@0.7.0/js-image-zoom.js"></script>

【讨论】:

  • 这很酷,但在我的情况下,我需要容器实际捕捉到代表兴趣点的黄色框,而不仅仅是跟踪鼠标
【解决方案2】:

也许像 javacript 在点击时添加 css 这样简单的东西就可以了...

document.getElementsByTagName('img')[0].style.transform = 'translate(-500px,-250px) scale(3)';

我相信您仍然需要手动调整 translate 参数。看看这个: https://codepen.io/pen/jOWamjL

【讨论】:

  • 这很优雅。你知道是否有办法在框坐标(300px,550px)上选择变换(-500px,-250px)?
  • 我这样做的方法是:我从 pin div 的 lefttop 属性中取出 50px,然后乘以 -1。我不知道它是否适用于您需要的每个别针 - 我会小心靠近边界的别针。
  • 谢谢@Rafael。我最终将赏金授予 dgknca,因为我更熟悉 CSS,但我认为这也是一个非常优雅的解决方案
【解决方案3】:
<html>
    <head>
        <link rel="stylesheet" href="example.css">
    </head>
    <body>
        <div class="big">
            <div class="small"></div>
        </div>
    </body>
</html>

let small = document.querySelector('.small')

let shiftX = null
let shiftY = null

let getCoords = (elem) => { 
    let box = elem.getBoundingClientRect()
      return {
        top: box.top + pageYOffset,
        left: box.left + pageXOffset
      }
   }
}

small.addEventListener('mousedown', evt => {
  evt.preventDefault()
  small.classList.add('test')
  small.style.position = 'absolute'
  let coords = getCoords(small)
  let shiftX = evt.pageX - coords.left
  let shiftY = evt.pageY - coords.top
})

small.addEventListener('mousemove', evt => {
  evt.preventDefault()
  small.style.left = evt.pageX - shiftX + 'px'
  small.style.top = evt.pageY - shiftY + 'px'
})

small.addEventListener('mouseup', evt => {
  evt.preventDefault()
  small.classList.remove('test')
})

.test {
    transform: scale(2);
}

【讨论】:

  • 在这种情况下,我需要蓝色方块来实际缩放/平移到绿色方块,类似于 Google 地图在您点击它们时缩放/平移到特定位置的方式。看起来这个脚本只是让绿色方块变大。
  • mm,你需要拖拽
  • 我不熟悉那个功能
  • 我不想拖拽方块,我想放大它
【解决方案4】:

您需要使用 Jquery 添加一个事件“点击”并切换类“支出”,例如为您的广场添加样式:

https://codepen.io/ZellRDesign/pen/NWxpmdd

var square = $(".square")

square.click(function(){
  console.log("salut")
  square.toggleClass("expend")
})
.square{
  height: 100px;
  width: 100px;
  background-color: green;
  transition: .3s;
} 

.square.expend{
  height: 200px;
  width: 200px;
  transition: .3s;
  background-color: red;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="square"></div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</body>
</html>

【讨论】:

  • 看起来这个 sn-p 只是让正方形变大,在我的应用程序中我需要 div 来实际放大它
猜你喜欢
  • 2015-08-11
  • 2020-06-08
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
  • 2015-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多