基于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 相关文章推荐
javascript 日期时间函数(经典+完善+实用)
May 27 Javascript
Js 刷新框架页的代码
Apr 13 Javascript
IE下使用jQuery重置iframe地址时内存泄露问题解决办法
Feb 05 Javascript
JS上传组件FileUpload自定义模板的使用方法
May 10 Javascript
jQuery事件用法详解
Oct 06 Javascript
关于js函数解释(包括内嵌,对象等)
Nov 20 Javascript
Html5+jQuery+CSS制作相册小记录
Dec 30 Javascript
jQuery插件HighCharts实现气泡图效果示例【附demo源码】
Mar 13 Javascript
JavaScript如何一次性展示几万条数据
Mar 30 Javascript
vue最简单的前后端交互示例详解
Oct 11 Javascript
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
Jun 18 jQuery
判断JavaScript中的两个变量是否相等的操作符
Dec 21 Javascript
微信小程序车牌号码模拟键盘输入功能的实现代码
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
这部好评如潮的动漫 知名梗频出 但是画风劝退很多人
2020/03/08 日漫
PHP APC配置文件2套和参数详解
2014/06/11 PHP
php生成二维码
2015/08/10 PHP
PHP实现链式操作的原理详解
2016/09/16 PHP
PHP实现根据数组的值进行分组的方法
2017/04/20 PHP
thinkphp分页集成实例
2017/07/24 PHP
Laravel框架路由和控制器的绑定操作方法
2018/06/12 PHP
为jQuery.Treeview添加右键菜单的实现代码
2010/10/22 Javascript
js获取对象为null的解决方法
2013/11/21 Javascript
自定义Angular指令与jQuery实现的Bootstrap风格数据双向绑定的单选与多选下拉框
2015/12/12 Javascript
jQuery数据类型小结(14个)
2016/01/08 Javascript
学习JavaScript设计模式之装饰者模式
2016/01/19 Javascript
jQuery动态添加可拖动元素完整实例(附demo源码下载)
2016/06/21 Javascript
jquery实现焦点轮播效果
2017/02/23 Javascript
JS二叉树的简单实现方法示例
2017/04/05 Javascript
Vue实现选择城市功能
2017/05/27 Javascript
详解react-native-fs插件的使用以及遇到的坑
2017/09/12 Javascript
Vue中CSS动画原理的实现
2019/02/13 Javascript
用Fundebug插件记录网络请求异常的方法
2019/02/21 Javascript
原生js实现点击按钮复制内容到剪切板
2020/11/19 Javascript
如何使用 JavaScript 操作浏览器历史记录 API
2020/11/24 Javascript
[41:52]DOTA2-DPC中国联赛 正赛 CDEC vs Dynasty BO3 第二场 2月22日
2021/03/11 DOTA
利用python发送和接收邮件
2016/09/27 Python
python实现excel读写数据
2021/03/02 Python
Python解决走迷宫问题算法示例
2018/07/27 Python
Python爬虫实现获取动态gif格式搞笑图片的方法示例
2018/12/24 Python
对python特殊函数 __call__()的使用详解
2019/07/02 Python
python tkinter窗口最大化的实现
2019/07/15 Python
HTML5新增加标签和功能概述
2016/09/05 HTML / CSS
墨西哥网上超市:Superama
2018/07/10 全球购物
意大利奢侈品多品牌集合店:TheDoubleF
2019/08/24 全球购物
会计专业自我评价
2014/02/12 职场文书
学校元旦晚会开场白
2015/05/29 职场文书
《你在为谁工作》心得体会(共8篇)
2016/01/20 职场文书
python实现socket简单通信的示例代码
2021/04/13 Python
MySQL外键约束(Foreign Key)案例详解
2022/06/28 MySQL