【问题标题】:Move (drag/pan) and zoom object (image or div) in pure js在纯 js 中移动(拖动/平移)和缩放对象(图像或 div)
【发布时间】:2016-05-17 02:07:58
【问题描述】:

我正在编写一个小脚本,使对象(div 或 img)在给定框架内可移动和可缩放。

但是我遇到了一些我不太确定的问题,因为我是 javascript 初学者 - 所以解释为什么会出现这些问题将不胜感激。

问题:

  1. 调用函数start_drag()while_drag()stop_drag() 返回undefined - 这是为什么呢?应该退回什么?
  2. 图像的拖动和移动不能正常工作 - 我没有单击鼠标按钮开始移动图像,而是单击一次然后开始移动。虽然我将mousedown 事件绑定到图像。我做错了什么?
  3. 为什么移动部分不能在移动设备上工作(缩放工作!)?

请看我的小提琴:https://jsfiddle.net/pow4ngbw/15/

【问题讨论】:

  • 您的 start_drag()、while_drag() 和 stop_drag() 函数不会显式返回任何内容,因此它们“返回”未定义...
  • 它在移动设备上不起作用,因为它没有触摸事件
  • 感谢@ronapelbaum - 但是我需要在香草js而不是jquery中拥有它

标签: javascript zooming move drag pan


【解决方案1】:

现在工作正常,主要是图像 css 但发现了几个错误(请参阅新的 img 属性),还添加了一些调整以使拖动更平滑。

 
    var img_ele = null,
      x_cursor = 0,
      y_cursor = 0,
      x_img_ele = 0,
      y_img_ele = 0;
    
    function zoom(zoomincrement) {
      img_ele = document.getElementById('drag-img');
      var pre_width = img_ele.getBoundingClientRect().width, pre_height = img_ele.getBoundingClientRect().height;
      img_ele.style.width = (pre_width * zoomincrement) + 'px';
      img_ele.style.height = (pre_height * zoomincrement) + 'px';
      img_ele = null;
    }
    
    document.getElementById('zoomout').addEventListener('click', function() {
      zoom(0.5);
    });
    document.getElementById('zoomin').addEventListener('click', function() {
      zoom(1.5);
    });
    
    function start_drag() {
      img_ele = this;
      x_img_ele = window.event.clientX - document.getElementById('drag-img').offsetLeft;
      y_img_ele = window.event.clientY - document.getElementById('drag-img').offsetTop;
      
    }
    
    function stop_drag() {
      img_ele = null;
    }
    
    function while_drag() {
      var x_cursor = window.event.clientX;
      var y_cursor = window.event.clientY;
      if (img_ele !== null) {
        img_ele.style.left = (x_cursor - x_img_ele) + 'px';
        img_ele.style.top = ( window.event.clientY - y_img_ele) + 'px';
        
          console.log(img_ele.style.left+' - '+img_ele.style.top);
    
      }
    }
    
    document.getElementById('drag-img').addEventListener('mousedown', start_drag);
    document.getElementById('container').addEventListener('mousemove', while_drag);
    document.getElementById('container').addEventListener('mouseup', stop_drag);
 #drag-img {
      cursor: move;
      position: relative;
      width: 500px;
      height: 500px;
    }
    
    #container {
      overflow: hidden;
      background: red;
      height: 500px;
      width: 500px;
    }
    
    .button {
      width: 200px;
      height: 50px;
    }
 <div id="container">
      <img ondragstart="return false" id="drag-img" src="http://www.patsoy.com/p/2015/09/geometric-patterns-f03phtdx.jpg" />
    </div>
    <input type="button" id="zoomout" class="button" value="Zoom out">
    <input type="button" id="zoomin" class="button" value="Zoom in">
  

【讨论】:

  • 没有添加触摸事件,所以仍然无法在手机上运行
  • 非常感谢@Bug!我做了一个新的小提琴jsfiddle.net/azyb9mzz 你能解释一下为什么你把事件监听器连接到容器 div 而不是 img 对象本身吗?我尝试向它添加触摸事件(touchstarttouchmovetouchend)——这似乎部分有效,因为我得到了正确的控制台警报。但是图像的样式位置没有更新,因此没有移动......但是为什么呢?
  • 基于@Bug 的工作,我实现了触摸功能:jsfiddle.net/j8kLz6wm/1再次感谢!
  • 我加入了容器事件,因为如果你快速移动鼠标,拖拽就会停止,最好使用 body 的事件
  • 我注意到当你第一次开始拖动时有轻微的跳跃,在你的 start_drag 事件中为 x_img_ele 和 y_img_ele 添加 +8
【解决方案2】:

我采用了 Bug 的代码并添加了我需要的功能,并且在 cmets 中被要求。我已将其更新为:缩放或平移时始终将图像保留在容器内,并将实现封装在 zoomer 对象内以保持全局环境清洁。

<!DOCTYPE html>
<html>
<head>
<style>
#zoom-img {
  cursor: move;
  position: relative;
  width: 500px;
  height: 500px;
}

#zoom-container {
  overflow: hidden;
  background: red;
  height: 500px;
  width: 500px;
}

.button {
  width: 100px;
  height: 50px;
}
</style>
</head>
<body id="fullbody">
<div id="zoom-container">
  <img ondragstart="return false" id="zoom-img" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Cordillera_de_los_Andes.jpg/1024px-Cordillera_de_los_Andes.jpg" />
</div>
<input type="button" id="zoomout" class="button" value="Zoom out">
<input type="button" id="zoomin" class="button" value="Zoom in">
</body>
</html>
<script>
//
//    This file is derived from the javascript portion of the drag-zoom example
//    at the web site: 
//     https://stackoverflow.com/questions/35252249/move-drag-pan-and-zoom-object-image-or-div-in-pure-js
//

var zoomer = (function () {
    var img_ele = null,
      x_cursor = 0,
      y_cursor = 0,
      x_img_ele = 0,
      y_img_ele = 0,
      orig_width = document.getElementById('zoom-img').getBoundingClientRect().width,
      orig_height = document.getElementById('zoom-img').getBoundingClientRect().height,
      current_top = 0,
      current_left = 0,
      zoom_factor = 1.0;

    return {
        zoom: function (zoomincrement) {
            img_ele = document.getElementById('zoom-img');
            zoom_factor = zoom_factor + zoomincrement;
            if (zoom_factor <= 1.0)
            {
                zoom_factor = 1.0;
                img_ele.style.top =  '0px';    
                img_ele.style.left = '0px';
            }
            var pre_width = img_ele.getBoundingClientRect().width, pre_height = img_ele.getBoundingClientRect().height;
            console.log('prewidth='+img_ele.getBoundingClientRect().width+'; pre_height ='+img_ele.getBoundingClientRect().height);
        //  img_ele.style.width = (pre_width * zoomincrement) + 'px';
        //  img_ele.style.height = (pre_height * zoomincrement) + 'px';
            var new_width = (orig_width * zoom_factor);
            var new_heigth = (orig_height * zoom_factor);

                console.log('postwidth='+img_ele.style.width+'; postheight ='+img_ele.style.height);

            if (current_left < (orig_width - new_width))
            {
                current_left = (orig_width - new_width);
            }
            if (current_top < (orig_height - new_heigth))
            {
                current_top = (orig_height - new_heigth);
            }
            img_ele.style.left = current_left + 'px';
            img_ele.style.top = current_top + 'px';
            img_ele.style.width = new_width + 'px';
            img_ele.style.height = new_heigth + 'px';

            img_ele = null;
        },

        start_drag: function () {
          if (zoom_factor <= 1.0)
          {
             return;
          }
          img_ele = this;
          x_img_ele = window.event.clientX - document.getElementById('zoom-img').offsetLeft;
          y_img_ele = window.event.clientY - document.getElementById('zoom-img').offsetTop;
          console.log('img='+img_ele.toString()+'; x_img_ele='+x_img_ele+'; y_img_ele='+y_img_ele+';')
          console.log('offLeft='+document.getElementById('zoom-img').offsetLeft+'; offTop='+document.getElementById('zoom-img').offsetTop)
        },

        stop_drag: function () {
          if (img_ele !== null) {
            if (zoom_factor <= 1.0)
            {
              img_ele.style.left = '0px';
              img_ele.style.top =  '0px';      
            }
            console.log(img_ele.style.left+' - '+img_ele.style.top);
            }
          img_ele = null;
        },

        while_drag: function () {
            if (img_ele !== null)
            {
                var x_cursor = window.event.clientX;
                var y_cursor = window.event.clientY;
                var new_left = (x_cursor - x_img_ele);
                if (new_left > 0)
                {
                    new_left = 0;
                }
                if (new_left < (orig_width - img_ele.width))
                {
                    new_left = (orig_width - img_ele.width);
                }
                var new_top = ( y_cursor - y_img_ele);
                if (new_top > 0)
                {
                    new_top = 0;
                }
                if (new_top < (orig_height - img_ele.height))
                {
                    new_top = (orig_height - img_ele.height);
                }
                current_left = new_left;
                img_ele.style.left = new_left + 'px';
                current_top = new_top;
                img_ele.style.top = new_top + 'px';

                //console.log(img_ele.style.left+' - '+img_ele.style.top);
            }
        }
    };
} ());

document.getElementById('zoomout').addEventListener('click', function() {
  zoomer.zoom(-0.25);
});
document.getElementById('zoomin').addEventListener('click', function() {
  zoomer.zoom(0.25);
});

document.getElementById('zoom-img').addEventListener('mousedown', zoomer.start_drag);
document.getElementById('zoom-container').addEventListener('mousemove', zoomer.while_drag);
document.getElementById('zoom-container').addEventListener('mouseup', zoomer.stop_drag);
document.getElementById('zoom-container').addEventListener('mouseout', zoomer.stop_drag);

</script>

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 2018-12-13
    • 2013-05-28
    • 2012-12-11
    • 2023-03-27
    • 2010-10-19
    • 2016-07-22
    • 1970-01-01
    相关资源
    最近更新 更多