vue里的svg缩放与拖拽功能实现案例

vue里的svg缩放与拖拽功能实现案例

代码案列

<template >
  <div style="width: 100%;height: 100%">
    <div id="dragDiv" style="background-color: #001529;margin-top: 10px;width: 100%;height: 90%">
    <svg version="1.1"
         xmlns="http://www.w3.org/2000/svg"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         viewBox="280 0 1024 1400"
         height="100%"
         width="100%"
         id="outbox">
      <g>
        <g id="28d34b3" name="line">
          <path class="line" fill="blue" stroke="#3a9cff" paint-order="fill stroke markers"
                d=" M 209.1799023140286 468.9155304128295 L 312.1799023140286 468.9155304128295" stroke-miterlimit="10"
                stroke-width="6" stroke-dasharray="10,10"/>
        </g>
      </g>
	  <!--固定type值,且针对svg的功能方法<script>要写在svg标签内部 -->
      <script type="application/ecmascript">
        let zoomVal = 0 // 放大缩小累计值
        let zoomStepSize = 20 // 放大缩小每次改变的步长20
        let removeFlag = false // 控制点击拖动,区分未点击时的鼠标移动
        let zoomW = 41 // 初始值 > zoomStepSize * 2 初次滚动后即可得到准确的当前值
        let zoomH = 41 // 初始值 > zoomStepSize * 2 初次滚动后即可得到准确的当前值
        let zoomX = 0
        let zoomY = 0


        // 加载SVG图像
        var oDiv = document.getElementById("outbox")
        getCurrentVB()
        oDiv.addEventListener('mousedown', moveDownMouse)
        oDiv.addEventListener('mouseup', moveUpMouse)
        oDiv.addEventListener('mousemove', moveMouse)
        oDiv.addEventListener('mousewheel',MouseWheel)


        // 鼠标滚轮事件
        function MouseWheel (e) {
          let ev = e || window.event
          let down = true

          // ev.wheelDelta未定义,ev.detail > 0为true表示往下滚动,为false表示往上滚动
          // wheelDelta和detail正好相反,火狐中wheelDelta未定义只能使用detail
          down = ev.wheelDelta ? ev.wheelDelta < 0 : ev.detail > 0
          if (down) {
            zoomOut() // 缩小
          } else {
            zoomIn() // 放大
          }
          if (ev.preventDefault) {
            ev.preventDefault()
          }
          return false
        }
        function zoomIn () {
          if (zoomW > zoomStepSize * 2 && zoomH > zoomStepSize * 2) {
            zoomVal += zoomStepSize
            zoomTo('in')
          }
        }
        function zoomOut () {
          zoomVal -= zoomStepSize
          if (zoomVal >= -zoomStepSize * 11) {
            zoomTo('out')
          }
          else {
            zoomVal = -zoomStepSize * 11 // 最小缩至-220不能再缩了
          }
        }
        function zoomTo (flag) {
          // 变化之前获取当前viewBox的位置
          getCurrentVB()
          // *********** 放大缩小后的各值的计算 开始 ***********
          if (flag === 'in') {
            zoomX = vbCX + zoomStepSize
            zoomY = vbCY + zoomStepSize
            zoomW = vbCW - zoomStepSize * 2
            zoomH = vbCH - zoomStepSize * 2
          }
          else {
            zoomX = vbCX - zoomStepSize
            zoomY = vbCY - zoomStepSize
            zoomW = vbCW + zoomStepSize * 2
            zoomH = vbCH + zoomStepSize * 2
          }
          // *********** 放大缩小后的各值的计算 结束 ***********
          // 将计算的结果赋予viewBox刷新当前展示的视图位置
          oDiv.setAttributeNS(null, 'viewBox', zoomX + ' ' + zoomY + ' ' + zoomW + ' ' + zoomH)
          // 变化之后获取当前viewBox的位置 保证了 vbCX vbCY vbCW vbCH始终为当前viewBox的值
          endZoom()
        }
        function endZoom () {
          getCurrentVB()
          // 视图发生系列缩放改变后最终的(x, y)坐标记录下来,用于放大后拖动
          endX = vbCX
          endY = vbCY
        }

        // 鼠标点击事件
        function moveDownMouse (evt) {
          getCurrentVB()
          removeFlag = true
          startX = parseInt(evt.clientX) // 当前点击的点的横坐标
          startY = parseInt(evt.clientY) // 当前点击的点的纵坐标
        }
        // 鼠标移动事件
        function moveMouse (evt) {
          if (removeFlag) {
            oDiv.setAttributeNS(null, 'style', 'cursor: move')
            moveX = parseInt(evt.clientX) - startX // 当前点-原始点=移动量
            moveY = parseInt(evt.clientY) - startY // 当前点-原始点=移动量
            vbCX = endX - moveX
            vbCY = endY - moveY
            vbCW = parseFloat(oDiv.viewBox.animVal.width)//刷新获取viewBox的高和宽
            vbCH = parseFloat(oDiv.viewBox.animVal.height)//刷新获取viewBox的高和宽
            // 刷新当前viewBox展示的视图位置
            oDiv.setAttributeNS(null, 'viewBox', vbCX + ' ' + vbCY + ' ' + vbCW + ' ' + vbCH)
          }
        }
        // 鼠标点击后松开事件
        function moveUpMouse (evt) {
          oDiv.setAttributeNS(null, 'style', 'cursor: default')
          // 视图发生系列移动后最终的(x, y)坐标记录下来,用于放大后拖动
          endX = vbCX
          endY = vbCY
          removeFlag = false
        }

        // 获取当前视图VB的位置信息
        function getCurrentVB () {
          vbCX = parseFloat(oDiv.viewBox.animVal.x)
          vbCY = parseFloat(oDiv.viewBox.animVal.y)
          vbCW = parseFloat(oDiv.viewBox.animVal.width)
          vbCH = parseFloat(oDiv.viewBox.animVal.height)
        }
        // 绑定事件到dom节点,考虑到兼容性
        function addEvent (obj, xEvent, fn) {
          if (obj.attachEvent) {
            obj.attachEvent('on' + xEvent, fn)
          }
          else {
            obj.addEventListener(xEvent, fn, false)
          }
        }

      </script>
    </svg>
  </div>
  </div>
</template>
<script>
</script>
<style>
</style>

回答: 在Vue实现SVG的放大缩小功能可以使用vue-svg-pan-zoom插件。首先,需要在项目中引入该插件,并注册为组件。然后,在需要放大缩小的SVG元素上使用SvgPanZoom组件,并设置相应的属性。例如,可以设置zoomEnabled属性为true来启用放大缩小功能,设置controlIconsEnabled属性为true来显示控制图标。同时,可以使用fit属性来控制SVG是否自适应容器大小,使用center属性来控制SVG是否居中显示。\[3\] 在JavaScript中,可以使用d3.zoom()方法来实现SVG的放大缩小功能。首先,需要选中SVG元素,然后调用d3.zoom()方法,并设置scaleExtent属性来限制缩放的范围。接着,使用on("zoom", zoom)方法来监听缩放事件,并在回调函数中设置元素的transform属性来实现缩放效果。\[2\] 综上所述,可以通过引入vue-svg-pan-zoom插件和使用d3.zoom()方法来实现Vue中的SVG放大缩小功能。 #### 引用[.reference_title] - *1* *2* [vue使用svg文件补充-svg放大缩小(使用d3.js)](https://blog.csdn.net/weixin_42118466/article/details/105861325)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [在vue页面用能放大缩小拖拽svg](https://blog.csdn.net/orangapple/article/details/107515081)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值