SVG图像缩放及拖动

svg引入

方法一:通过embed标签引入

<embed id="svgPic" name="svgPic" text-rendering="geometricPrecision" pluginspage="http://www.adobe.com/svg/viewer/install/" align="top" src="/static/svg/svgPic.svg" type="image/svg+xml" wmode="transparent">

方法二:直接引入

<svg version="1.1" id="svgPic" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100%" height="100%" viewBox="0 0 1920 1080" enable-background="new 0 0 1920 1080" xml:space="preserve">
	<rect x="-1" y="0.128" fill="transparent" width="1920" height="1080"/>
	<line fill="none" stroke="#FFFFFF" stroke-width="2" stroke-miterlimit="10" x1="27.865" y1="138.277" x2="1039.588" y2="138.277"/>
	……
</svg>

svg图像缩放,从调用Init开始

let oDiv = null // svg对应的dom对象
let vbCX = 0
let vbCY = 0
let vbCW = 0
let vbCH = 0
let zoomVal = 0 // 放大缩小累计值
let zoomStepSize = 20 // 放大缩小每次改变的步长20
let removeFlag = false // 控制点击拖动,区分未点击时的鼠标移动
let startX = 0 // 起始值x坐标
let startY = 0 // 起始值y坐标
let moveX = 0 // 水平移动量,往左为正
let moveY = 0 // 垂直移动量,往上为正
let endX = 0 // 最终到达的x坐标
let endY = 0 // 最终到达的y坐标
let zoomW = 41 // 初始值 > zoomStepSize * 2 初次滚动后即可得到准确的当前值
let zoomH = 41 // 初始值 > zoomStepSize * 2 初次滚动后即可得到准确的当前值
let zoomX = 0
let zoomY = 0

// 加载SVG图像
export function Init (svgId) {
  oDiv = document.getElementById(svgId)
  getCurrentVB() // svg图层参数初始化
  // 挂载监听鼠标事件,考虑兼容性,兼容火狐DOMMouseScroll事件
  addEvent(oDiv, 'mousewheel', onMouseWheel)
  addEvent(oDiv, 'DOMMouseScroll', onMouseWheel)
  oDiv.addEventListener('mousedown', moveDownMouse, false)
  oDiv.addEventListener('mouseup', moveUpMouse, false)
  oDiv.addEventListener('mousemove', moveMouse, false)
}

// 鼠标滚轮事件
function onMouseWheel (e) {
  let ev = e || window.event
  let down = true
  // ev.wheelDelta已定义,ev.wheelDelta < 0为true表示往下滚动,为false表示往上滚动
  // 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) {
  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
    // 刷新当前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)
  }
}

svg缩放与移动【最新2020.12.02】

在之前的代码上进行的优化

let oDiv = null
let vbCX = 0
let vbCY = 0
let vbCW = 0
let vbCH = 0
let zoomVal = 0 // 放大缩小累计值
let zoomStepSize = 20 // 放大缩小每次改变的步长20
let removeFlag = false
let startX = 0 // 起始值x坐标
let startY = 0 // 起始值y坐标
let moveX = 0 // 水平移动量,往左为正
let moveY = 0 // 垂直移动量,往上为正
let endX = 0 // 最终到达的x坐标
let endY = 0 // 最终到达的y坐标
let zoomW = 41 // 初始值 > zoomStepSize * 2 初次滚动后即可得到准确的当前值
let zoomH = 41 // 初始值 > zoomStepSize * 2 初次滚动后即可得到准确的当前值
let zoomX = 0
let zoomY = 0

// 加载SVG地图
export function Init (svgId, svgDoc) {
  if (svgId === null) {
    oDiv = svgDoc // 外部引入直接传入svg对象
  } else {
    oDiv = document.getElementById(svgId) // 代码嵌入,通过svg标签的ID获取svg对象
  }
  // 参数初始化
  initBasicParam()
  addEvent(oDiv, 'mousewheel', onMouseWheel)
  addEvent(oDiv, 'DOMMouseScroll', onMouseWheel) // 兼容火狐使用DOMMouseScroll事件
  oDiv.addEventListener('mousedown', moveDownMouse, false)
  oDiv.addEventListener('mouseup', moveUpMouse, false)
  oDiv.addEventListener('mousemove', moveMouse, false)
}
// svg图层参数初始化
function initBasicParam () {
  getCurrentVB()
}
// 以下是鼠标事件 放大缩小地图 移动地图
function onMouseWheel (e) {
  let ev = e || window.event
  let down = true
  // ev.wheelDelta已定义,ev.wheelDelta < 0为true表示往下滚动,为false表示往上滚动
  // 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
}
// zoom in 放大
function zoomIn () {
  if (zoomW > zoomStepSize * 2 && zoomH > zoomStepSize * 2) {
    zoomVal += zoomStepSize
    zoomTo('in')
  }
}
// zoom out 缩小
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) {
  // 移动点击时,初次先确认最终的坐标点,因为viewBox前两个参数可能不是0 0
  endZoom()
  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
    // 刷新当前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
}
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)
}
function addEvent (obj, xEvent, fn) {
  if (obj.attachEvent) {
    obj.attachEvent('on' + xEvent, fn)
  } else {
    // 解决e.preventDefault()报错 第三个参数由false改为 {passive: false}
    obj.addEventListener(xEvent, fn, { passive: false })
  }
}

遗留问题:

1、360等浏览器 SVG 放大倍数有问题
2、Microsoft edge SVG缩放闪屏
解决后更新

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: svg拖拽缩放.zip是一个压缩文件,其中包含了一些用于实现SVG形拖拽和缩放的文件和代码。 SVG是一种用于描述二维矢量形的XML格式,可以在网页上显示出高质量的像。拖拽和缩放是一些常见的交互性功能,能够增强SVG形的用户体验。 这个压缩文件中可能包含了一些JavaScript代码文件,这些代码通过控制鼠标事件来实现SVG形的拖拽和缩放功能。可能会有一个HTML文件,其中包含了用于嵌入SVG形,并与JavaScript代码进行交互的代码。还可能包含一些CSS文件,用于样式化SVG形。 通过使用这些文件和代码,我们可以在网页上显示SVG形,并使其具有拖拽和缩放的功能。用户可以使用鼠标拖拽SVG形,移动到所需的位置。同时,用户还可以使用鼠标滚轮或其他的手势进行缩放操作,以便放大或缩小SVG形。 这些功能能够增加用户与SVG形的互动性,提升用户的体验。这在许多场景中都非常有用,比如在地应用中,用户可以通过拖拽和缩放来浏览地的不同区域;在设计工具中,用户可以通过拖拽和缩放来调整形的位置和大小等。 使用这个压缩文件提供的文件和代码,我们可以方便地实现SVG形的拖拽和缩放,为用户提供更好的用户体验。 ### 回答2: svg拖拽缩放.zip是一个压缩文件,其中包含了用于实现SVG拖拽和缩放功能的相关代码和资源文件。 在现代网页开发中,SVG(可缩放矢量形)被广泛应用于形设计和数据可视化领域。通过使用SVG拖拽缩放功能,我们可以实现在网页上对SVG形进行简单的拖拽和缩放操作。 这个压缩文件中可能包含了HTML、CSS和JavaScript等文件,用于实现SVG拖拽和缩放功能的具体代码。通常情况下,这些代码会利用JavaScript的事件监听和DOM操作来实现拖拽和缩放效果。 在实际使用中,我们可以将这些相关文件解压缩并在网页中引入相应的代码文件。然后,根据具体的需求进行配置和定制,以实现自己想要的SVG拖拽和缩放效果。 总而言之,SVG拖拽缩放.zip是一个用于实现SVG拖拽和缩放功能的压缩文件,内含相关代码和资源文件。通过正确使用这些文件,我们可以在网页中实现对SVG形的简单拖拽和缩放操作。 ### 回答3: "svg拖拽缩放.zip" 是一个文件,是一个压缩文件,其中包含了一种使用 SVG(可缩放矢量形)进行拖拽和缩放的示例代码和相关资源。 SVG 是一种用于描述二维矢量形的 XML 格式标准,它可以实现像的放大缩小而不失真,并且可以直接在网页上显示和编辑,因此在 Web 开发中非常常用。而拖拽和缩放是在用户交互中经常使用的功能。 该示例代码和资源文件能够帮助开发者学习如何使用 SVG 实现形的拖拽和缩放功能。通过使用相关的 JavaScript 代码,可以实现通过鼠标拖动形并放置到指定位置的功能,同时也可以通过滚动鼠标滚轮来实现形的缩放操作。 在解压缩并查看该压缩文件后,你将找到一些包含 SVG 形和 JavaScript 代码的文件。这些文件可能包括用于绘制形和定义交互行为的 SVG 标签、包含操作处理函数的 JavaScript 文件等。 通过阅读和理解这些代码,你可以学习到如何在自己的网页或应用程序中实现类似的拖拽和缩放功能。你可以根据自己的需求来修改和定制这些代码,以满足你的具体开发需求。 总之,“svg拖拽缩放.zip” 提供了一个学习如何使用 SVG 实现拖拽和缩放功能的示例代码和资源,对于对 SVG 和拖拽、缩放功能感兴趣的开发者来说,是一个有价值的资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值