了解中使用的阻力贴图功能http://urban-walks.com/#map.

Understanding Drag map functionality used in http://urban-walks.com/#map

本文关键字:功能 http urban-walks #map com 了解      更新时间:2023-09-26

我试图了解他们在拖动映射功能中使用了什么样的JS,但无法理解。

如果有人能理解,请告诉我,因为我想在我的一个网站上复制相同的功能。

提前感谢。:)

请参阅使用名为jQuery图像平移的插件完成的以下功能。

我使用了多实例同步示例作为参考。

$.fn.imagePanning = function() {
  var init = "center",
    speed = 800, //animation/tween speed
    sync = ".sync", //synchronized instances selector (leave empty for no sync)
    //custom js tween
    _tweenTo = function(el, prop, to, duration, easing, overwrite) {
      if (!el._mTween) {
        el._mTween = {
          top: {},
          left: {}
        };
      }
      var startTime = _getTime(),
        _delay, progress = 0,
        from = el.offsetTop,
        elStyle = el.style,
        _request, tobj = el._mTween[prop];
      if (prop === "left") {
        from = el.offsetLeft;
      }
      var diff = to - from;
      if (overwrite !== "none") {
        _cancelTween();
      }
      _startTween();
      function _step() {
        progress = _getTime() - startTime;
        _tween();
        if (progress >= tobj.time) {
          tobj.time = (progress > tobj.time) ? progress + _delay - (progress - tobj.time) : progress + _delay - 1;
          if (tobj.time < progress + 1) {
            tobj.time = progress + 1;
          }
        }
        if (tobj.time < duration) {
          tobj.id = _request(_step);
        }
      }
      function _tween() {
        if (duration > 0) {
          tobj.currVal = _ease(tobj.time, from, diff, duration, easing);
          elStyle[prop] = Math.round(tobj.currVal) + "px";
        } else {
          elStyle[prop] = to + "px";
        }
      }
      function _startTween() {
        _delay = 1000 / 60;
        tobj.time = progress + _delay;
        _request = (!window.requestAnimationFrame) ? function(f) {
          _tween();
          return setTimeout(f, 0.01);
        } : window.requestAnimationFrame;
        tobj.id = _request(_step);
      }
      function _cancelTween() {
        if (tobj.id == null) {
          return;
        }
        if (!window.requestAnimationFrame) {
          clearTimeout(tobj.id);
        } else {
          window.cancelAnimationFrame(tobj.id);
        }
        tobj.id = null;
      }
      function _ease(t, b, c, d, type) {
        var ts = (t /= d) * t,
          tc = ts * t;
        return b + c * (0.499999999999997 * tc * ts + -2.5 * ts * ts + 5.5 * tc + -6.5 * ts + 4 * t);
      }
      function _getTime() {
        if (window.performance && window.performance.now) {
          return window.performance.now();
        } else {
          if (window.performance && window.performance.webkitNow) {
            return window.performance.webkitNow();
          } else {
            if (Date.now) {
              return Date.now();
            } else {
              return new Date().getTime();
            }
          }
        }
      }
    };
  return this.each(function() {
    var $this = $(this),
      timer, el;
    if ($this.data("imagePanning")) return;
    $this.data({
        "imagePanning": 1,
        "imagePanningDest": 0
      })
      //create markup
      .wrap("<div class='img-pan-container' />")
      .after("<div class='resize' style='position:absolute; width:auto; height:auto; top:0; right:0; bottom:0; left:0; margin:0; padding:0; overflow:hidden; visibility:hidden; z-index:-1'><iframe style='width:100%; height:0; border:0; visibility:visible; margin:0' /><iframe style='width:0; height:100%; border:0; visibility:visible; margin:0' /></div>")
      //image loaded fn
      .one("load", function() {
        setTimeout(function() {
          $this.addClass("loaded").trigger("mousemove", 1);
        }, 1);
      }).each(function() { //run load fn even if cached
        if (this.complete) $(this).load();
      })
      //panning fn
      .parent().on("mousemove touchmove MSPointerMove pointermove", function(e, p) {
        var cont = $(this);
        e.preventDefault();
        var contH = cont.height(),
          contW = cont.width(),
          isTouch = e.type.indexOf("touch") !== -1,
          isPointer = e.type.indexOf("pointer") !== -1,
          evt = isPointer ? e.originalEvent : isTouch ? e.originalEvent.touches[0] || e.originalEvent.changedTouches[0] : e,
          coords = [!p ? evt.pageY - cont.offset().top : init === "center" ? contH / 2 : 0, !p ? evt.pageX - cont.offset().left : init === "center" ? contW / 2 : 0];
        (sync ? $(sync).find("img") : $this) //check sync
        .data({
          "imagePanningDest": [Math.round(($this.outerHeight(true) - contH) * (coords[0] / contH)), Math.round(($this.outerWidth(true) - contW) * (coords[1] / contW))]
        });
      })
      //resize fn
      .find(".resize iframe").each(function() {
        $(this.contentWindow || this).on("resize", function() {
          $this.trigger("mousemove", 1);
        });
      });
    //panning animation 60FPS
    if (timer) clearInterval(timer);
    timer = setInterval(function() {
      _tweenTo($this[0], "top", -$this.data("imagePanningDest")[0], speed);
      _tweenTo($this[0], "left", -$this.data("imagePanningDest")[1], speed);
    }, 16.6);
  });
}
$(document).ready(function() {
  $(".content img").imagePanning();
});
.content {
    width: 800px;
    height: 600px;
    overflow: hidden;
}
.content img {
    opacity: 0;
    transition: opacity .6s linear .8s;
}
.content img.loaded {
    opacity: 1;
}
.img-pan-container, .img-pan-container img {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
.img-pan-container {
    position: relative;
    overflow: hidden;
    cursor: crosshair;
    height: 100%;
    width: 100%;
}
.img-pan-container img {
    -webkit-transform: translateZ(0);
    -ms-transform: translateZ(0);
    transform: translateZ(0);
    position: absolute;
    top: 0;
    left: 0;
}
.boxed {
    width: 183px;
    height: 200px;
    top: 10%;
    position: absolute;
    left: 10%;
    border: 8px black solid;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content sync">
  <img src="http://urban-walks.com/static/img/slider/map/map-dark_3000.jpg" />
</div>
<div class="content boxed sync">
  <img src="http://urban-walks.com/static/img/slider/map/map-light_3000.jpg" />
</div>

演示:http://jsfiddle.net/kishoresahas/d7vkz0ke