簡體   English   中英

在React中對SVG弧形路徑進行動畫處理

[英]Animate SVG Arc Path in React

我正在使用React,我想要實現的是在更改時在SVG弧路徑上制作動畫。 基本上,我有一個量規,它顯示0到100之間的某個值,並且該值可以更改(在下面的示例中,它每秒更改一次)。

我已經創建了這個模擬我想要的代碼筆(下面的代碼): https ://codepen.io/Gesma94/pen/oJvjwe

在示例中可以看到,我在SVG中使用d3創建了一個Gauge,其中藍色條可以占用更多或更少的時間; 如您所見,重新渲染儀表時,將僅渲染新的藍色條,而在“舊點”和“新點”之間沒有任何動畫。

我想實現的是在條形之前的點和條形將要到達的點之間進行平滑的移動(希望我已經清楚了)。

class MyComponent extends React.Component {
   render() {
      console.log("Rendering");
      const value = (this.props.value * Math.PI / 100) - Math.PI/2;

      const currentValueFilledCircle = d3.arc()
      .innerRadius(37.5)
      .outerRadius(49.5)
      .startAngle(-Math.PI/2)
      .endAngle(value)(null);

      const currentValueEmptyCircle = d3.arc()
      .innerRadius(37.5)
      .outerRadius(49.5)
      .startAngle(value)
      .endAngle(Math.PI/2)(null);

      return (
         <div style={{width: "300px", height: "300px"}}>
            <svg height="100%" width="100%" viewBox="-50 -50 100 100">
               <g>
                  <path d={currentValueFilledCircle} fill="blue" />
                  <path d={currentValueEmptyCircle} fill="gray" />
               </g>
            </svg>
         </div>
      );
   };
}

class App extends React.Component {
   constructor() {
      super();
      this.value = 77;
   }

   componentDidMount() {
      this.interval = setInterval(() => {
         const diff = Math.floor(Math.random() * 7) - 3;
         let newCurrentValue = this.value + diff;

         if (newCurrentValue > 100) newCurrentValue = 100;
         else if (newCurrentValue < 0) newCurrentValue = 0;

         this.value = newCurrentValue;
         this.forceUpdate();
      }, 500);
   }

   render() {
      return (<MyComponent value={this.value} />)
   }
}

ReactDOM.render(<App />, document.getElementById('app'));

所以,我掙扎了一段時間,但是我找到了使用react-move/Animate的解決方案: https : //react-move.js.org/#/documentation/animate

由於我無法在Codepen上使用它,因此我在沙盒中重新創建了這種情況,它是: https ://codesandbox.io/embed/0qyrmyrw

要點是代碼的以下部分:

<Animate
  start={{ value: this.props.value }}
  update={{
    value: [this.props.value], // Before the sqaure brackets!!
    timing: { duration: 750 }
  }}
>
  {(state: { value: number }) => {
    const scaledValue = (state.value * Math.PI) / 100 - Math.PI / 2;
    const currentValueFilledCircle = arc()
      .innerRadius(37.5)
      .outerRadius(49.5)
      .startAngle(-Math.PI / 2)
      .endAngle(scaledValue)(null);

    const currentValueEmptyCircle = arc()
      .innerRadius(37.5)
      .outerRadius(49.5)
      .startAngle(scaledValue)
      .endAngle(Math.PI / 2)(null);

    return (
      <React.Fragment>
        <path d={currentValueFilledCircle} fill="blue" />
        <path d={currentValueEmptyCircle} fill="gray" />
      </React.Fragment>
    );
  }}
</Animate>

基本上,通過編寫update={{value: [this.props.value] ... }}Animate Component只需運行一組具有不同值的render()方法(從前一個值到當前值),因此它給出了平滑運動效果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM