纯Javascript如何在mousemove上放大图像?

时间:2016-06-08 09:36:26

标签: javascript html css

我正在尝试在图像中创建onmousemove事件,然后在右侧显示缩放图像。

问题:

  1. 当我尝试鼠标移动到图像内部时,黑框和缩放图像闪烁。
  2. 黑框中的缩放图像不匹配。
  3. 我该怎么做?可能计算错了。

    这是我的代码。

    <div>
        <div id="cursor" style="background:black; opacity:0.5; width:100px; height:100px; position:absolute; display:none">
    
        </div>
        <div style="float:left;">
            <img id="img" src="http://www.animenewsnetwork.com/thumbnails/cover400x200/cms/news/102950/26902290903_3c8f2db0ea_b.jpg" onmousemove="getPos(event)" onmouseout="stopTracking()"/>
        </div>
        <div id="zoom" style="width:300px; height:300px; zoom:1; float:left;">
            qwe
        </div>
    </div>
    <script>
        function getPos(e){
            var x = e.clientX;
            var y = e.clientY;
            var width = document.getElementById("img").clientWidth;
            var height = document.getElementById("img").clientHeight;
    
            document.getElementById("cursor").style.left = x - 50;
            document.getElementById("cursor").style.top = y - 50;
            document.getElementById("cursor").style.display = "inline-block";
    
            document.getElementById("zoom").style.background = "url('http://www.animenewsnetwork.com/thumbnails/cover400x200/cms/news/102950/26902290903_3c8f2db0ea_b.jpg') "+x / width * 100+"% "+y / width * 100+"%";
        }
    
        function stopTracking(){
            document.getElementById("cursor").style.display = "none";
            document.getElementById("zoom").style.background = "transparent";
        }
    </script>
    

    感谢高级。

2 个答案:

答案 0 :(得分:2)

我加了半秒的时间延迟,眨眼就消失了。

    function getPos(e){


    var delay=500; //1/2  second

    setTimeout(function() {
      //your code to be executed after 1/2 second
    var x = e.clientX;
    var y = e.clientY;
    var width = document.getElementById("img").clientWidth;
    var height = document.getElementById("img").clientHeight;

    document.getElementById("cursor").style.left = x - 50;
    document.getElementById("cursor").style.top = y - 50;
    document.getElementById("cursor").style.display = "inline-block";
    document.getElementById("zoom").style.background = "url('http://www.animenewsnetwork.com/thumbnails/cover400x200/cms/news/102950/26902290903_3c8f2db0ea_b.jpg') "+x / width * 100+"% "+y / width * 100+"%";
    }, delay);


}

答案 1 :(得分:0)

从我的电子商务项目中捕获源代码(我正在使用GSAP动画库,您可以创建带有过渡的自定义CSS类):

<div class="grid col-10 rel z300">
  <div class="border padt20 padb20 padl20 padr20 zoom--in flex align-center">
    <img class="auto" src="img/prod.jpg" data-zoom="img/prod-large.jpg" alt="">
  </div>
</div>


export class zoom_in_gallery {
  constructor() {
    if (!this.setVars()) return;
    this.setEvents();
  }

  setVars() {
    let _this = this;

    _this.zoom = document.body.getElementsByTagName('section')[0].getElementsByClassName('zoom--in')[0];
    if (!this.zoom) return false;

    _this.img = this.zoom.firstElementChild;
    if (!this.img) return false;

    _this.zoom_pop = false;
    _this.act = false;

    return true;
  }

  setEvents() {
    let _this = this;

    function del(el) => {
      el = typeof el === 'string' ? document.body.getElementsByClassName(el)[0] : el;

      if (!el || !el.parentNode) return;
      return el.parentNode.removeChild(el);
    }

    this.obj.onmove = (e) => {
      if (_this.act) return;
      let y = e.offsetY ? (e.offsetY) : e.pageY - _this.img.offsetTop,
        x = e.offsetX ? (e.offsetX) : e.pageX - _this.img.offsetLeft;

      if (!_this.zoom_pop) {
        _this.zoom_pop = _this.render(e.target.parentNode, `<div class="top0 right0 abs o-hidden border" style="right:calc(-70%);left:initial;height:${_this.zoom.offsetWidth / 1.5}px;width:${_this.zoom.offsetWidth / 1.5}px"><div style="width:100%;height:100%;background: #fff url(${_this.img.dataset.zoom}) 0 0 / cover scroll no-repeat"></div></div>`);
        TweenLite.fromTo(_this.zoom_pop, .3, {autoAlpha: 0}, {autoAlpha: 1});
      }

      _this.zoom_pop.firstElementChild.style.backgroundPosition = `${x / 3.8}% ${y / 3.8}%`;
    };

    this.obj.onleave = () => {
      if (!_this.zoom_pop || _this.act) return;
      _this.act = true;

      TweenLite.to(_this.zoom_pop, .3, {
        autoAlpha: 0, onComplete: () => {
         del(_this.zoom_pop);
         _this.zoom_pop = false;
         _this.act = false;
        }
      });
    };

    this.zoom.addEventListener('mousemove', this.obj.onmove);
    this.zoom.addEventListener('mouseout', this.obj.onleave);
  }

  render(relEl, tpl, cfg = {}) {
    if (!relEl) return;
    const parse = typeof cfg.parse === 'undefined' ? true : cfg.parse, child;

    if (tpl.nodeName === 'TEMPLATE') {
      child = document.importNode(tpl.content, true);
    } else if (typeof tpl === 'string') {
      const range = document.createRange();
      range.selectNode(relEl);
      child = range.createContextualFragment(tpl);
    } else {
      child = tpl;
    }

    if (parse) {
      relEl.appendChild(child);
      return relEl.lastElementChild;
    }
    return {rel: relEl, el: child};
  }
}