基于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 相关文章推荐
让iframe框架网页在任何浏览器下自动伸缩
Aug 18 Javascript
由浅到深了解JavaScript类
Sep 08 Javascript
jquery api参考 visualjquery 中国线路 速度快
Nov 30 Javascript
IE下JS读取xml文件示例代码
Aug 05 Javascript
再次谈论React.js实现原生js拖拽效果引起的一系列问题
Apr 03 Javascript
深入解析JavaScript中的立即执行函数
May 21 Javascript
jquery自适应布局的简单实例
May 28 Javascript
详解axios 全攻略之基本介绍与使用(GET 与 POST)
Sep 15 Javascript
vue2.0学习之axios的封装与vuex介绍
May 28 Javascript
JS实现十分钟倒计时代码实例
Oct 18 Javascript
Echart折线图手柄触发事件示例详解
Dec 16 Javascript
处理JavaScript值为undefined的7个小技巧
Jul 28 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静态类
2006/11/25 PHP
谈谈新手如何学习PHP
2006/12/14 PHP
Memcache 在PHP中的使用技巧
2010/02/08 PHP
php指定函数参数默认值示例代码
2013/12/04 PHP
关于PHP的curl开启问题探讨
2014/04/08 PHP
destoon切换城市后实现logo旁边显示地区名称的方法
2014/08/21 PHP
Laravel向公共模板赋值方法总结
2019/06/25 PHP
解决IE下select标签innerHTML插入option的BUG(兼容IE,FF,Opera,Chrome,Safari)
2010/05/13 Javascript
js与jquery获取父元素,删除子元素的两种不同方法
2014/01/09 Javascript
JQuery 的跨域方法推荐_可跨任何网站
2016/05/18 Javascript
静态页面html中跳转传值的JS处理技巧
2016/06/22 Javascript
谈谈因Vue.js引发关于getter和setter的思考
2016/12/02 Javascript
JavaScript基于Dom操作实现查找、修改HTML元素的内容及属性的方法
2017/01/20 Javascript
jQuery插件FusionCharts实现的2D饼状图效果【附demo源码下载】
2017/03/03 Javascript
vue之数据交互实例代码
2017/06/16 Javascript
深入探究node之Transform
2017/07/20 Javascript
jsonp跨域获取数据的基础教程
2018/07/01 Javascript
10分钟彻底搞懂Http的强制缓存和协商缓存(小结)
2018/08/30 Javascript
element-ui组件中input等的change事件中传递自定义参数
2019/05/22 Javascript
node使用request请求的方法
2019/12/20 Javascript
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
2020/05/03 Javascript
[04:03]DOTA2英雄梦之声_第02期_风暴之灵
2014/06/30 DOTA
python 多进程通信模块的简单实现
2014/02/20 Python
Fiddler如何抓取手机APP数据包
2016/01/22 Python
Python中如何优雅的合并两个字典(dict)方法示例
2017/08/09 Python
Python网络爬虫中的同步与异步示例详解
2018/02/03 Python
python爬虫爬取监控教务系统的思路详解
2020/01/08 Python
解决Django中checkbox复选框的传值问题
2020/03/31 Python
体育教育毕业生自荐信
2013/11/21 职场文书
大三学生入党思想汇报
2014/01/02 职场文书
学校安全检查制度
2014/01/27 职场文书
幼儿园教师考核制度
2014/02/01 职场文书
幼儿教育感言
2014/02/05 职场文书
租房协议书范本
2014/04/09 职场文书
员工辞职信范文
2015/03/02 职场文书
SpringBoot中HttpSessionListener的简单使用方式
2022/03/17 Java/Android