ReactJS,CSS和SVG动画,以及重新渲染

时间:2018-01-10 01:39:27

标签: javascript css reactjs svg

这个问题可以在这里看到:
https://codepen.io/fsabe/pen/opEVNR?editors=0110

首次加载时,您会看到蓝色圆圈四处移动,红色框渐渐消失 圆圈通过svg标签和css动画框进行动画制作 如果单击画布上的任意位置,代码将触发重新渲染,可以通过打开控制台来验证。

我的期望是两个动画都会在点击时重置,但这不会发生 我有一种预感,这与缓存和反应的影子DOM有关。

为什么会这样?如何解决?

代码如下:

df=ts.to_frame('Val').reset_index()
df['index']=df['index'].apply(lambda x : pd.date_range(start=x,periods=5).tolist())
df.Val/=5
ts_new=df.set_index('Val')['index'].apply(pd.Series).stack().reset_index().groupby(0).Val.sum()
ts_new
Out[33]: 
0
2017-01-01     20.0
2017-01-02     20.0
2017-01-03     60.0
2017-01-04     60.0
2017-01-05     60.0
2017-01-06     40.0
2017-01-07     40.0
2017-01-10    100.0
2017-01-11    100.0
2017-01-12    100.0
2017-01-13    100.0
2017-01-14    100.0
Name: Val, dtype: float64
#nonSvgBox {
  animation-duration: 1s;
  animation-name: fade;
  width: 100px;
  height: 100px;
  background-color: red;
}

@keyframes fade {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

谢谢。

1 个答案:

答案 0 :(得分:2)

React正在重复使用元素,因此动画不会重播他们已经为当前元素播放的b / c。

我认为在这种情况下采用dom操作比使用某些setState技巧更容易。

https://codepen.io/guanzo/pen/vpdPzX?editors=0110

将refs存储到2个元素,然后使用JS触发动画。

class Component extends React.Component {
  onClick() {
    this.svgAnimate.beginElement()//triggers animation
    this.square.style.animation = 'none';//override css animation
    this.square.offsetHeight; /* trigger reflow */
    this.square.style.animation = null; //fallback to css animation
  }

    render() {
    console.log('rendering');
        return (
            <div onClick={() => this.onClick()}>
                <svg>
                    <path 
                        stroke="blue"
            strokeWidth="10"
                        fill="transparent"
                        d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80"
            strokeDasharray="251.2,251.2">
              <animate
                ref={(svgAnimate) => { this.svgAnimate = svgAnimate; }} 
                attributeType="css"
                attributeName="stroke-dasharray"
                from="0" to="251.2" dur="1s" />
                </path>
              </svg>
        <div id="nonSvgBox"
          ref={(square) => { this.square = square; }} 
          ></div>
            </div>
        );
    }
}

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