基于Vue实现图片在指定区域内移动的思路详解


Posted in Javascript onNovember 11, 2018

  当图片比要显示的区域大时,需要将多余的部分隐藏掉,我们可以通过绝对定位来实现,并通过动态修改图片的left值和top值从而实现图片的移动。具体实现效果如下图,如果我们移动的是div 实现思路相仿。

基于Vue实现图片在指定区域内移动的思路详解

此处需要注意的是

我们在移动图片时,需要通过draggable="false" 将图片的 <img src="/static/pano-dev/test/image-2.jpg" draggable="false" />,否则按下鼠标监听onmousemove事件时监听不到

然后还需要禁用图片的选中css

/*禁止元素选中*/
-moz-user-select: none; /*火狐*/
-webkit-user-select: none; /*webkit浏览器*/
-ms-user-select: none; /*IE10*/
-khtml-user-select: none; /*早期浏览器*/
user-select: none;

Vue 代码

<style lang="less" scoped>
@import url("./test.less");
</style>
<template>
 <div class="page">
  <div class="image-move-wapper">
   <div class="image-show-box" ref="imageShowBox">
    <div class="drag-container" ref="dragContainer" :style="'left:' + dragContainer.newPoint.left+'px; top:' + dragContainer.newPoint.top+'px'" @mousedown="DragContainerMouseDown">
     <div class="drag-image-box">
      <img src="/static/pano-dev/test/image-2.jpg" draggable="false" />
      <div class="point" style="left:10%; top:10%" @mousedown="PointMouseDown"></div>
     </div>
    </div>
   </div>
  </div>
 </div>
</template>
<script>
export default {
 data() {
  return {
   dragContainer: {
    box: {
     w: 0,
     h: 0
    },
    point: {
     left: 0,
     top: 0
    },
    newPoint: {
     left: 0,
     top: 0
    }
   },
   mousePoint: {
    x: 0,
    y: 0
   },
   imageShowBox: {
    box: {
     w: 0,
     h: 0
    },
    dragcheck: {
     h: true,
     v: true
    }
   }
  };
 },
 updated() {
  let _this = this;
  // 确保DOM元素已经渲染成功,然后获取拖拽容器和显示区域的大小
  _this.$nextTick(function() {
   _this.dragContainer.box = {
    w: _this.$refs.dragContainer.offsetWidth,
    h: _this.$refs.dragContainer.offsetHeight
   };
   _this.imageShowBox.box = {
    w: _this.$refs.imageShowBox.offsetWidth,
    h: _this.$refs.imageShowBox.offsetHeight
   };
   // 判断是否允许拖拽
   _this.imageShowBox.dragcheck = {
    h: _this.imageShowBox.box.w > _this.dragContainer.box.w ? false : true,
    v: _this.imageShowBox.box.h > _this.dragContainer.box.h ? false : true
   };
  });
 },
 methods: {
  // 鼠标在拖拽容器中按下时触发
  DragContainerMouseDown(e) {
   const _this = this;
   // 记录鼠标点击时的初始坐标
   this.mousePoint = {
    x: e.clientX,
    y: e.clientY
   };
   _this.dragContainer.point = _this.dragContainer.newPoint;
   document.body.onmousemove = _this.DragContainerMouseMove;
   document.onmouseup = _this.DragContainerMouseUp;
   return false;
  },
  // 容器拖拽时触发
  DragContainerMouseMove(e) {
   const _this = this;
   // 鼠标偏移量 = 初始坐标 - 当前坐标
   let dx = e.clientX - _this.mousePoint.x;
   let dy = e.clientY - _this.mousePoint.y;
   // 获取拖拽容器移动后的left和top值
   if (_this.imageShowBox.dragcheck.h)
    var newx = dx > 0 ? Math.min(0, _this.dragContainer.point.left + dx) : Math.max(- _this.dragContainer.box.w + _this.imageShowBox.box.w, _this.dragContainer.point.left + dx );
   if (_this.imageShowBox.dragcheck.v)
    var newy = dy > 0 ? Math.min(0, _this.dragContainer.point.top + dy) : Math.max(- _this.dragContainer.box.h + _this.imageShowBox.box.h, _this.dragContainer.point.top + dy );
   _this.dragContainer.newPoint = {
    left: typeof newx != 'undefined' ? newx : _this.dragContainer.point.left,
    top: typeof newy != 'undefined' ? newy : _this.dragContainer.point.top
   };
   console.log(_this.dragContainer.newPoint);
   return false;
  },
  // 移动完成 取消onmousemove和onmouseup事件
  DragContainerMouseUp(e) {
   document.body.onmousemove = null;
   document.onmouseup = null;
  },
  PointMouseDown(e) {
   //阻止事件冒泡
   e.stopPropagation();
  }
 }
};
</script>

样式表

.page {
 background: #444;
 width: 100%;
 height: 100%;
 position: relative;
 .image-move-wapper {
  position: absolute;
  right: 50px;
  top: 50px;
  background: #fff;
  box-shadow: rgba(255, 255, 255, 0.5);
  padding: 10px;
 }
 .image-show-box {
  height: 400px;
  width: 400px;
  cursor: move;
  overflow: hidden;
  position: relative;
  .drag-container {
   position: absolute;
   left: 0px;
   top: 0;
   /*禁止元素选中*/
   -moz-user-select: none; /*火狐*/
   -webkit-user-select: none; /*webkit浏览器*/
   -ms-user-select: none; /*IE10*/
   -khtml-user-select: none; /*早期浏览器*/
   user-select: none;
   .drag-image-box {
    position: relative;
    .point {
     position: absolute;
     background: red;
     height: 30px;
     width: 30px;
     border-radius: 50%;
    }
   }
  }
 }
}

总结

以上所述是小编给大家介绍的基于Vue实现图片在指定区域内移动的思路详解,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
innerhtml用法 innertext用法 以及innerHTML与innertext的区别
Oct 26 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
Aug 12 Javascript
jquery带动画效果幻灯片特效代码
Aug 27 Javascript
js+ajax实现获取文件大小的方法
Dec 08 Javascript
JavaScript高级程序设计(第三版)学习笔记1~5章
Mar 11 Javascript
jquery分页插件jquery.pagination.js使用方法解析
Apr 01 Javascript
jQuery 3.0中存在问题及解决办法
Jul 15 Javascript
js通过keyCode值判断单击键盘上某个键,然后触发指定的事件方法
Feb 19 Javascript
Vuex和前端缓存的整合策略详解
May 09 Javascript
Vue项目中quill-editor带样式编辑器的使用方法
Aug 08 Javascript
bootstrap table合并行数据并居中对齐效果
Oct 17 Javascript
Vue实现多页签组件
Jan 14 Vue.js
微信小程序车牌号码模拟键盘输入功能的实现代码
Nov 11 #Javascript
详解Vue 动态组件与全局事件绑定总结
Nov 11 #Javascript
详解如何在vue项目中使用eslint+prettier格式化代码
Nov 10 #Javascript
AngularJS上传文件的示例代码
Nov 10 #Javascript
详解vue-cli 3.0 build包太大导致首屏过长的解决方案
Nov 10 #Javascript
优雅的在React项目中使用Redux的方法
Nov 10 #Javascript
Vue组件之单向数据流的解决方法
Nov 10 #Javascript
You might like
同一空间绑定多个域名而实现访问不同页面的PHP代码
2006/12/06 PHP
使用GROUP BY的时候如何统计记录条数 COUNT(*) DISTINCT
2011/04/23 PHP
PHP无限分类(树形类)
2013/09/28 PHP
[原创]php求圆周率的简单实现方法
2016/05/30 PHP
用javascript实现画板的代码
2007/09/05 Javascript
js和jquery设置disabled属性为true使按钮失效
2014/08/07 Javascript
js跨域问题浅析及解决方法优缺点对比
2014/11/08 Javascript
js的window.showModalDialog及window.open用法实例分析
2015/01/29 Javascript
轻松实现JavaScript图片切换
2016/01/12 Javascript
Node.js使用NodeMailer发送邮件实例代码
2017/03/06 Javascript
nodejs构建本地web测试服务器 如何解决访问静态资源问题
2017/07/14 NodeJs
Chrome调试折腾记之JS断点调试技巧
2017/09/11 Javascript
vue+socket.io+express+mongodb 实现简易多房间在线群聊示例
2017/10/21 Javascript
微信小程序获取位置展示地图并标注信息的实例代码
2019/09/01 Javascript
[02:48]DOTA2超级联赛专访海涛:你们的选择没有错
2013/06/07 DOTA
[03:55]DOTA2完美大师赛选手传记——LFY.MONET
2017/11/18 DOTA
[58:18]2018DOTA2亚洲邀请赛3月29日 小组赛B组 iG VS Mineski
2018/03/30 DOTA
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python深入学习之对象的属性
2014/08/31 Python
python装饰器简介---这一篇也许就够了(推荐)
2019/04/01 Python
django 信号调度机制详解
2019/07/19 Python
详解Python直接赋值,深拷贝和浅拷贝
2020/07/09 Python
基于python模拟TCP3次握手连接及发送数据
2020/11/06 Python
关于CSS Tooltips(鼠标经过时显示)的效果
2013/04/10 HTML / CSS
世界领先的26岁以下学生和青少年旅行预订网站:StudentUniverse
2018/07/01 全球购物
介绍一下ICMP(Internet Control Message Protocol)Internet控制信息协议
2016/11/26 面试题
小学生期末自我鉴定
2014/01/19 职场文书
行政专员的岗位职责
2014/03/10 职场文书
法人委托书的范本格式
2014/09/11 职场文书
2015初中政治教学工作总结
2015/07/21 职场文书
毕业班工作总结
2015/08/10 职场文书
检讨书之工作不认真
2019/08/14 职场文书
Nginx本地目录映射实现代码实例
2021/03/31 Servers
MySQL 自定义变量的概念及特点
2021/05/13 MySQL
「回转企鹅罐」10周年纪念展「輪るピングドラム展」海报公开
2022/03/22 日漫
netty 实现tomcat的示例代码
2022/06/05 Servers