如何翻译svg的路径

时间:2017-05-23 16:13:55

标签: javascript animation svg svg-animate

我有一辆车速表。我想创建一些动画。有一个由路径制成的针。我已将该路径分组,以便我可以翻译或转换。它是一个米/针,必须随用户提供的价值移动。如果用户提供介于0和25之间的值,则针应位于第一个切片中,依此类推。但我不知道移动由路径构成的针。

我创建了一个jsbin

http://jsbin.com/danefehiro/1/edit?html,js,output

这是代码

<input type="text" id="speedValue" />
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 344.996 344.996" xml:space="preserve">
<g>
    <path fill="rgb(132, 219, 255)" d="M7.5,243.337h52.227c0-31.141,12.622-59.334,33.03-79.741l-36.93-36.93
        C25.968,156.525,7.5,197.774,7.5,243.337z"/>
    <path fill="rgb(84, 192, 235)" d="M55.827,126.666l36.93,36.93c20.408-20.408,48.6-33.03,79.741-33.03V78.339
        C126.935,78.339,85.685,96.807,55.827,126.666z"/>
    <circle style="fill:#51B3DA;" cx="172.498" cy="243.337" r="23.32"/>
    <path fill="rgb(255, 209, 92)" d="M337.496,243.337h-52.227c0-31.141-12.622-59.334-33.03-79.741l36.93-36.93
        C319.028,156.525,337.496,197.774,337.496,243.337z"/>
    <path fill="rgb(255, 112, 88)" d="M289.169,126.666l-36.93,36.93c-20.408-20.408-48.6-33.03-79.741-33.03V78.339
        C218.061,78.339,259.311,96.807,289.169,126.666z"/>
    <g id="meter">
        <path fill="#40596B" id="needle" d="M175.884,220.29c10.162,1.482,18.179,9.5,19.661,19.662l44.785-64.447L175.884,220.29z"/>
    </g>
</g>
</svg>


  var speedValue = document.querySelector('#speedValue');
  var needle = document.querySelector('#needle');
  var meter = document.querySelector('#needle');
  speedValue.addEventListener("click", function(event){
    var value = event.target.value;
    // if value is in between 1 - 25, the needle
    // should be on first block, if 25 - 50, then
    // the needle should be on second slice and if
    // 50  - 75, then on 3rd slice and if 75 - 100
    // then on last slice
    if (value >= 0 && value <= 25) {
      meter.setAttribute("transform", "rotate(45)");
    } else if(value > 25 && value <= 50) {
      meter.setAttribute("transform", "rotate(90)"); 
    } else {
      meter.setAttribute("transform", "rotate(180)"); 
    }
  });

1 个答案:

答案 0 :(得分:1)

当默认的#meter路径已经旋转135度时,你为自己设置了一个陷阱,并且你缺少图的变换原点。以下作品:

var speedValue = document.querySelector('#speedValue');
var needle = document.querySelector('#needle');
var meter = document.querySelector('#meter');
speedValue.addEventListener("click", function(event){
  var value = event.target.value;
  // if value is in between 1 - 25, the needle
  // should be on first block, if 25 - 50, then
  // the needle should be on second slice and if
  // 50  - 75, then on 3rd slice and if 75 - 100
  // then on last slice
  needle.setAttribute("transform-origin", "172.498px 243.337px");
  if (value >= 0 && value <= 25) {
    needle.setAttribute("transform", "rotate(-112.5)"); // 45 / 2 - 135 = -112.5
  } else if(value > 25 && value <= 50) {
    needle.setAttribute("transform", "rotate(-67.5)"); 
  } else if(value > 50 && value <= 75) {
    needle.setAttribute("transform", "rotate(-22.5)"); 
  } else {
    needle.setAttribute("transform", "rotate(22.5)"); 
  }
});

我添加了一个onLoad监听器,以便从一开始就正确定位针。

window.addEventListener("load", function(event){
  var value = event.target.value;
  needle.setAttribute("transform-origin", "172.498px 243.337px");
  needle.setAttribute("transform", "rotate(-112.5)");
});

根据评论,添加了animateTransform元素以向您展示如何使用它(即使它应该属于一个新问题)。

一个新的jsbin:http://jsbin.com/qexohozido/1/edit?html,js,output

首先在#needle:

下添加元素
<animateTransform id="animation" attributeName="transform" type="rotate" from="0 172.498 243.337" to="0 172.498 243.337" dur="1s" fill="freeze" restart="whenNotActive"/>

然后在if-else中为它设置动画:

var from = 0;
var animation = document.querySelector('#animation');
... else if(value > 50 && value <= 75) {
  animation.setAttribute("from", from + " 172.498 243.337");
  animation.setAttribute("to", "90 172.498 243.337");
  animation.beginElement();
  from = 90; 
} ...

在这种情况下,你不需要在#animation中偏移-135度,因为在onLoad期间#needle中的旋转已经被偏移了。