SVG平移和缩放不起作用

3

尝试对两个矩形进行SVG平移和缩放,但似乎无法使其正常工作。虽然我是新手,但我已经编写了以下代码,但它似乎并不起作用。如果有人能找出问题所在,请告知。我使用元素的组ID尝试根据我的js进行平移和缩放,但仍然无法正常工作。

    <!DOCTYPE html>
      <head>

     </head>
      <body>

      <svg  width="24cm" height="16cm" viewBox="-4 -1 26 20" 
      xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">


       <g id="myfield" transform="scale(1,1) translate(0,0)" >


          <g transform=" scale(1,-1) translate(0,-16)"><g id="togglefield">
           <rect id= "rectangle1" class= "rectangles" x= 2  y= 0  width= 4  height= 6  onClick="fieldDetails(event)"></rect>

       <rect  id="rectangle2" class= "rectangles" x= 2  y= 6  width= 4  
         height= 5 onClick="fieldDetails(event)"></rect>

     </g>
     <g id="togglefind">
     <circle class="circles" id="find1" cx= 4  cy= 1  r="0.2" onClick="findDetails(event)"></circle>
       <text class="text" x= 4 y= 1  transform="translate(0 2 ) scale(-1,1) rotate(180)"> 1 </text>

      <circle class="circles" id="find5" cx= 4  cy= 7  r="0.2" onClick="findDetails(event)"></circle>
      <text class="text" x= 4 y= 7  transform="translate(0 14 ) scale(-1,1) rotate(180)"> 5 </text>

      </g>
      </g>
     <rect x="12.6" y="12.4" width="3" height="3" fill="white" stroke="grey" stroke-width="0.05"/>
      <text x="13" y="13.2" font-family="Arial" font-size="0.6">Legend</text>
       <g id="Fieldlgd">
        <rect x="12.8" y="13.6" width="0.6" height="0.6" fill="none" stroke="green" stroke-width="0.04"/>
         <text x="13.6" y="14" font-family="Georgia" font-size="0.5">Field ID</text>
         <text x="13" y="14" font-family="Georgia" font-size="0.5">1</text>
           </g><g id="Findlgd">
          <circle cx="13.1" cy="14.7" r="0.12" fill="blue" stroke="red" stroke-width="0.05"/>
         <text x="13.6" y="14.85" font-family="Georgia" font-size="0.5">Find ID</text>
          <text x="13.2" y="14.7" font-family="Arial" font-size="0.45">1</text>
      </g>
         </g>
          <rect x="-4" y="0.3" width="3.2" height="12" fill="white" stroke="black" stroke-width="0" fill-opacity="0.8"/>
       <text x="-4" y="0.8" font-family="San Serif" font-size="3%">Pan and Zoom </text>
    <text x="-2.7" y="1.8" font-family="Georgia" font-size="4%">N</text>
      <polyline id="panup" onclick="panup_click(evt)" points="-3,2 -2.5,1 -2,2 -2.3,1.9 -2.7,1.9 -3,2" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
      <text x="-2.7" y="3.4" font-family="Georgia" font-size="4%">S</text>
       <polyline id="pandown" onclick="pandown_click(evt)" points="-3,2.8 -2.5,3.8 -2,2.8 -2.3,2.9 -2.7,2.9 -3,2.8" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
      <text x="-3.3" y="2.6" font-family="Georgia" font-size="4%">W</text>
       <polyline id="panleft" onclick="panleft_click(evt)" points="-2.7,1.9 -3.7,2.4 -2.7,2.9 -2.8,2.6 -2.8,2.2 -2.7,1.9" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
      <text x="-2.1" y="2.6" font-family="Georgia" font-size="4%">E</text>
      <polyline id="panright" onclick="panright_click(evt)" points="-2.3,1.9 -1.3,2.4 -2.3,2.9 -2.2,2.6 -2.2,2.2 -2.3,1.9" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
      <text x="-2.7" y="2.6" font-family="Georgia" font-size="4%">C</text>
       <circle id="recenter" onclick="recenter_click(evt)" cx="-2.5" cy="2.4" r="0.3" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
    <polyline id="zoomcross" points="-2.6,4.2 -2.4,4.2 -2.4,4.6 -2.1,4.6 -2.1,4.8 -2.4,4.8 -2.4,5.3 -2.6,5.3 -2.6,4.8 -2.9,4.8 -2.9,4.6 -2.6,4.6 -2.6,4.2" fill="cornflowerblue"/>
   <rect id="zoomIn" onclick="zoomin_click(evt)" x="-3" y="4" width="1" height="1.5" fill="white" stroke="black" stroke-width="0.05" opacity="0.2"/>
  <rect id="zoomdash" x="-2.9" y="5.9" width="0.8" height="0.2" 
   fill="cornflowerblue"/>
   <rect id="zoomOut" onclick="zoomout_click(evt)" x="-3" y="5.7" width="1" height="0.6" fill="white" stroke="black" stroke-width="0.05" opacity="0.2"/>

</svg>



// Pan left function  
function panleft_click(evt) {
var root = document.documentElement;  
           // variable to get the group transform object
    var myfield  = null;
    myfield  = document.getElementById("myfield");

            // Incase the group has no Id then get the first '<g>' element
    if(myfield  === null)   
            myfield  = document.getElementsByTagName('g')[0];

  var goIn = evt.target;  // thus line is currently not used

  // Fetch the current transform state of the group element into a 
  var matrix = myfield.getCTM();
  // Read the translate attributes from the matrix into variable x and y
  // Below is the desired leftward change
  var x = (matrix.e + 2) / matrix.a  ; // Divide change by current scale to remove exponential movement
  var y = matrix.f  / matrix.a ;  // To keep motion only along one axis
  // Set the new transform attribute for the group
  myfield.setAttributeNS(null,"transform", "scale(" + matrix.a + "," + matrix.d + ") translate(" + x + "," + y + ")");

}

// Pan right function  
function panright_click(evt) {

           // variable to get the group transform object
    var myfield  = null;
    myfield  = document.getElementById("myfield");

            // Incase the group has no Id then get the first '<g>' element
    if(myfield  === null)   
            myfield  = document.getElementsByTagName('g')[0];

  var goIn = evt.target;  // thus line is currently not used

  // Fetch the current transform state of the group element into a matrix
  var matrix = myfield.getCTM();
  // Read the translate attributes from the matrix into variable x and y
  // Below is the desired rightward change
  var x = (matrix.e - 2) / matrix.a;   // Divide change by current scale to remove exponential movement
  var y = matrix.f  / matrix.a;      // To keep motion only along one axis
  // Set the new transform attribute for the group
  myfield.setAttributeNS(null,"transform", "scale(" + matrix.a + "," + matrix.d + ") translate(" + x + "," + y + ")");

}

// Pan up function  
function panup_click(evt) {

           // variable to get the group transform object
    var myfield  = null;
    myfield  = document.getElementById("myfield");

            // Incase the group has no Id then get the first '<g>' element
    if(myfield  === null)   
            myfield  = document.getElementsByTagName('g')[0];

  var goIn = evt.target;  // thus line is currently not used

  // Fetch the current transform state of the group element into a matrix
  var matrix = myfield.getCTM();
  // Read the translate attributes from the matrix into variable x and y
  var x = matrix.e / matrix.a ;     // Divided by scale to keep motion only along one axis

  // Below is the desired upward change
  var y = (matrix.f + 2) / matrix.a;   // Divide change by current scale to remove exponential movement
  // Set the new transform attribute for the group
  myfield.setAttributeNS(null,"transform", "scale(" + matrix.a + "," + matrix.d + ") translate(" + x + "," + y + ")");

}

// Pan down function  
function pandown_click(evt) {

           // variable to get the group transform object
    var myfield  = null;
    myfield  = document.getElementById("myfield");

            // Incase the group has no Id then get the first '<g>' element
    if(myfield  === null)   
            myfield  = document.getElementsByTagName('g')[0];

  var goIn = evt.target;  // thus line is currently not used

  // Fetch the current transform state of the group element into a matrix
  var matrix = myfield.getCTM();
  // Read the translate attributes from the matrix into variable x and y
  var x = matrix.e / matrix.a;   // Divided by scale to keep motion only along one axis

  // Below is the desired downward change
  var y = (matrix.f - 2) / matrix.a;   // Divide change by current scale to remove exponential movement
  // Set the new transform attribute for the group
  myfield.setAttributeNS(null,"transform", "scale(" + matrix.a + "," + matrix.d + ") translate(" + x + "," + y + ")");

}

   // Zoom in (enlarge) function 
   function zoomin_click(evt) {

           // variable to get the group transform object
    var myfield  = null;
    myfield  = document.getElementById("myfield");

            // Incase the group has no Id then get the first '<g>' element
    if(myfield  === null)   
            myfield  = document.getElementsByTagName('g')[0];

      var goIn = evt.target;  // thus line is currently not used
  // Fetch the current transform state of the group element into a matrix
  var matrix = myfield.getCTM();
  // Read the scale attributes from the matrix into variable x and y
  // then apply an increment by multiplying
      var x = matrix.a * 1.2;
      var y = matrix.d * 1.2;

    // Set the new transform attribute for the group
    myfield.setAttributeNS(null,"transform", "scale(" + x + "," + y + ") translate(" + matrix.e + "," + matrix.f + ")");

}
   // Zoom out (reduce) function 
   function zoomout_click(evt) {

           // variable to get the group transform object
    var myfield  = null;
    myfield  = document.getElementById("myfield");

            // Incase the group has no Id then get the first '<g>' element
    if(myfield  === null)   
            myfield  = document.getElementsByTagName('g')[0];

      var goIn = evt.target;  // thus line is currently not used
  // Fetch the current transform state of the group element into a matrix
  var matrix = myfield.getCTM();
  // Read the scale attributes from the matrix into variable x and y
  // then apply a reduction in scale by dividing
      var x = matrix.a / 1.2;
      var y = matrix.d / 1.2;

    // Set the new transform attribute for the group
    myfield.setAttributeNS(null,"transform", "scale(" + x + "," + y + ") translate(" + matrix.e + "," + matrix.f + ")");

}
   // Recenter/reset function 
   function recenter_click(evt) {

    // Reset the group to the original transform
    document.getElementById("myfield").setAttributeNS(null,"transform", "scale(1,1) translate(0,0)");  
}

“it doesn't seem to work” 意思是什么?你已经做到哪一步了?请详细说明。 如果您将您发布的代码转换为 StackOverflow Snippet 会很有用。 - Paul LeBeau
@PaulLeBeau似乎getCTM无法正常工作,因为我无法访问矩阵值。 - lloyd
1个回答

1

getCTM不是用于此目的的正确函数。它包括由于viewBox等应用于父SVG的任何变换。您只想操作“myfield”组的transform属性。

我建议仅使用预定义的DOM函数来操纵tranform属性。

您可以使用以下方式访问变换属性DOM:

<myfield DOM object>.transform.baseVal

这将返回一个SVGTransformList对象,它基本上是包含两个SVGTransform对象的数组。一个用于scale()部分,另一个用于transform()部分。一旦你拥有了这些对象,你就可以给它们赋新值,SVG 将会更新。

function panup_click(evt) {
  pan(0,-2);
}

function pandown_click(evt) {
  pan(0,2);
}

function panleft_click(evt) {
  pan(-2,0);
}

function panright_click(evt) {
  pan(2,0);
}

// Pan function  
function pan(dx, dy) {
  // variable to get the group transform object
  var myfield  = document.getElementById("myfield");
  // Fetch the current value of the transform attribute
  var transformList = myfield.transform.baseVal;
  var translate = transformList.getItem(1);
  // Adjust the translate transform item
  var tx = translate.matrix.e;
  var ty = translate.matrix.f;
  translate.setTranslate(tx + dx, ty + dy);
}

// Zoom in (enlarge) function 
function zoomin_click(evt) {
  zoom(1.2);
}

// Zoom out (reduce) function 
function zoomout_click(evt) {
  zoom(1 / 1.2);
}

function zoom(scaleFactor)
{
  // variable to get the group transform object
  var myfield  = document.getElementById("myfield");
  // Fetch the current value of the transform attribute
  var transformList = myfield.transform.baseVal;
  var scale = transformList.getItem(0);
  // Adjust the translate transform item
  var s = scale.matrix.a;
  scale.setScale(s * scaleFactor, s * scaleFactor);
}

// Recenter/reset function 
function recenter_click(evt) {
  // Reset the group to the original transform
  document.getElementById("myfield").setAttributeNS(null,"transform", "scale(1,1) translate(0,0)");  
}
<svg  width="24cm" height="16cm" viewBox="-4 -1 26 20" 
      xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

  <g id="myfield" transform="scale(1,1) translate(0,0)" >

    <g transform=" scale(1,-1) translate(0,-16)">
      <g id="togglefield">
        <rect id= "rectangle1" class= "rectangles" x= 2  y= 0  width= 4  height= 6  onClick="fieldDetails(event)"></rect>
        <rect  id="rectangle2" class= "rectangles" x= 2  y= 6  width= 4  height= 5 onClick="fieldDetails(event)"></rect>
      </g>
      <g id="togglefind">
        <circle class="circles" id="find1" cx= 4  cy= 1  r="0.2" onClick="findDetails(event)"></circle>
        <text class="text" x= 4 y= 1  transform="translate(0 2 ) scale(-1,1) rotate(180)"> 1 </text>
        <circle class="circles" id="find5" cx= 4  cy= 7  r="0.2" onClick="findDetails(event)"></circle>
        <text class="text" x= 4 y= 7  transform="translate(0 14 ) scale(-1,1) rotate(180)"> 5 </text>
      </g>
    </g>

    <rect x="12.6" y="12.4" width="3" height="3" fill="white" stroke="grey" stroke-width="0.05"/>
    <text x="13" y="13.2" font-family="Arial" font-size="0.6">Legend</text>
    <g id="Fieldlgd">
      <rect x="12.8" y="13.6" width="0.6" height="0.6" fill="none" stroke="green" stroke-width="0.04"/>
      <text x="13.6" y="14" font-family="Georgia" font-size="0.5">Field ID</text>
      <text x="13" y="14" font-family="Georgia" font-size="0.5">1</text>
    </g>
    <g id="Findlgd">
      <circle cx="13.1" cy="14.7" r="0.12" fill="blue" stroke="red" stroke-width="0.05"/>
      <text x="13.6" y="14.85" font-family="Georgia" font-size="0.5">Find ID</text>
      <text x="13.2" y="14.7" font-family="Arial" font-size="0.45">1</text>
    </g>
  </g>

  <rect x="-4" y="0.3" width="3.2" height="12" fill="white" stroke="black" stroke-width="0" fill-opacity="0.8"/>
  <text x="-4" y="0.8" font-family="San Serif" font-size="3%">Pan and Zoom </text>
  <text x="-2.7" y="1.8" font-family="Georgia" font-size="4%">N</text>
  <polyline id="panup" onclick="panup_click(evt)" points="-3,2 -2.5,1 -2,2 -2.3,1.9 -2.7,1.9 -3,2" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
  <text x="-2.7" y="3.4" font-family="Georgia" font-size="4%">S</text>
  <polyline id="pandown" onclick="pandown_click(evt)" points="-3,2.8 -2.5,3.8 -2,2.8 -2.3,2.9 -2.7,2.9 -3,2.8" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
  <text x="-3.3" y="2.6" font-family="Georgia" font-size="4%">W</text>
  <polyline id="panleft" onclick="panleft_click(evt)" points="-2.7,1.9 -3.7,2.4 -2.7,2.9 -2.8,2.6 -2.8,2.2 -2.7,1.9" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
  <text x="-2.1" y="2.6" font-family="Georgia" font-size="4%">E</text>
  <polyline id="panright" onclick="panright_click(evt)" points="-2.3,1.9 -1.3,2.4 -2.3,2.9 -2.2,2.6 -2.2,2.2 -2.3,1.9" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
  <text x="-2.7" y="2.6" font-family="Georgia" font-size="4%">C</text>
  <circle id="recenter" onclick="recenter_click(evt)" cx="-2.5" cy="2.4" r="0.3" fill="lavender" stroke="cornflowerblue" stroke-width="0.05" fill-opacity="0.6"/>
  <polyline id="zoomcross" points="-2.6,4.2 -2.4,4.2 -2.4,4.6 -2.1,4.6 -2.1,4.8 -2.4,4.8 -2.4,5.3 -2.6,5.3 -2.6,4.8 -2.9,4.8 -2.9,4.6 -2.6,4.6 -2.6,4.2" fill="cornflowerblue"/>
  <rect id="zoomIn" onclick="zoomin_click(evt)" x="-3" y="4" width="1" height="1.5" fill="white" stroke="black" stroke-width="0.05" opacity="0.2"/>
  <rect id="zoomdash" x="-2.9" y="5.9" width="0.8" height="0.2" fill="cornflowerblue"/>
  <rect id="zoomOut" onclick="zoomout_click(evt)" x="-3" y="5.7" width="1" height="0.6" fill="white" stroke="black" stroke-width="0.05" opacity="0.2"/>

</svg>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接