如何实现React原生倒计时圈
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何实现React原生倒计时圈相关的知识,希望对你有一定的参考价值。
有人,请帮助我在react-native中实现倒计时圈我希望计时器从300秒开始下降到0,其中有一个动画圈和文本(时间)。我尝试使用https://github.com/MrToph/react-native-countdown-circle
但问题是文本(时间)在一个完整的动画后更新。您还可以看到我在那里打开的问题。
以下是我的实现的代码片段
<CountdownCircle
seconds=300
radius=25
borderWidth=3
color="#006400"
bgColor="#fff"
textStyle= fontSize: 15
onTimeElapsed=() =>
console.log('time over!')
/>
答案
我更改了您在问题中提到的库文件。我知道这不好,但我试图解决你的问题。
import CountdownCircle from 'react-native-countdown-circle'//you can make your own file and import from that
<CountdownCircle
seconds=30
radius=30
borderWidth=8
color="#ff003f"
bgColor="#fff"
textStyle= fontSize: 20
onTimeElapsed=() => console.log("Elapsed!")
/>
这是库文件,现在你可以将它作为一个组件使用,这里是react-native-countdown-circle库文件代码(修改后的代码)
import React from "react";
import
Easing,
Animated,
StyleSheet,
Text,
View,
ViewPropTypes
from "react-native";
import PropTypes from "prop-types";
// compatability for react-native versions < 0.44
const ViewPropTypesStyle = ViewPropTypes
? ViewPropTypes.style
: View.propTypes.style;
const styles = StyleSheet.create(
outerCircle:
justifyContent: "center",
alignItems: "center",
backgroundColor: "#e3e3e3"
,
innerCircle:
overflow: "hidden",
justifyContent: "center",
alignItems: "center",
backgroundColor: "#fff"
,
leftWrap:
position: "absolute",
top: 0,
left: 0
,
halfCircle:
position: "absolute",
top: 0,
left: 0,
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
backgroundColor: "#f00"
);
function calcInterpolationValuesForHalfCircle1(animatedValue, shadowColor )
const rotate = animatedValue.interpolate(
inputRange: [0, 50, 50, 100],
outputRange: ["0deg", "180deg", "180deg", "180deg"]
);
const backgroundColor = shadowColor;
return rotate, backgroundColor ;
function calcInterpolationValuesForHalfCircle2(
animatedValue,
color, shadowColor
)
const rotate = animatedValue.interpolate(
inputRange: [0, 50, 50, 100],
outputRange: ["0deg", "0deg", "180deg", "360deg"]
);
const backgroundColor = animatedValue.interpolate(
inputRange: [0, 50, 50, 100],
outputRange: [color, color, shadowColor, shadowColor]
);
return rotate, backgroundColor ;
function getInitialState(props)
console.log();
return
circleProgress,
secondsElapsed: 0,
text: props.updateText(0, props.seconds),
interpolationValuesHalfCircle1: calcInterpolationValuesForHalfCircle1(
circleProgress,
props
),
interpolationValuesHalfCircle2: calcInterpolationValuesForHalfCircle2(
circleProgress,
props
)
;
const circleProgress = new Animated.Value(0);
export default class PercentageCircle extends React.PureComponent
static propTypes =
seconds: PropTypes.number.isRequired,
radius: PropTypes.number.isRequired,
color: PropTypes.string,
shadowColor: PropTypes.string, // eslint-disable-line react/no-unused-prop-types
bgColor: PropTypes.string,
borderWidth: PropTypes.number,
containerStyle: ViewPropTypesStyle,
textStyle: Text.propTypes.style,
updateText: PropTypes.func,
onTimeElapsed: PropTypes.func
;
static defaultProps =
color: "#f00",
shadowColor: "#999",
bgColor: "#e9e9ef",
borderWidth: 2,
seconds: 10,
children: null,
containerStyle: null,
textStyle: null,
onTimeElapsed: () => null,
updateText: (elapsedSeconds, totalSeconds) =>
(totalSeconds - elapsedSeconds).toString()
;
constructor(props)
super(props);
this.state = getInitialState(props);
this.restartAnimation();
componentWillReceiveProps(nextProps)
if (this.props.seconds !== nextProps.seconds)
this.setState(getInitialState(nextProps));
onCircleAnimated = ( finished ) =>
// if animation was interrupted by stopAnimation don't restart it.
if (!finished) return;
const secondsElapsed = this.state.secondsElapsed + 1;
const callback =
secondsElapsed < this.props.seconds
? this.restartAnimation
: this.props.onTimeElapsed;
const updatedText = this.props.updateText(
secondsElapsed,
this.props.seconds
);
this.setState(
...getInitialState(this.props),
secondsElapsed,
text: updatedText
,
callback
);
;
restartAnimation = () =>
Animated.timing(this.state.circleProgress,
toValue:
parseFloat(JSON.stringify(this.state.circleProgress)) +
100 / this.props.seconds,
duration: 1000,
easing: Easing.linear
).start(this.onCircleAnimated);
;
renderHalfCircle( rotate, backgroundColor )
const radius = this.props;
return (
<View
style=[
styles.leftWrap,
width: radius,
height: radius * 2
]
>
<Animated.View
style=[
styles.halfCircle,
width: radius,
height: radius * 2,
borderRadius: radius,
backgroundColor,
transform: [
translateX: radius / 2 ,
rotate ,
translateX: -radius / 2
]
]
/>
</View>
);
renderInnerCircle()
const radiusMinusBorder = this.props.radius - this.props.borderWidth;
return (
<View
style=[
styles.innerCircle,
width: radiusMinusBorder * 2,
height: radiusMinusBorder * 2,
borderRadius: radiusMinusBorder,
backgroundColor: this.props.bgColor,
...this.props.containerStyle
]
>
<Text style=this.props.textStyle>this.state.text</Text>
</View>
);
render()
const
interpolationValuesHalfCircle1,
interpolationValuesHalfCircle2
= this.state;
return (
<View
style=[
styles.outerCircle,
width: this.props.radius * 2,
height: this.props.radius * 2,
borderRadius: this.props.radius,
backgroundColor: this.props.color
]
>
this.renderHalfCircle(interpolationValuesHalfCircle1)
this.renderHalfCircle(interpolationValuesHalfCircle2)
this.renderInnerCircle()
</View>
);
以上是关于如何实现React原生倒计时圈的主要内容,如果未能解决你的问题,请参考以下文章