javascript - React 中的动画 SVG 弧路径
问题描述
我正在使用 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
组件只需运行一组具有不同值的 render() 方法,从前一个到当前,因此它给出了平滑移动的效果。
推荐阅读
- reactjs - Material-UI 和 Webpack,捆绑
- ffmpeg - 使用ffmpeg处理rtsp流url时出现unkonwn命令失败
- python - 索引数据帧或尝试使用 df.info() 或 df.head() 等 pandas 函数时出现 Python 错误
- nginx - 我们可以在同一位置(/)的单个 nginx conf 上配置 grpc_pass 和 proxy_pass 吗?
- installation - 安装失败 - SAP Adaptive Server Enterprise 16.0 SP03
- html - Jinaj2 模态窗口在按下数据目标的按钮时不起作用
- apache-nifi - Apache Nifi PutSQL 处理器连接到 Oracle
- matlab - 求单变量函数的最小值
- d3.js - 将 observable d3.js 画笔和焦点示例转换为 jsfiddle
- java - 有没有办法在java或c#中加密和解密阿拉伯字符串?