使用JavaScript实现一个拖拽缩放效果

目录
  • 前言
  • 基本思路
  • 拖拽实现
  • 缩放实现
  • 最后

前言

在写一个简单的H5页面时,需要实现如下的一个拖拽效果,找了半天未能找到符合要求的,含泪手写
先来看一下我们要是实现一个怎样的效果

基本思路

  • 鼠标摁下,记录元素的初始位置以及宽高
  • 监听鼠标的移动,根据鼠标的移动不断改变自己的位置/宽高
  • 是否存在边界限制

拖拽实现

我们常见的改变元素位置的方式有

  • 定位
  • 使用translate进行偏移

那我们现在用那种方式那实现拖拽呢?
从功能实现上来看,这两个方式都能很好的实现我们的需求
从性能上来看,translate天生就是用来制作动画效果的,所以translate的性能以及流畅度都是要优于定位的。
开始操作!!

<style>
  .box{
    margin: 50px;
    width: 500px;
    height: 300px;
    border: 1px solid black;
    position: relative;
  }
  .drag{
    height: 100px;
    width: 100px;
    background-color: #cbd;
  }
</style>

<div class="box">
  <div class="drag"></div>
</div>

<script>
  let dragEl = document.querySelector(".drag")
  let container = document.querySelector(".box")
  let width, height, maxWidth, maxHeight, tx, ty, startX, startY
  // 初始化
  function init() {
    // 为目标元素设置初始的偏移,避免在第一次获取偏移时为空的问题
    dragEl.style.transform = "translate(0px,0px)"
    // 获取父元素宽高
    maxWidth = container.clientWidth
    maxHeight = container.clientHeight
  }
  function getInfo(e) {
      // 获取元素当前的宽高
      width = dragEl.clientWidth
      height = dragEl.clientHeight
      // 获取元素当前的偏移量
      let translateStr = dragEl.style.transform
      const reg = /\d+/g
      let translateArr = translateStr.match(reg)
      tx = Number(translateArr[0])
      ty = Number(translateArr[1])
      // 记录鼠标的起始位置
      startX = e.clientX
      startY = e.clientY
    }
  function  drag() {
    dragEl.addEventListener("mousedown", (e) => {
      getInfo(e)
      document.onmousemove = (e) => {
        let distanceX = tx + e.clientX - startX
        let distanceY = ty + e.clientY - startY
        dragEl.style.transform = `translate(${distanceX}px, ${distanceY}px)`
      }
      document.onmouseup = () => {
        document.onmousemove = null
      }
    })
  }
  init()
  drag()
</script>

通过上述代码,我们已经完成了元素的拖动,接下来需要考虑的就是,如果有边界限制,我们又该如何实现
从上诉例子中,我们可以观察出,元素偏移的最小值为0,最大值为父元素的宽高 - 目标元素的宽高
所以在有边界限制的情形下偏移量的计算方式为

let distanceX = Math.max(0, Math.min(tx + e.clientX - startX, maxWidth - width))
let distanceY = Math.max(0, Math.min(ty + e.clientY - startY, maxHeight - height))

缩放实现

这里我们以向左缩放为例

  • 首先我们需要为目标元素添加一个边框,用来进行缩放的操作
<style>
  .box{
    margin: 50px;
    width: 500px;
    height: 300px;
    border: 1px solid black;
    position: relative;
  }
  .drag{
    height: 100px;
    width: 100px;
    background-color: #cbd;
  }
  .left{
    width: 10px;
    height: calc(100% - 14px);
    margin: 7px 0px;
    position: absolute;
    background-color: #000;
    cursor: col-resize;
    top: 0;
    left: -5px;
  }
</style>
<script>
function addLeft() {
  left = document.createElement("div")
  left.className = "left"
  dragEl.append(left)
}
init()
drag()
addLeft()
</script>

2.为左侧的边框添加缩放功能,因为是左侧的缩放,所以在宽度变化的同时,需要不断调整元素的位置,令其符合视觉效果

function leftZoom() {
  left.addEventListener("mousedown", (e) => {
    e.stopPropagation()
    getInfo(e)
    document.onmousemove = (e) => {
      // 注意这里是
      newWidth = width - (e.clientX - startX)
      let distanceX = tx + (e.clientX - startX)
      dragEl.style.width = `${newWidth}px`
      dragEl.style.transform = `translate(${distanceX}px, ${ty}px)`
    }
    document.onmouseup = () => {
      document.onmousemove = null
    }
  })
}
init()
drag()
addLeft()
leftZoom()
  • 限制元素缩放的最小值
let minWidth = 30
newWidth = Math.max(minWidth, width - (e.clientX - startX))
  • 现在我们已经完成了缩放,但是当元素向右缩小到最小值时,元素会向右移动,显然这是不符合逻辑的,所以我们需要对偏移进行限制
// 最大偏移为已经偏移的距离 + 目标元素的宽度 - 最小宽度
let distanceX = Math.min(tx + width - minWidth, tx + (e.clientX - startX))

4.如果缩放的尺寸需要限制在父元素内,我们需要继续完善代码

// 最大宽度为元素当前偏移量 + 最初的宽度,最小宽度为minWidth
newWidth = Math.min(tx + width, Math.max(minWidth, width - (e.clientX - startX)))
// 最大偏移为已经偏移的距离 + 目标元素的宽度 - 最小宽度,最小偏移为0
let distanceX = Math.max(0,Math.min(tx + width - minWidth, tx + (e.clientX - startX)))

其他是三边以及四个角的实现方式基本相同,就不在这里一一赘述了

最后

虽然我们完成了元素的拖拽与缩放,但是我们在使用时,还是存在许多的限制,比如

  • 目标元素不能被定位,如果使用定位对元素进行了偏移,我们所做的限制就会不生效
  • 同理目标元素也不能存在边距

虽然存在限制,但是我们可以根据自己的实际需求进行调整

到此这篇关于如何使用JS实现一个这样的拖拽缩放效果的文章就介绍到这了,更多相关js拖拽缩放内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 原生js实现拖拽移动与缩放效果

    本文实例为大家分享了js实现拖拽移动与缩放效果的具体代码,供大家参考,具体内容如下 效果图如下-实现了简单的拖拽和缩放功能 第一步-简单的拖拽功能 // 创建一个MoveClass构造函数 function MoveClass(id, options = {}) { // 绑定ele属性 this.ele = document.querySelector(id); this.move(); } // 给MoveClass原型上绑定move方法 MoveClass.prototype.move =

  • js 表格排序(编辑+拖拽+缩放)

    Table body{ font-size:12px} #tab{ border-collapse: collapse;} .edit{ height:16px; width:98%; background-color:#EFF7FF; font-size:12px; border:0px;} #tab thead td{ background:url(/upload/201005/20100531233452190.bmp);color:#183C94} #tab tbody td{ over

  • javascript实现表格排序 编辑 拖拽 缩放

    简单表格排序 可以双击编辑 自定义编辑后的 规则 可拖动列进行列替换 可推动边框进行列宽度的缩放 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xht

  • js实现鼠标拖拽缩放div实例代码

    封装为了jq插件,如下 drag.js ;(function ($) { $.fn.dragDiv = function (options) { var def = { maxW:600,// 可伸缩的最大宽度 minW:50// 可伸缩的最小宽度 };// 参数默认值 var opts = $.extend(def,options);// 扩展参数,使用默认值或传参 //设置最大/最小宽度 var max_width = opts.maxW, min_width = opts.minW; //

  • JavaScript实现拖拽和缩放效果

    本文实例为大家分享了JavaScript实现拖拽和缩放效果的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>拖拽缩放</title> <me

  • 使用JavaScript实现一个拖拽缩放效果

    目录 前言 基本思路 拖拽实现 缩放实现 最后 前言 在写一个简单的H5页面时,需要实现如下的一个拖拽效果,找了半天未能找到符合要求的,含泪手写先来看一下我们要是实现一个怎样的效果 基本思路 鼠标摁下,记录元素的初始位置以及宽高 监听鼠标的移动,根据鼠标的移动不断改变自己的位置/宽高 是否存在边界限制 拖拽实现 我们常见的改变元素位置的方式有 定位 使用translate进行偏移 那我们现在用那种方式那实现拖拽呢?从功能实现上来看,这两个方式都能很好的实现我们的需求从性能上来看,translat

  • JS实现六边形3D拖拽翻转效果的方法

    效果图 实例代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv=&q

  • JavaScript实现拖拽盒子效果

    本文实例为大家分享了JavaScript实现拖拽盒子效果的具体代码,供大家参考,具体内容如下 实现效果: 1.单击关闭,关闭盒子 2.点击左上方'点击注册',打开盒子 3.鼠标放在盒子上方蓝色区域显示十字 4.点击鼠标不松开就可移动盒子 5.松开鼠标图片暂停 实现步骤: 1.在页面最上方设置一个盒子,里面有一个超链接,超链接里面设置href="javascript:void(0);",再点击时不打开网页. 2.再设置一个可以拖拽的盒子,盒子嵌套一个蓝色盒子为的最上方的蓝色区域,蓝色盒子

  • Vue 实现一个简单的鼠标拖拽滚动效果插件

    最近开源了一个 Vue 组件,还不够完善,欢迎大家来一起完善它,也希望大家能给个 star 支持一下,谢谢各位了. github 地址:github.com/qq449245884- 最近在做一个新的项目,有个需要是这样的: 简单描述一下,就是鼠标拖动页面,整个页面会随着的鼠标的拖拽而移动,如果页面有内容,里面的内容也需要跟着拖动的外层整体移到. 一开始没啥思路,所以就发了个朋友圈,得到的答案挺多的,主要还是用拖拽之类的,但这个拖拽只是单个元素的拖动,我想要的整个视图的拖动. 这里线索又断了.

  • JavaScript实现简单拖拽效果

    本文实例为大家分享了JavaScript实现简单拖拽效果的具体代码,供大家参考,具体内容如下 先看实现的效果: 思路:里面用到了三个事件,鼠标按下.移动.松开事件 那么首先创建盒子并且给它赋予css样式 HTML: // html <div> <p>我是个蓝色的盒子</p> </div> CSS: CSS *{margin: 0;padding: 0;} div{ width: 100px; height: 100px; background-color:

  • JavaScript实现鼠标拖拽效果

    本文实例为大家分享了JavaScript实现鼠标拖拽效果的具体代码,供大家参考,具体内容如下 这次的效果图如下: 我认为这个实验的难点是保持盒子和鼠标的相对位置不变,通过鼠标按下和移动来实现拖拽的效果 如何实现拖拽的效果呢? 我们需要用到三个函数: onmousedown.onmousemove.onmouseup,分别表示鼠标按下.鼠标移动.鼠标抬起 在鼠标按下的回调函数中,我们需要通过clientX和clientY获取鼠标的初始位置,通过offsetLeft和offsetTop获取盒子的初始

  • JavaScript实现九宫格拖拽效果

    本文实例为大家分享了JavaScript实现九宫格拖拽效果的具体代码,供大家参考,具体内容如下 关于一些拼图游戏什么的,见人家效果做的不错,参考下别人写的代码,我也尝试着做了个. <!DOCTYPE html> <html>     <head>         <meta charset="UTF-8">         <title></title>         <style type="t

  • JS实现网站菜单拖拽移位效果的方法

    本文实例讲述了JS实现网站菜单拖拽移位效果的方法.分享给大家供大家参考.具体如下: 这是一个基于JavaScript的层手动实例,让网站的菜单可以拖拽移位,记得土豆网的"豆单"有这种功能.本效果还尚未彻底完成,部分地方因没有写入对应内容,因此JS可能会提示有错误. 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/js-web-menu-tzyw-style-codes/ 具体代码如下: <html> <head>

  • JavaScript实现可拖拽的拖动层Div实例

    本文实例讲述了JavaScript实现可拖拽的拖动层Div.分享给大家供大家参考.具体如下: 这是一个完美的JS拖拽效果,带拖尾的JavaScript拖动层代码,经过了多次优化修正,复制节点的方法不错,值得JS爱好者学习,同时代码修正了给拖拽元素加ondblclick事件无效的问题,兼容多种浏览器,拷贝代码即可运行使用. 运行效果如下图所示: 具体代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

  • javascript实现文件拖拽事件

    本文实例为大家分享了javascript实现文件拖拽事件的具体代码,供大家参考,具体内容如下 1.效果图: 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <style type="text/css"> #div1 { width: 350px; height: 70px; pa

随机推荐