css - 反应计时器没有正确转换
问题描述
我的 React Timer 几乎准备好了,我给它添加了一个动画,但是有一些问题:首先,当你从会话中中断计时器时,它会闪烁 2 或 3 秒/渲染(它首先显示 -01:60在它上面然后环形动画需要时间来“重新填充”),我如何防止奇怪的渲染和环形的重新填充?它有一个过渡属性,我当时尝试将其设置为无或将持续时间设置为零,因此它不需要时间,但它似乎没有任何效果。
其次,当您暂停并播放计时器很多时,显示的秒数会减少 3,而它们应该停在那里,而且如果我能够解决这个问题,那么当我暂停并播放计时器很多时,戒指不会与计时器同步(因为转换发生在一秒的开始,所以即使您在该秒的中途暂停计时器,转换也不会停止)
定时器组件:
import * as React from "https://cdn.skypack.dev/react@17.0.1";
import * as ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";
var timer_is_paused = true, timer_is_resetted = true;
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = {
mStr: this.props.s_mins < 10 ? "0" + this.props.s_mins.toString() :
this.props.s_mins.toString(),
sStr: "00",
onBreak: false,
class: "fas fa-play",
strke: "rgb(12, 140, 214)",
strke_len: 942,
tr: "stroke-dasharray 0.3s linear;"
}
this.expected;
this.interval = 300;
this.currMins = this.props.s_mins - 1; //25:00 => 24:60
this.circleDecrement = 942 / this.props.s_mins / 60;
this.strkeLen = 942;
this.start_timer = this.start_timer.bind(this);
this.play_pause = this.play_pause.bind(this);
this.reset = this.reset.bind(this);
}
start_timer() {
if(timer_is_paused) return false;
this.strkeLen -= this.circleDecrement;
var dt = Date.now() - this.expected;
var seconds = Math.floor(dt / this.interval),
minutes = Math.floor(seconds / 60);
if(seconds === (this.currMins + 1) * 60 + 1) {
this.setState({tr: "none !important;"})
this.setState(state => ({
mStr: "00",
sStr: "00",
strke_len: 0,
onBreak: !state.onBreak,
tr: "stroke-dasharray 0.3s linear;"
}));
this.currMins = (this.state.onBreak ? this.props.b_mins : this.props.s_mins) - 1;
this.circleDecrement = 942 / 60 / (this.state.onBreak ? this.props.b_mins : this.props.s_mins);
this.strkeLen = 942;
this.expected = Date.now();
}
else {
seconds = (60 * (minutes + 1) - seconds).toString(); //same as (60 - seconds % 60).toString();
minutes = (this.currMins - minutes).toString();
console.log(minutes, seconds);
this.setState({
mStr: minutes < 10 ? "0" + minutes : minutes,
sStr: seconds < 10 ? "0" + seconds : seconds,
strke_len: Math.floor(this.strkeLen)
});
}
setTimeout(this.start_timer, this.interval - dt % this.interval);
}
play_pause() {
if (timer_is_paused) {
this.setState({ class: "fas fa-pause"});
timer_is_paused = false;
if(timer_is_resetted) {
this.expected = Date.now();
timer_is_resetted = false;
}
setTimeout(this.start_timer, this.interval);
}
else {
this.setState({class: "fas fa-play"});
timer_is_paused = true;
}
}
reset() {
this.setState({
mStr: this.props.s_mins < 10 ? "0" + this.props.s_mins.toString() :
this.props.s_mins.toString(),
sStr: "00",
onBreak: false,
class: "fas fa-play",
strke: "rgb(12, 140, 214)",
strke_len: 942
});
this.currMins = this.props.s_mins - 1;
this.circleDecrement = 942 / this.props.s_mins / 60;
timer_is_paused = true;
timer_is_resetted = true;
}
componentDidUpdate(prevProps) {
if(this.props.s_mins !== prevProps.s_mins && !this.state.onBreak) {
this.setState({
mStr: this.props.s_mins < 10 ? "0" + this.props.s_mins.toString() :
this.props.s_mins.toString(),
sStr: "00"
});
this.circleDecrement = 942 / 60 / this.props.s_mins;
this.currMins = this.props.s_mins - 1;
}
else if(this.props.b_mins !== prevProps.b_mins && this.state.onBreak) {
this.setState({
mStr: this.props.b_mins < 10 ? "0" + this.props.b_mins.toString() :
this.props.b_mins.toString(),
sStr: "00"
});
this.currMins = this.props.b_mins - 1;
this.circleDecrement = 942 / 60 / this.props.b_mins;
}
}
render() {
return <div><svg>
<circle stroke= "grey" />
<circle id="path" stroke={this.state.strke} transition={this.state.tr}
stroke-dasharray={this.state.strke_len.toString() + " 942"}/>
</svg>
<div id="timeriii">
<span id="timer-label">{this.state.onBreak ? "Break" : "Session"}</span><br />
<span id="time-left">{this.state.mStr}:{this.state.sStr}</span><br />
<button id="start_stop" onClick={this.play_pause} class="left-positioned">
<i class={this.state.class}></i>
</button>
<button id="reset" onClick={this.reset} class="right-positioned"><i class="fas fa-undo" /></button>
</div>
</div>
}
}
圆的CSS:
#path {
transform: rotate(90deg);
transform-origin: center;
transition: stroke-dasharray 0.3s linear;
stroke-linecap: round;
}
解决方案
推荐阅读
- azure - 如何从 azure devops 中的另一个构建管道触发构建
- javascript - DataTable TypeError:d.trim 不是函数
- html - 响应式页面:将一行转换为两个或三个的最简单方法
- ios - 上传 4.7 英寸而不是 5.5 英寸的 App Store 屏幕截图
- php - 在 PHP API 中使用单选按钮和滑块
- python - modulenotfounderror 没有名为“modin”的模块
- python - 在 django 中将模型表单作为 json 响应发送
- discord - Discord.js 如何列出具有特定角色的所有成员的显示名称
- c# - 使用 System.Management.Automation 运行 PS 脚本时出现查找程序集的问题
- mesos - Mesos/Chronos 任务如何更新为已完成任务状态?