基于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 相关文章推荐
node.js中的path.normalize方法使用说明
Dec 08 Javascript
JavaScript中Date对象的常用方法示例
Oct 24 Javascript
RequireJS多页面应用实例分析
Jun 29 Javascript
Node.js和Express简单入门介绍
Mar 24 Javascript
详解如何使用 vue-cli 开发多页应用
Dec 16 Javascript
Express之托管静态文件的方法
Jun 01 Javascript
使用Angular-CLI构建NPM包的方法
Sep 07 Javascript
React 使用recharts实现散点地图的示例代码
Dec 07 Javascript
解决vue组件props传值对象获取不到的问题
Jun 06 Javascript
CountUp.js数字滚动插件使用方法详解
Oct 17 Javascript
js实现文章目录索引导航(table of content)
May 10 Javascript
解决vue里a标签值解析变量,跳转页面,前面加默认域名端口的问题
Jul 22 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
php懒人函数 自动添加数据
2011/06/28 PHP
php自动给文章加关键词链接的函数代码
2012/11/29 PHP
PHP常用的缓存技术汇总
2014/05/05 PHP
PHP生成指定长度随机数最简洁的方法
2014/07/14 PHP
php中FTP函数ftp_connect、ftp_login与ftp_chmod用法
2014/11/18 PHP
用php来限制每个ip每天浏览页面数量的实现思路
2015/02/24 PHP
php中 $$str 中 &quot;$$&quot; 的详解
2015/07/06 PHP
javascript比较文档位置
2008/04/08 Javascript
Javascript 判断Flash是否加载完成的代码
2010/04/12 Javascript
Js 去掉字符串中的空格(实现代码)
2013/11/19 Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
2014/02/07 Javascript
json+jQuery实现的无限级树形菜单效果代码
2015/08/27 Javascript
JavaScript实现图片自动加载的瀑布流效果
2016/04/11 Javascript
JavaScript程序中实现继承特性的方式总结
2016/06/24 Javascript
深入学习js瀑布流布局
2016/10/14 Javascript
详解Angular的内置过滤器和自定义过滤器【推荐】
2016/12/26 Javascript
javaScript基础详解
2017/01/19 Javascript
JavaScript实现QQ聊天消息展示和评论提交功能
2017/05/22 Javascript
js中el表达式的使用和非空判断方法
2018/03/28 Javascript
vscode 开发Vue项目的方法步骤
2018/11/25 Javascript
Vue 如何使用props、emit实现自定义双向绑定的实现
2020/06/05 Javascript
[01:14]2014DOTA2展望TI 剑指西雅图newbee战队专访
2014/06/30 DOTA
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
python 实现selenium断言和验证的方法
2019/02/13 Python
解决python web项目意外关闭,但占用端口的问题
2019/12/17 Python
Python面向对象魔法方法和单例模块代码实例
2020/03/25 Python
意大利拉斐尔时尚购物网:Raffaello Network(支持中文)
2018/11/09 全球购物
Abbacino官网:包、钱包和女士配饰
2019/04/15 全球购物
Farfetch澳大利亚官网:Farfetch Australia
2020/04/26 全球购物
Linux如何为某个操作添加别名
2013/03/01 面试题
社区活动邀请函范文
2014/01/29 职场文书
检举信的格式及范文
2014/04/04 职场文书
大学生就业协议书范本(适用于公司企业)
2014/10/07 职场文书
集英社今正式宣布 成立游戏公司“集英社Games”
2022/03/31 其他游戏
SQL Server使用导出向导功能
2022/04/08 SQL Server
解决Mysql中的innoDB幻读问题
2022/04/29 MySQL