根据用户提供的值动画svg行

时间:2017-04-09 07:39:12

标签: javascript reactjs svg

我应该如何垂直制作我的svg线?我有一个温度计svg。我想根据用户提供的值移动温度计的针,但我只能显示svg。初始值为1,针头应为1,但约为-19,-18。我还创建了一个webpackbin来展示我做了什么

这是链接

https://www.webpackbin.com/bins/-KhGUeUlftWQUNDSxMrC

我粘贴的下面的代码不完整,因为我必须删除路径代码,因为SO的身体限制。

const normalize = (value, maxValue) => {
  const capacity = parseFloat(maxValue);
  // needle ranges from 0 to 50 degrees
  // It should not overflow
  const nValue = (parseFloat(value) / capacity) * 50;
  return Math.max(Math.min(nValue, 50), 0);
};

class HelloSvg extends React.Component {
  constructor() {
    super();
    this.state = {value: '1'};

  }


  componentDidMount() {
    const {value} = this.state;
    this.animation.setAttribute('from', this.animation.getAttribute('to'));
    this.animation.setAttribute('to', 50 - value);
    this.animation.beginElement();
  }

  handleChange(event) { 
    this.setState({ value: event.target.value });
  }


  //shouldComponentUpdate() {
    //return false;
  //}

  render() {
    const {value} = this.state;
    console.log(this.state.value);
    return (
      <div>
      Hello from React
      <input type="range" min='1' max='50' onChange={this.handleChange.bind(this)} />
        Value is {this.state.value}
      <svg width="100%" height="auto" viewBox="50 50 60 800" version="1.1" xmlns="http://www.w3.org/2000/svg">
        <defs>
    <linearGradient x1="-103.596615%" y1="53.6675027%" x2="174.725349%" y2="53.6675027%" id="linearGradient-1">
        <stop stopColor="#000000" offset="0%"></stop>
        <stop stopColor="#B6B6B6" offset="50%"></stop>
        <stop stopColor="#FFFFFF" offset="100%"></stop>
    </linearGradient>
</defs>
<g id="Page-1" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
    <g id="thermometer">
        <g id="callibrations" transform="translate(-3.099210, -1.008722)">
            <rect id="rect4197" fill="#1ab394" x="0.46429" y="0.99612" width="227.30853" height="817.64752"></rect>
            <path d="M113.15625,43.46875 C98.74432,43.49155 89.08034,59.50943 92.09455,72.90625 C92.30532,282.95724 91.65711,451.01733 92.46875,661.0625 C94.96609,678.28747 121.07484,684.93864 131.09375,670.5625 C140.06366,658.7571 134.72639,643.12281 136.1538,629.53125 C135.90071,426.03222 136.67745,264.52501 135.71875,61.03125 C133.78141,50.75755 123.6736,42.80162 113.15625,43.46875 Z" id="path4415" fill="url(#linearGradient-1)"></path>
            <rect id="rect3857" fill="white" x="0.46429" y="0.99612" width="227.30853" height="817.64752"></rect>
            <path d="M114.1186,51.45093 C121.88695,51.45093 128.14089,57.70487 128.14089,65.47322 L128.14089,698.52196 C128.14089,706.29031 121.88695,712.54425 114.1186,712.54425 C106.35025,712.54425 100.09631,706.29031 100.09631,698.52196 L100.09631,65.47322 C100.09631,57.70487 106.35025,51.45093 114.1186,51.45093 L114.1186,51.45093 Z" id="rect3048" fill="grey"></path>
            <rect id="level" fill="blue" opacity="0.79" x="100.089208" y="500" width="28.0599995" height="200">
               <animateTransform
                      attributeName="height"
                      to="30"
                      dur="300ms"
                      repeatCount="0"
                      fill="freeze"
                      ref={(animation) => { this.animation = animation; }}
                 />
            </rect>
            <path d="M128.14089,65.47322 L128.14089,698.52196 C128.14089,706.29031 121.88695,712.54425 114.1186,712.54425 C106.35025,712.54425 100.09631,706.29031 100.09631,698.52196 L100.09631,65.47322 C100.09631,57.70487 106.35025,51.45093 114.1186,51.45093 C121.88695,51.45093 128.14089,57.70487 128.14089,65.47322 Z" id="path3887" fill="grey" opacity="0.454616855"></path>
            <path d="M162.16938,727.645267 C162.16938,754.183009 140.65635,775.696112 114.118545,775.696112 C87.580845,775.696112 66.06771,754.183009 66.06771,727.645267 C66.06771,701.107514 87.580845,679.594421 114.118545,679.594421 C140.65635,679.594421 162.16938,701.107514 162.16938,727.645267 Z" id="path3046" fill="#056AAE"></path>
            <path d="M162.16938,727.645267 C162.16938,754.183009 140.65635,775.696112 114.118545,775.696112 C87.580845,775.696112 66.06771,754.183009 66.06771,727.645267 C66.06771,701.107514 87.580845,679.594421 114.118545,679.594421 C140.65635,679.594421 162.16938,701.107514 162.16938,727.645267 Z" id="path3051" fill="red" opacity="0.47163122"></path>
           </g>
              <text id="Unit" fontFamily="ArialMT, Arial" fontSize="32" fontWeight="normal" fill="#0E0E0E">
                  <tspan x="94" y="32">°F</tspan>
              </text>
              <g id="callibtext" transform="translate(21.000000, 94.000000)" fontSize="24" fontFamily="ArialMT, Arial" fill="#0E0E0E" fontWeight="normal">
                  <text id="-30">
                      <tspan x="0" y="581">-30</tspan>
                  </text>
                  <text id="50">
                      <tspan x="8" y="22">50</tspan>
                  </text>
                  <text id="0">
                      <tspan x="21" y="371">0</tspan>
                  </text>
              </g>
          </g>
      </g>
  </svg>
    </div> 
    );
  }
}

export default HelloSvg;

我想要移动的针是代码中的矩形,所以我试图在那里应用动画,但我看不出任何影响。

1 个答案:

答案 0 :(得分:1)

以下工作示例是否对您有所帮助?

var slider = document.getElementById("slider");
var anim = document.getElementById("anim");

slider.addEventListener("change", function(evt) {

  var sliderValue = evt.target.value;
  var currentTo = anim.getAttribute("to");
  anim.setAttribute("from", currentTo);
  anim.setAttribute("to", 400 - sliderValue);
  anim.beginElement();

});
<svg width="100" height="400">
  <line x1="50" y1="400" x2="50" y2="0" stroke="lightgrey" stroke-width="20"/>
  <line x1="50" y1="400" x2="50" y2="400" stroke="red" stroke-width="20">
    <animate id="anim"
             attributeName="y2"
             to="400"
             dur="1s"
             fill="freeze"/>
  </line>
</svg>

<input id="slider" type="range" min="0" max="400" step="1" value="0"/>