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

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

此处需要注意的是

我们在移动图片时,需要通过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实现图片在指定区域内移动的思路详解,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

(0)

相关推荐

  • 详解基于vue的移动web app页面缓存解决方案

    现在移动web app越来越热门了,许多公司开始尝试使用angular.react.vue等MVVM框架来开发单页架构的web app.但在开发web app时,如果希望页面的导航体验也接近原生应用,那一般都会遇到这两个问题: 识别前进后退行为 后退时恢复之前的页面 笔者开发了一个基于vue与vue-router的导航库vue-navigation,来帮助开发者来解决这些问题,下面是问题的解决思路. 识别前进后退 先说第一个问题.和原生app不一样,浏览器中主要有这几个限制: 没有提供前进后退的

  • 利用Vue实现移动端图片轮播组件的方法实例

    前言 轮播图的插件也有很多,用jQuery写起来也不难,这里分享的是关于利用Vue实现移动端图片轮播组件的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: wc-swiper 基于 Vue 的移动端的图片轮播组件. Why 之前一直在用 vue-awesome-swiper, 功能很齐全, 但是唯一的问题就是体积比较大. 我只是想要一个简单的图片轮播, 但是却要引入 100多k 大小的文件, 这样是不对的. 特点 支持自动播放 & 无限轮播 (loop) 效果 支持用户滑

  • vue.js移动端app之上拉加载以及下拉刷新实战

    上拉加载以及下拉刷新都是移动端很常见的功能,在搜索或者一些分类列表页面常常会用到. 跟横向滚动一样,我们还是采用better-scroll这个库来实现.由于better已经更新了新的版本,之前是0.几的版本,更新了一下发现,现在已经是1.2.6这个版本了,新版本多了些 比较好用的api,所以我也重写了之前的代码,用新的api来实现上拉加载以及下拉刷新. 首先把基本的样式写好,这里就略过了,然后引入better-scroll库 import BScroll from 'better-scroll'

  • vue实现移动端图片裁剪上传功能

    本文实例为大家分享了vue移动端图片裁剪上传的具体代码,供大家参考,具体内容如下 1. 安装cropperjs依赖库 npm install cropperjs 2. 编写组件SimpleCropper.vue <template> <div class="v-simple-cropper"> <slot> <button @click="upload">上传图片</button> </slot>

  • vue+vux实现移动端文件上传样式

    样式使用的是vux的cell组件 如下图的官方demo样子 上图的样式需要修改一下,把 保护中 修改成一个图片 并且内嵌一个input type='file'  就可以拥有好看的样式的文件上传了 <!--引入组件--> import { Cell } from 'vux' <!--官网的组件是这么写的--> <group> <cell title="title" value="value"></cell>

  • 写一个移动端惯性滑动&回弹Vue导航栏组件 ly-tab

    前段时间写了一个移动端的自适应滑动Vue导航栏组件,觉得有一定实用性,大家可能会用得到(当然有些大佬自己写得更好的话就没必要啦),于是前两天整理了一下,目前已经发布到npm和GitHub上了,点我到npm,点我到GitHub项目 ,有需要的同学可以在项目中 npm install ly-tab -S 或者 yarn add ly-tab 使用,具体用法下面会讲到. 好了,先看看效果吧 好的,开始废话了,实习差不多3个月了,这段时间跟着导师大佬也有接触过一些项目,也学到了不少东西,接触到的项目基本

  • vue2.0 移动端实现下拉刷新和上拉加载更多的示例

    本人正在基于 vue2.0 + webpack + es6 搭建前端架构,整理了部分插件,下面这个是下拉更新 上拉更多的,挺好用的,分享给大家. 直接上代码,不懂的多看几遍,下面我换会告诉大家如何使用. <template lang="html"> <div class="yo-scroll" :class="{'down':(state===0),'up':(state==1),refresh:(state===2),touch:tou

  • vue移动端实现下拉刷新

    看完这篇文章,相信大伙也一样可以,做出一个自己的刷新,加载的组件 说这个功能之前,大家要先了解一下,要怎么触发滚动条事件. 一定要注意,所有滚动事件都必须要满足这个条件,横向滚动条也一样, 只要满足子元素宽度大于父元素宽度就可以了.(下篇文章会讲怎么实现一个横向滚动条) 接入正题!!! 先来看看怎么剖析这个下拉刷新. 要用到的移动端的三个事件: touchstart(手指按下),touchmove(手指移动),touchend(手指离开) 下拉刷新也就是(touchstart => touchm

  • 详解vue移动端日期选择组件

    先给大家分享一下源码:https://github.com/lx544690189/vue-mobile-calendar Build Setup # install dependencies npm install # build for production with minification npm run build Usage install npm install vue-mobile-calendar or:(from the dist folder) <script src=&quo

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

    当图片比要显示的区域大时,需要将多余的部分隐藏掉,我们可以通过绝对定位来实现,并通过动态修改图片的left值和top值从而实现图片的移动.具体实现效果如下图,如果我们移动的是div 实现思路相仿. 此处需要注意的是 我们在移动图片时,需要通过draggable="false" 将图片的 <img src="/static/pano-dev/test/image-2.jpg" draggable="false" />,否则按下鼠标监听o

  • 基于Pytorch版yolov5的滑块验证码破解思路详解

    前言 本文将使用pytorch框架的目标识别技术实现滑块验证码的破解.我们这里选择了yolov5算法 例:输入图像 输出图像 可以看到经过检测之后,我们能很准确的定位到缺口的位置,并且能得到缺口的坐标,这样一来我们就能很轻松的实现滑动验证码的破解. 一.前期工作 yolov系列是常用的目标检测算法,yolov5不仅配置简单,而且在速度上也有不小的提升,我们很容易就能训练我们自己的数据集. YOLOV5 Pytorch版本GIthub网址感谢这位作者的代码. 下载之后,是这样的格式 ---data

  • vue实现密码显示隐藏功能的思路详解

    效果: 思路: 利用input的type属性,当type值是text的时候展示密码,当type值是password的时候隐藏密码: 于是很容易想到用v-bind来绑定type,同时用一个布尔值来控制,写成三元表达式的形式: 加入一个图片元素,点击图标元素切换这个布尔值,就可以达到切换显示隐藏,切换布尔值的同时也切换图标. 页面布局 <div id='app'> <!--三元表达式 pwdFlag为真则type是password密码隐藏 pwdFlag为假则type是text密码显示 --

  • vue单页开发父子组件传值思路详解

    vue单页开发时经常需要父子组件之间传值,自己用过但是不是很熟练,这里我抽空整理了一下思路,写写自己的总结. GitHub地址:https://github.com/leileibrother/wechat-vue 文件目录如下图,example.vue是父组件,exampleChild.vue是子组件. 父组件引入子组件,父组件html的代码如下: <template> <div> <h3>这是父组件</h3> <p style="marg

  • 基于Vue实现的多条件筛选功能的详解(类似京东和淘宝功能)

    基于Vue实现的多条件筛选功能(类似京东和淘宝功能),可以支持多选.清空.全选功能,数据源是通过JSon格式的数据封装而成. 实现的效果图: 代码实现如下: html: <div id='app'> <template v-if='condition.length'> <div> <span>已选中:<span> <span v-for='(item,index) in condition' class='active'>{{item

  • Vue自定义图片懒加载指令v-lazyload详解

    Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍.以下将详细介绍如何实现自定义指令v-lazyload. 先看如何使用这个指令: <img v-lazyload="imageSrc" > imageSrc是要加载的图片的实际路径. 为了实现这个指令,我们首先单独建立一个文件,名字为lazyload.js.并填写基本的代码,如下: //Vue 图片懒加载,导出模块 export default (Vue , o

  • vue 项目常用加载器及配置详解

    本文介绍了vue 项目常用加载器及配置详解,分享给大家,具体如下: 1.安装sass: 1.1 由于sass-loader依赖于node-sass,所以在安装sass-loader的同时还需安装node-sass npm install --save-dev node-sass npm install --save-dev sass-loader 1.2 安装完成后修改 <style>标签: <style lang="scss"></style> 2

  • cropper js基于vue的图片裁剪上传功能的实现代码

    前些日子做了一个项目关于vue项目需要头像裁剪上传功能,看了一篇文章,在此基础上做的修改完成了这个功能,与大家分享一下.原文:http://www.jb51.net/article/135719.htm 首先下载引入cropper js, npm install cropper js --save 在需要的页面引入:import Cropper from "cropper js" html的代码如下: <template> <div id="demo&quo

  • 基于vue实现图片验证码倒计时60s功能

    1.基于VUE实现图片验证码 html: <div class="formItem pr"> <img src="../../image/icon2.png" alt=""> <input type="text" placeholder="请输入验证码"> <img :src="IdentifyingCode" alt="图文验证码&q

  • Vue图片放大镜组件的封装使用详解

    基于Vue的图片放大镜组件封装,供大家参考,具体内容如下 图片放大镜的实现过程是将一个小图放置在一个盒子里,当鼠标在小图盒子里移动时,出现一个移动块(阴影区域/遮罩层),右侧大图片盒子出现一个等比例放大的在小图盒子移动块中的图片内容.效果图如下: 实现图片放大镜效果的Vue组件代码如下: <template> <div> <div class="move" @mouseover="over()" @mouseout="out(

随机推荐