UNPKG

svg-action

Version:

控制SVG拖动,缩放,旋转,转图片等

1 lines 40.3 kB
{"version":3,"file":"svg-action.umd.cjs","sources":["../src/SvgAction.js"],"sourcesContent":["let debug = false;\r\n\r\n/**\r\n * 给svg添加放大缩小的功能\r\n */\r\nSvgAction.defaultOption = {\r\n // 鼠标超过多少才移动\r\n threshold: 15,\r\n \r\n // 每次放大比例\r\n deltaThreshold: 0.1,\r\n // 可缩放倍数\r\n range: { min: 0.4, max: 100 },\r\n // 每次缩放比例\r\n scale: 0.25,\r\n // ctrl | shift + 鼠标滚轮每次移动的像素\r\n stepSize: 75,\r\n // 键盘或调用移动方法时默认步长\r\n keyStepSize: 10,\r\n // 滚轮缩放\r\n mouseScale: true,\r\n // 平移\r\n mouseMove: true,\r\n // 拖动\r\n mouseDrag: true,\r\n // 旋转\r\n mouseRotate: true,\r\n // 翻转\r\n mouseFlip: true,\r\n};\r\n\r\nlet DEG_ELEMENT;\r\n\r\n\r\n/**\r\n * @param {Object} options\r\noptions: {\r\n threshold {Number}: 指定鼠标拖动时起始阈值,默认:15\r\n deltaThreshold {Number} 最小放大比例,默认:0.1\r\n range {Object} {\r\n min: 最小缩放倍数,默认:0.25\r\n max: 最大缩放倍数,默认:100\r\n }\r\n scale {Number}: 每次缩放比例,默认:0.25\r\n stepSize {Number}: ctrl | shift + 鼠标滚轮每次移动的像素 默认75\r\n keyStepSize {Number}: 键盘或调用移动方法时默认步长,默认10\r\n mouseControl {Element}: 设置鼠标控制节点,默认svg节点父级document\r\n mouseScale {Boolean} 是否开启鼠标缩放,默认true\r\n mouseMove {Boolean} 是否开启鼠标移动,按住Shift或Ctrl键 + 滚轮即可平移,默认true\r\n mouseDrag {Boolean} 是否开启鼠标拖拽,默认true\r\n mouseRotate {Boolean} 是否开启鼠标旋转,按住ctrl即可旋转,默认true\r\n mouseFlip {Boolean} 是否开启鼠标翻转,按住Shift即可旋转,默认true\r\n\r\n keyControl {Element} 设置键盘控制的节点,默认svg父级或document\r\n}\r\n */\r\nfunction SvgAction (svg, options) {\r\n let self = this;\r\n if (!svg) {\r\n throw new Error('初始化失败,找不到SVG!');\r\n }\r\n self._svg = svg;\r\n self.options = {\r\n ...SvgAction.defaultOption,\r\n ...options,\r\n };\r\n \r\n self.options.mouseControl = self.getControlElement();\r\n self.options.keyControl = self.getKeyElement();\r\n \r\n \r\n self._totalDelta = 0;\r\n self._previouScale = 1; // 当前缩放大小\r\n self._deg = 0; // 当前旋转角度\r\n\r\n self._init();\r\n}\r\n\r\nSvgAction.prototype._init = function () {\r\n this._initSvg();\r\n // 添加css\r\n generateCss();\r\n this.buildEvent();\r\n}\r\n\r\nSvgAction.prototype.buildEvent = function () {\r\n if (this.eventState){\r\n return;\r\n }\r\n this.eventState = true;\r\n\r\n // 绑定鼠标事件\r\n buildMoveEvent.call(this);\r\n buildMousewheelEvent.call(this);\r\n\r\n // 绑定键盘事件\r\n buildKeyEvent.call(this);\r\n}\r\n\r\nfunction stopBubble(event) {\r\n let e = event || window.event;\r\n if (e.preventDefault) {\r\n e.preventDefault();\r\n }\r\n // 一般用在鼠标或键盘事件上\r\n if (e.stopPropagation) {\r\n // W3C取消冒泡事件\r\n e.stopPropagation();\r\n } else {\r\n // IE取消冒泡事件\r\n window.event.cancelBubble = true;\r\n }\r\n};\r\n\r\n\r\nfunction touchDebug(self, fast, last, cente){\r\n if(!debug){\r\n return;\r\n }\r\n let ns = 'http://www.w3.org/2000/svg'\r\n\r\n let group = self._viewport.querySelector(\"#touchDebug\"),\r\n fastText, lastText, centeText;\r\n if (group){\r\n fastText = group.querySelector('#fastText');\r\n lastText = group.querySelector('#lastText');\r\n centeText = group.querySelector('#centeText');\r\n } else {\r\n group = document.createElementNS(ns, 'g');\r\n fastText = document.createElementNS(ns,'text');\r\n lastText = document.createElementNS(ns,'text');\r\n centeText = document.createElementNS(ns, 'text');\r\n group.id = 'touchDebug';\r\n fastText.id = 'fastText';\r\n lastText.id = 'lastText';\r\n centeText.id = 'centeText';\r\n fastText.innerHTML = '点1';\r\n lastText.innerHTML = '点2';\r\n centeText.innerHTML = '中';\r\n\r\n group.appendChild(fastText);\r\n group.appendChild(lastText);\r\n group.appendChild(centeText);\r\n\r\n self._viewport.appendChild(group);\r\n }\r\n // if (!cente){\r\n // cente = getPointCentre(fast.x, fast.y, last.x, last.y);\r\n // }\r\n let f = transformPoint(self._svg, fast.x, fast.y);\r\n let l = transformPoint(self._svg, last.x, last.y);\r\n // let c = transformPoint(self._svg, cente.x, cente.y);\r\n\r\n\r\n fastText.setAttribute('transform', `translate(${f.x}, ${f.y})`)\r\n lastText.setAttribute('transform', `translate(${l.x}, ${l.y})`)\r\n centeText.setAttribute('transform', `translate(${cente.x}, ${cente.y})`)\r\n}\r\n\r\nfunction transformPoint(svg, screenX, screenY) {\r\n var p = svg.createSVGPoint()\r\n p.x = screenX\r\n p.y = screenY\r\n return p.matrixTransform(svg.getScreenCTM().inverse())\r\n}\r\n\r\n/**\r\n * 添加图形移动事件\r\n */\r\nfunction buildMoveEvent () {\r\n let self = this;\r\n let ops = self.options;\r\n let context = {};\r\n // 添加事件\r\n // 鼠标按下\r\n let el = ops.mouseControl;\r\n\r\n el.addEventListener('mousedown', handleMousedown, false);\r\n el.addEventListener('touchstart', handleTouchstart, { passive: false });\r\n\r\n function handleMousedown(event) { // 开启拖拽\r\n // stopBubble(event);\r\n context.start = toPoint(event); // 起始坐标\r\n\r\n self._svg.className.baseVal = 'move-cursor-grabbing';\r\n document.addEventListener('mousemove', handleMouseMove, false);\r\n document.addEventListener('mouseup', handleEnd, false);\r\n }\r\n \r\n\r\n function handleTouchstart(event){\r\n stopBubble(event);\r\n context.start = toPoint(event); // 起始坐标\r\n document.addEventListener('touchmove', handleMouseMove, { passive: false });\r\n document.addEventListener('touchend', handleEnd, { passive: false });\r\n if (event.touches.length >= 2){\r\n let fast = toPoint(event.touches[0]);\r\n let last = toPoint(event.touches[1]);\r\n let cente = getPointCentre(fast.x, fast.y, last.x, last.y);\r\n cente = transformPoint(self._svg, cente.x, cente.y),\r\n context.doubleStart = {\r\n fast,\r\n last,\r\n cente,\r\n length: getDistance(fast.x, fast.y, last.x, last.y),\r\n };\r\n touchDebug(self, fast, last, cente);\r\n }\r\n }\r\n\r\n\r\n function handleMouseMove(event){\r\n stopBubble(event);\r\n\r\n if (event.type == 'touchmove' && event.touches.length >= 2){\r\n // 缩放\r\n let fast = toPoint(event.touches[0]);\r\n let last = toPoint(event.touches[1]);\r\n let doubleStart = context.doubleStart;\r\n touchDebug(self, fast, last, doubleStart.cente);\r\n\r\n // 计算距离\r\n let length = getDistance(fast.x, fast.y, last.x, last.y)\r\n if (length > doubleStart.length){ // 放大\r\n self._zoom(1, doubleStart.cente, 0.025);\r\n } else { // 缩小\r\n self._zoom(-1, doubleStart.cente, 0.025);\r\n }\r\n doubleStart.length = length;\r\n return;\r\n }\r\n\r\n context.position = toPoint(event); // 当前鼠标坐标\r\n context.delta = deltaPos(context.position, context.start); // 当前坐标到起始坐标的偏移\r\n\r\n\r\n // 鼠标移动超过15px才移动图形,防止晃动\r\n let fast = false;\r\n if (!context.dragging && _length(context.delta) > ops.threshold) {\r\n context.dragging = true;\r\n fast = true;\r\n }\r\n if (!context.dragging){\r\n return;\r\n }\r\n\r\n if (ops.mouseRotate && event.ctrlKey){\r\n handleRotate(event, fast);\r\n } else if (ops.mouseFlip && event.shiftKey) {\r\n handleFlip(event, fast);\r\n } else if (ops.mouseDrag){\r\n handleMove(event, fast);\r\n }\r\n\r\n context.last = context.position; // 记录下最后一次移动的位置\r\n }\r\n\r\n // 处理拖拽\r\n function handleMove (event) {\r\n let lastPosition = context.last || context.start;\r\n let delta = deltaPos(context.position, lastPosition);\r\n self.move({\r\n dx: delta.x,\r\n dy: delta.y\r\n });\r\n }\r\n\r\n /**\r\n * 处理旋转\r\n * 按住Ctrl 加鼠标\r\n */\r\n function handleRotate(event, fast){\r\n let degEl = degElement();\r\n\r\n // 鼠标移动超过15px才移动图形,防止晃动\r\n if (fast) {\r\n document.body.appendChild(degEl);\r\n degEl.show = true;\r\n }\r\n\r\n let lastPosition = context.last || context.start;\r\n let delta = deltaPos(context.position, lastPosition);\r\n let step = delta.x || delta.y;\r\n let deg = step < 0 ? -1 : 1;\r\n self.rotate(deg); // 没出触发旋转1度\r\n \r\n\r\n degEl.style.top = event.clientY + 'px';\r\n degEl.style.left = event.clientX + 20 + 'px';\r\n degEl.innerText = self._deg + '°';\r\n\r\n }\r\n /**\r\n * 处理翻转\r\n * 按住Shift 加鼠标\r\n */\r\n function handleFlip(event, fast){\r\n if (!fast){\r\n return;\r\n }\r\n if (context.delta.x >= ops.threshold){ // X 轴\r\n self.flipX();\r\n } else if (context.delta.x < ops.threshold){ //Y轴\r\n self.flipY();\r\n }\r\n }\r\n\r\n function handleEnd (event) {\r\n self._svg.className.baseVal = 'move-cursor-grab';\r\n context = {}; // 每一次移动结束,都清除上一次的结果\r\n document.removeEventListener('mousemove', handleMouseMove);\r\n document.removeEventListener('mouseup', handleEnd);\r\n\r\n document.removeEventListener('touchmove', handleMouseMove);\r\n document.removeEventListener('touchend', handleEnd);\r\n\r\n degElement().remove();\r\n }\r\n\r\n self._eventFn = {\r\n handleMousedown,\r\n handleTouchstart,\r\n handleMouseMove,\r\n handleEnd\r\n }\r\n}\r\n//计算两点间距离\r\nfunction getDistance (startX, startY, endX, endY) {\r\n return Math.hypot(endX - startX, endY - startY);\r\n};\r\n\r\nfunction getPointCentre(startX, startY, endX, endY) {\r\n let x = (startX - endX) / 2\r\n let y = (startY - endY) / 2\r\n return {\r\n x: startX + (0 - x),\r\n y: startY + (0 - y)\r\n };\r\n};\r\n\r\nfunction degElement(){\r\n if (DEG_ELEMENT){\r\n return DEG_ELEMENT;\r\n }\r\n\r\n DEG_ELEMENT = document.createElement('span');\r\n DEG_ELEMENT.style.position = 'fixed';\r\n DEG_ELEMENT.style.userSelect = 'none';\r\n return DEG_ELEMENT;\r\n}\r\n\r\n/**\r\n * 图形缩放事件\r\n * 滚轮事件\r\n */\r\nfunction buildMousewheelEvent () {\r\n let self = this;\r\n let el = self.options.mouseControl;\r\n el.addEventListener('mousewheel', handleMousewheel, false);\r\n function handleMousewheel (event) {\r\n stopBubble(event);\r\n\r\n if (self.options.mouseMove && (event.ctrlKey || event.shiftKey)) {\r\n handleWheelMove(event);\r\n } else if (self.options.mouseScale) {\r\n handleMouseScale(event);\r\n }\r\n }\r\n self._eventFn.handleMousewheel = handleMousewheel;\r\n\r\n // 平移\r\n function handleWheelMove(event){\r\n let factor = self.options.stepSize / 100;\r\n let delta;\r\n if (event.shiftKey) {\r\n delta = { // 水平\r\n dx: factor * event.deltaY,\r\n dy: 0\r\n };\r\n } else { // 垂直\r\n delta = {\r\n dx: factor * event.deltaX,\r\n dy: factor * event.deltaY\r\n };\r\n }\r\n\r\n self.move(delta);\r\n }\r\n /**\r\n * 缩放\r\n */\r\n function handleMouseScale(event){\r\n var elementRect = el.getBoundingClientRect();\r\n var offset = {\r\n x: event.clientX - elementRect.left,\r\n y: event.clientY - elementRect.top\r\n };\r\n\r\n self.zoom(event.wheelDelta < 0 ? 'out' : 'in', offset);\r\n }\r\n}\r\n\r\n/**\r\n * 处理键盘事件\r\n */\r\nfunction buildKeyEvent(){\r\n let self = this;\r\n self.options.keyControl.addEventListener('keydown', handleKeydown);\r\n function handleKeydown (event) {\r\n let key = getKey(event);\r\n if (!key) {\r\n return;\r\n }\r\n if (event.ctrlKey) {\r\n handleRotateAndZoom(key);\r\n } else if (event.shiftKey) {\r\n handleFlip(key);\r\n } else if (key == 'center') {\r\n self.reset();\r\n } else {\r\n handleMove(key);\r\n }\r\n }\r\n self._eventFn.handleKeydown = handleKeydown;\r\n\r\n function handleMove(key){\r\n self[key]();\r\n // switch(key){\r\n // case 'up':\r\n // self.up();\r\n // break;\r\n // case 'down':\r\n // self.down();\r\n // break;\r\n // case 'left':\r\n // self.left();\r\n // break;\r\n // case 'right':\r\n // self.right();\r\n // break;\r\n // }\r\n }\r\n\r\n function handleRotateAndZoom(key){\r\n switch(key){\r\n case 'up':\r\n self.zoomIn();\r\n break;\r\n case 'left':\r\n self.rotate();\r\n break;\r\n case 'down':\r\n self.zoomOut();\r\n break;\r\n case 'right':\r\n self.rotate(-45);\r\n break;\r\n }\r\n }\r\n\r\n function handleFlip(key){\r\n switch (key) {\r\n case 'up':\r\n case 'down':\r\n self.flipY();\r\n break;\r\n case 'left':\r\n case 'right':\r\n self.flipX();\r\n break;\r\n }\r\n }\r\n\r\n}\r\nfunction getKey(event){\r\n switch (event.key){\r\n case 'w':\r\n case 'ArrowUp':\r\n return 'up';\r\n\r\n case 's':\r\n case 'ArrowDown':\r\n return 'down';\r\n\r\n case 'a':\r\n case 'ArrowLeft':\r\n return 'left';\r\n\r\n case 'd':\r\n case 'ArrowRight':\r\n return 'right';\r\n\r\n case '0':\r\n case '`':\r\n return 'center';\r\n\r\n default: return null;\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 初始化svg,第一个节点必须是g\r\n * 如果不是就添加\r\n */\r\nSvgAction.prototype._initSvg = function () {\r\n let svg = this._svg;\r\n svg.className.baseVal = 'move-cursor-grab';\r\n // 第一个子节点必须是g\r\n if (svg.tagName === 'g') {\r\n this._viewport = svg;\r\n this._svg = findSvg(this._viewport) || this._viewport;\r\n function findSvg(node){\r\n if (node.parentElement.tagName == 'svg'){\r\n return node.parentElement;\r\n }\r\n return findSvg(node.parentElement);\r\n }\r\n } if (svg.childNodes.length === 1 && svg.firstElementChild.tagName === 'g') { // 判断第一个节点是否是g\r\n this._viewport = svg.firstElementChild;\r\n } else {\r\n let g = document.createElementNS(svg.namespaceURI, 'g');\r\n let childNodes = svg.childNodes;\r\n for (;childNodes.length !== 0;) {\r\n g.appendChild(childNodes[0]);\r\n }\r\n svg.appendChild(g);\r\n this._viewport = g;\r\n }\r\n}\r\n\r\n\r\n\r\n/**\r\n * 放大\r\n * @param {Number} i \r\n */\r\nSvgAction.prototype.zoomIn = function (i) {\r\n i = i || this.options.scale;\r\n this._zoom(1, getCentre.call(this), i);\r\n}\r\n/**\r\n * 缩小\r\n * @param {Number} i \r\n */\r\nSvgAction.prototype.zoomOut = function (i) {\r\n i = i || this.options.scale;\r\n this._zoom(-1, getCentre.call(this), i);\r\n}\r\n\r\nSvgAction.prototype.reset = function reset() {\r\n // this.zoom('fit-viewport');\r\n this.zoom('center');\r\n};\r\n\r\n/**\r\n * 缩放\r\n * @param {Number | String} delta in: 放大,out:缩小,center 居中,如果为数字,表示缩放倍数\r\n * @param {Object} position {x,y}以哪个位置为中心, 默认中心\r\n */\r\nSvgAction.prototype.zoom = function (delta, position) {\r\n let self = this;\r\n if (!delta) {\r\n return round(self._viewport.getCTM().a, 1000);\r\n }\r\n\r\n var scale = self.options.scale;\r\n if (delta === 'center') {\r\n return self._fitViewport(delta);\r\n } else if(delta === 'in') {\r\n delta = 1;\r\n } else if (delta === 'out') {\r\n delta = -1;\r\n } else if (typeof (delta) == 'number'){\r\n scale = Math.abs(delta);\r\n } else {\r\n return round(self._viewport.getCTM().a, 1000);\r\n }\r\n self._totalDelta += delta;\r\n\r\n if (Math.abs(self._totalDelta) > self.options.deltaThreshold) {\r\n let i = self._zoom(delta, position, scale);\r\n\r\n // reset\r\n self._totalDelta = 0;\r\n return i;\r\n }\r\n};\r\n\r\n\r\n/**\r\n * 缩放\r\n * @param {Number} delta 正数或负数,正数表示放大,负数缩小\r\n * @param {Object} position 偏移\r\n * @param {Number} stepSize 缩放比例\r\n * @returns \r\n */\r\nSvgAction.prototype._zoom = function (delta, position, stepSize) {\r\n let self = this;\r\n var direction = delta > 0 ? 1 : -1;\r\n\r\n var currentLinearZoomLevel = log10(self._previouScale);\r\n\r\n var newLinearZoomLevel = Math.round(currentLinearZoomLevel / stepSize) * stepSize;\r\n\r\n newLinearZoomLevel += stepSize * direction;\r\n\r\n var newLogZoomLevel = Math.pow(10, newLinearZoomLevel);\r\n\r\n setZoom.call(self, cap(self.options.range, newLogZoomLevel), position);\r\n\r\n this._previouScale = round(self._viewport.getCTM().a, 1000);\r\n return this._previouScale;\r\n};\r\n\r\n\r\nfunction setZoom (scale, center) {\r\n var svg = this._svg,\r\n viewport = this._viewport;\r\n\r\n var matrix = svg.createSVGMatrix();\r\n var point = svg.createSVGPoint();\r\n\r\n var centerPoint,\r\n originalPoint,\r\n currentMatrix,\r\n scaleMatrix,\r\n newMatrix;\r\n\r\n currentMatrix = viewport.getCTM();\r\n\r\n var currentScale = currentMatrix.a;\r\n\r\n if (center) {\r\n point.x = center.x;\r\n point.y = center.y;\r\n centerPoint = point;\r\n\r\n // revert applied viewport transformations\r\n originalPoint = centerPoint.matrixTransform(currentMatrix.inverse());\r\n\r\n // create scale matrix\r\n scaleMatrix = matrix\r\n .translate(originalPoint.x, originalPoint.y)\r\n .scale(1 / currentScale * scale)\r\n .translate(-originalPoint.x, -originalPoint.y);\r\n\r\n newMatrix = currentMatrix.multiply(scaleMatrix);\r\n } else {\r\n newMatrix = matrix.scale(scale);\r\n }\r\n setCTM(this._viewport, {matrix: newMatrix});\r\n\r\n return newMatrix;\r\n};\r\n\r\nSvgAction.prototype._fitViewport = function (center) {\r\n let self = this;\r\n let outer = {\r\n height: self._svg.clientHeight,\r\n width: self._svg.clientWidth\r\n };\r\n // let inner = {\r\n // height: self._viewport.clientHeight,\r\n // width: self._viewport.clientWidth,\r\n // x: 0,\r\n // y: 0\r\n // };\r\n let inner = self._viewport.getBBox();\r\n let newScale, newViewbox;\r\n\r\n // display the complete diagram without zooming in.\r\n // instead of relying on internal zoom, we perform a\r\n // hard reset on the canvas viewbox to realize this\r\n //\r\n // if diagram does not need to be zoomed in, we focus it around\r\n // the diagram origin instead\r\n\r\n if (inner.x >= 0 &&\r\n inner.y >= 0 &&\r\n inner.x + inner.width <= outer.width &&\r\n inner.y + inner.height <= outer.height &&\r\n !center) {\r\n newViewbox = {\r\n x: 0,\r\n y: 0,\r\n width: Math.max(inner.width + inner.x, outer.width),\r\n height: Math.max(inner.height + inner.y, outer.height)\r\n };\r\n } else {\r\n newScale = Math.min(1, outer.width / inner.width, outer.height / inner.height);\r\n let offsetX = - inner.x * newScale;\r\n let offsetY = - inner.y * newScale;\r\n let x = outer.width / 2 - inner.width * newScale / 2;\r\n let y = outer.height / 2 - inner.height * newScale / 2;\r\n newViewbox = {\r\n x: x >= 0 ? x + offsetX : offsetX,\r\n y: y >= 0 ? y + offsetY : offsetY\r\n };\r\n }\r\n let newMatrix = self._svg.createSVGMatrix()\r\n .translate(newViewbox.x, newViewbox.y)\r\n .scale(newScale);\r\n setCTM(self._viewport, {matrix: newMatrix});\r\n\r\n // 设置角度还原\r\n self._deg = 0;\r\n\r\n return self._previouScale = round(self._viewport.getCTM().a, 1000);\r\n};\r\n\r\n\r\n/**\r\n * 平移\r\n * @param {Object} delta {dx: 0, dy: 0}\r\n */\r\nSvgAction.prototype.move = function (delta) {\r\n let viewport = this._viewport;\r\n var matrix = viewport.getCTM();\r\n if (delta) {\r\n delta.dx = delta.dx || delta.x || 0;\r\n delta.dy = delta.dy || delta.y || 0;\r\n delta = Object.assign({ dx: 0, dy: 0 }, delta);\r\n // 使用浏览器的api计算偏移距离\r\n matrix = this._svg.createSVGMatrix().translate(delta.dx, delta.dy).multiply(matrix);\r\n setCTM(viewport, {matrix});\r\n }\r\n return { x: matrix.e, y: matrix.f };\r\n}\r\n\r\n/**\r\n * 上移\r\n * @param {Number} i 移动的像素点\r\n */\r\nSvgAction.prototype.up = function (i) {\r\n i = i || this.options.keyStepSize;\r\n return this.move({dy: -i});\r\n}\r\n/**\r\n * 下移\r\n * @param {Number} i 移动的像素点\r\n */\r\nSvgAction.prototype.down = function (i) {\r\n i = i || this.options.keyStepSize;\r\n return this.move({dy: i});\r\n}\r\n/**\r\n * 左移\r\n * @param {Number} i 移动的像素点\r\n */\r\nSvgAction.prototype.left = function (i) {\r\n i = i || this.options.keyStepSize;\r\n return this.move({dx: -i});\r\n}\r\n/**\r\n * 右移\r\n * @param {Number} i 移动的像素点\r\n */\r\nSvgAction.prototype.right = function (i) {\r\n i = i || this.options.keyStepSize;\r\n return this.move({dx: i});\r\n}\r\n\r\n/**\r\n * 旋转\r\n */\r\nSvgAction.prototype.rotate = function(angle = 45){\r\n let bbox = this._viewport.getBBox();\r\n setCTM(this._viewport, {\r\n rotate: {\r\n angle: angle,\r\n x: bbox.width / 2 + bbox.x,\r\n y: bbox.height / 2 + bbox.y\r\n }\r\n });\r\n\r\n this._deg += angle;\r\n}\r\n\r\n\r\n/**\r\n * 翻转\r\n */\r\nSvgAction.prototype.flipX = function () {\r\n let ctm = this._viewport.getCTM();\r\n setCTM(this._viewport, { matrix: ctm.flipX() });\r\n}\r\nSvgAction.prototype.flipY = function () {\r\n let ctm = this._viewport.getCTM();\r\n setCTM(this._viewport, { matrix: ctm.flipY() });\r\n}\r\n\r\n\r\n\r\nSvgAction.prototype.getControlElement = function () {\r\n return this.options.mouseControl || this._svg.parentElement || document;\r\n}\r\nSvgAction.prototype.getKeyElement = function () {\r\n return this.options.keyControl || document;\r\n}\r\n\r\nSvgAction.prototype.toImage = function () {\r\n let self = this;\r\n let image = new Image();\r\n let rect = self._svg.getBoundingClientRect();\r\n image.width = rect.width;\r\n image.height = rect.height;\r\n image.src = 'data:image/svg+xml;utf8,' + unescape(self._svg.outerHTML);\r\n\r\n return new Promise((resolve)=>{\r\n image.onload = function () {\r\n\r\n let canvas = document.createElement('canvas');\r\n canvas.width = rect.width;\r\n canvas.height = rect.height;\r\n\r\n let context = canvas.getContext('2d');\r\n context.drawImage(image, 0, 0, rect.width, rect.height);\r\n\r\n resolve(canvas.toDataURL('image/png'));\r\n }\r\n });\r\n\r\n \r\n\r\n \r\n\r\n}\r\n\r\nSvgAction.prototype.save = function () {\r\n this.toImage().then(url=>{\r\n var a = document.createElement('a');\r\n a.href = url;\r\n a.download = \"svg.png\"; //设定下载名称\r\n a.click(); //点击触发下载\r\n })\r\n}\r\n\r\n/**\r\n * 关闭事件\r\n */\r\nSvgAction.prototype.disableEvent = function () {\r\n // 清空事件\r\n let self = this;\r\n let ops = self.options;\r\n let eventFn = self._eventFn;\r\n let el = ops.mouseControl;\r\n self.eventState = false;\r\n\r\n el.removeEventListener('mousedown', eventFn.handleMousedown);\r\n el.removeEventListener('touchstart', eventFn.handleTouchstart);\r\n\r\n document.removeEventListener('mousemove', eventFn.handleMouseMove);\r\n document.removeEventListener('mouseup', eventFn.handleEnd);\r\n\r\n document.removeEventListener('touchmove', eventFn.handleMouseMove);\r\n document.removeEventListener('touchend', eventFn.handleEnd);\r\n\r\n el.removeEventListener('mousewheel', eventFn.handleMousewheel);\r\n ops.keyControl.removeEventListener('keydown', eventFn.handleKeydown);\r\n}\r\n\r\n\r\n/**\r\n * 获取图形原中心坐标\r\n * @param {Element} node \r\n */\r\nfunction getCentre (){\r\n let rect = this._viewport.getBoundingClientRect();\r\n let ctm = this._viewport.getCTM();\r\n return {\r\n x: ctm.e + rect.width / 2,\r\n y: ctm.f + rect.height / 2,\r\n }\r\n}\r\n\r\n\r\n/**\r\n * 设置matrix\r\n * @param {Object} node 节点\r\n * @param {Object} m 平移或放大\r\n */\r\nfunction setCTM(node, { matrix, rotate }) {\r\n matrix = matrix || node.getCTM();\r\n // var mstr = 'matrix(' + m.a + ',' + m.b + ',' + m.c + ',' + m.d + ',' + m.e + ',' + m.f + ')';\r\n var mstr = `matrix(${matrix.a}, ${matrix.b}, ${matrix.c}, ${matrix.d}, ${matrix.e}, ${matrix.f})`;\r\n if (rotate){\r\n mstr += `, rotate(${rotate.angle}, ${rotate.x}, ${rotate.y})`;\r\n }\r\n node.setAttribute('transform', mstr);\r\n}\r\n\r\nfunction cap (range, scale) {\r\n return Math.max(range.min, Math.min(range.max, scale));\r\n}\r\nfunction round (number, resolution) {\r\n return Math.round(number * resolution) / resolution;\r\n}\r\nfunction log10 (x) {\r\n return Math.log(x) / Math.log(10);\r\n}\r\nvar sign = Math.sign || function (n) {\r\n return n >= 0 ? 1 : -1;\r\n};\r\n/**\r\n * 计算移动的长度\r\n * @param {Object} point\r\n */\r\nfunction length (point) {\r\n return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));\r\n}\r\n/**\r\n * 计算移动了多少\r\n * @param {Object} a\r\n * @param {Object} b\r\n */\r\nfunction deltaPos (a, b) {\r\n return {\r\n x: a.x - b.x,\r\n y: a.y - b.y\r\n };\r\n}\r\n/**\r\n * 转换为坐标\r\n * @param {Object} event\r\n */\r\nfunction toPoint (event) {\r\n if (event.pointers && event.pointers.length) {\r\n event = event.pointers[0];\r\n }\r\n\r\n if (event.touches && event.touches.length) {\r\n event = event.touches[0];\r\n }\r\n\r\n return event ? {\r\n x: event.clientX,\r\n y: event.clientY\r\n } : null;\r\n}\r\nfunction _length (point) {\r\n return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2));\r\n}\r\n\r\nfunction generateCss () {\r\n let SvgAction = document.getElementById('SvgAction');\r\n if (SvgAction) {\r\n return;\r\n }\r\n\r\n let css = `\r\n .move-cursor-grab{\r\n cursor: grab;\r\n cursor: -webkit-grab;\r\n }\r\n .move-cursor-grabbing{\r\n cursor: grabbing;\r\n cursor: -webkit-grabbing;\r\n }\r\n `;\r\n let style = document.createElement('style');\r\n style.id = 'SvgAction';\r\n style.innerText = css;\r\n document.head.appendChild(style);\r\n}\r\n\r\nwindow.SvgAction = SvgAction;\r\n\r\nexport default SvgAction;\r\n"],"names":["SvgAction","DEG_ELEMENT","svg","options","self","generateCss","buildMoveEvent","buildMousewheelEvent","buildKeyEvent","stopBubble","event","e","touchDebug","fast","last","cente","transformPoint","screenX","screenY","p","ops","context","el","handleMousedown","handleTouchstart","toPoint","handleMouseMove","handleEnd","getPointCentre","getDistance","doubleStart","length","deltaPos","_length","handleRotate","handleFlip","handleMove","lastPosition","delta","degEl","degElement","deg","startX","startY","endX","endY","x","y","handleMousewheel","handleWheelMove","handleMouseScale","factor","elementRect","offset","handleKeydown","key","getKey","handleRotateAndZoom","findSvg","node","g","childNodes","i","getCentre","position","round","scale","stepSize","direction","currentLinearZoomLevel","log10","newLinearZoomLevel","newLogZoomLevel","setZoom","cap","center","viewport","matrix","point","centerPoint","originalPoint","currentMatrix","scaleMatrix","newMatrix","currentScale","setCTM","outer","inner","newScale","newViewbox","offsetX","offsetY","angle","bbox","ctm","image","rect","resolve","canvas","url","a","eventFn","rotate","mstr","range","number","resolution","b","css","style"],"mappings":"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"}