首页 > 解决方案 > 通过 viewBox 值移动事件 SVG

问题描述

我无法保存图像位置以供下次更改。似乎 svg 每次点击都会重置位置,我如何保存位置?这件事让我很困惑,除了这个可拖动的图像外,互联网上没有太多关于它的信息 ,但本教程适用于内部对象的“x”和“y”,而不适用于 viewBox 值。

	let image = document.querySelector("#parImage");
    	let svg = image.querySelector("svg");
    	let vbVals = svg.getAttribute("viewBox").split(" ");
    	let CTM = svg.getScreenCTM();

    	let x = 0;
    	let y = 0;
    	let z = 0;
    	let w = 0;

    	window.onload = function()
    	{
    		image.addEventListener('mousedown', startDrag);
	        image.addEventListener('mouseup', endDrag);
	        image.addEventListener('mouseleave', endDrag);
    	}

   		function drag()
   		{
   			event.preventDefault();

   			//x += 0.1;

			let X = (-((event.clientX - CTM.e) / CTM.a)) + 40;
			let Y = (-((event.clientY - CTM.f) / CTM.d)) + 30;

			svg.setAttribute("viewBox", 
				(X - x) 	+ " " + 
				(Y - y) 	+ " " + 
				vbVals[2] 	+ " " + 
				vbVals[3]);
   		}


   		function startDrag()
   		{
   			image.addEventListener('mousemove', drag);

   			x = (-((event.clientX - CTM.e) / CTM.a)) + 40;
   			y = (-((event.clientY - CTM.f) / CTM.d)) + 30;
   			x -= parseFloat(vbVals[0]);
   			y -= parseFloat(vbVals[1]);

   			z = parseFloat(vbVals[2]);
   			w = parseFloat(vbVals[3]);
   		}

   		function endDrag()
   		{
   			image.removeEventListener("mousemove", drag);
   		}
figure {
        width: 300px;
        background: wheat;
        margin: 0 auto;
    }

    .static {
        cursor: not-allowed;
    }

    .draggable {
        cursor: move;
    }
<!DOCTYPE html>
<html>

<head>
    <title></title>
</head>

<body>
    <div class="section-library-detailbox">
        <div class="inner">
            <figure id="parImage"><svg class="draggable" viewBox="-15 -10 400 440">
                      <path d="M30,1h40l29,29v40l-29,29h-40l-29-29v-40z" stroke="#000" fill="none"/> 
  <path d="M31,3h38l28,28v38l-28,28h-38l-28-28v-38z" fill="#a23"/> 
  <text x="50" y="68" font-size="48" fill="#FFF" text-anchor="middle"><![CDATA[410]]></text>
                </svg></figure>
        </div>
    </div>
</body>

</html>

标签: javascripthtmlcsssvg

解决方案


您需要阅读vbVals每次拖动,而不仅仅是最初。正如@Robert Longson 在评论中所说,您可以依靠现有的 API 来操作视图框;

let image = document.querySelector("#parImage");
let svg = image.querySelector("svg");
//let vbVals = svg.getAttribute("viewBox").split(" ");

let CTM = svg.getScreenCTM();

let x = 0;
let y = 0;
let z = 0;
let w = 0;

window.onload = function() {
  image.addEventListener('mousedown', startDrag);
  image.addEventListener('mouseup', endDrag);
  image.addEventListener('mouseleave', endDrag);
}

function drag() {
  event.preventDefault();

  //x += 0.1;

  let X = (-((event.clientX - CTM.e) / CTM.a)) + 40;
  let Y = (-((event.clientY - CTM.f) / CTM.d)) + 30;

  svg.viewBox.baseVal.x = (X - x);
  svg.viewBox.baseVal.y = (Y - y);
  /*svg.setAttribute("viewBox",
    (X - x) + " " +
    (Y - y) + " " +
    vbVals[2] + " " +
    vbVals[3]);*/
}


function startDrag() {
  image.addEventListener('mousemove', drag);

  x = (-((event.clientX - CTM.e) / CTM.a)) + 40;
  y = (-((event.clientY - CTM.f) / CTM.d)) + 30;

  //vbVals = svg.getAttribute("viewBox").split(" "); /* added this */
  x -= /*parseFloat(vbVals[0])*/ svg.viewBox.baseVal.x;
  y -= /*parseFloat(vbVals[1])*/ svg.viewBox.baseVal.y;

  z = /*parseFloat(vbVals[2])*/ svg.viewBox.baseVal.width;
  w = /*parseFloat(vbVals[3])*/ svg.viewBox.baseVal.height;
}

function endDrag() {
  image.removeEventListener("mousemove", drag);
}
figure {
  width: 300px;
  background: wheat;
  margin: 0 auto;
}

.static {
  cursor: not-allowed;
}

.draggable {
  cursor: move;
}
<div class="section-library-detailbox">
  <div class="inner">
    <figure id="parImage"><svg class="draggable" viewBox="-15 -10 400 440">
                      <path d="M30,1h40l29,29v40l-29,29h-40l-29-29v-40z" stroke="#000" fill="none"/> 
  <path d="M31,3h38l28,28v38l-28,28h-38l-28-28v-38z" fill="#a23"/> 
  <text x="50" y="68" font-size="48" fill="#FFF" text-anchor="middle"><![CDATA[410]]></text>
                </svg></figure>
  </div>
</div>


推荐阅读