javascript - SVG 平移和缩放不起作用

标签 javascript html svg

尝试对两个矩形执行此 svg 平移和缩放,我似乎无法让它工作。这真的很新,但我能够想出这个,但它似乎不起作用。我也添加了我的 javascript 代码,如果有人似乎找不到问题,我使用元素的组 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)");  
}

最佳答案

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

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

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

<myfield DOM object>.transform.baseVal

返回一个 SVGTransformList 对象,它基本上是一个包含两个 SVGTramnsform 对象的数组。一个用于 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>

关于javascript - SVG 平移和缩放不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48242935/

相关文章:

javascript - 给某些 map 图 block 上色

jquery - textarea 填充 jsfiddle 中的表格单元格但不在实际应用程序中

html - 匹配列表元素符号与 `<div>` 中文本的对齐方式

javascript - 位置:固定一个元素覆盖其他元素

javascript - d3.js 使用 DateTime 和 int 数组创建一个简单的折线图

javascript - 将 Javascript 变量传递到 PHP 服务器

javascript - 为什么 CORS 发布请求在一种情况下有效,但在另一种情况下无效

javascript - Sass:使用@use 和@forward 时的模块循环

javascript - 将使用 D3js 创建的 SVG 转换为 PNG

javascript - 长文本的省略号