react-native-text-ticker
Advanced tools
Comparing version 1.1.0 to 1.2.0
141
index.js
@@ -46,3 +46,4 @@ import React, { PureComponent } from 'react' | ||
scrollSpeed: PropTypes.number, // Will be ignored if you set duration directly. | ||
shouldAnimateTreshold: PropTypes.number | ||
shouldAnimateTreshold: PropTypes.number, | ||
disabled: PropTypes.bool | ||
} | ||
@@ -64,3 +65,4 @@ | ||
scrollSpeed: 150, | ||
shouldAnimateTreshold: 0 | ||
shouldAnimateTreshold: 0, | ||
disabled: false | ||
} | ||
@@ -80,6 +82,10 @@ | ||
componentWillMount() { | ||
this.calculateMetricsPromise = null | ||
} | ||
componentDidMount() { | ||
this.invalidateMetrics() | ||
const { marqueeDelay, marqueeOnMount } = this.props | ||
if (marqueeOnMount) { | ||
const { disabled, marqueeDelay, marqueeOnMount } = this.props | ||
if (!disabled && marqueeOnMount) { | ||
this.startAnimation(marqueeDelay) | ||
@@ -92,2 +98,14 @@ } | ||
this.resetScroll() | ||
} else if (this.props.disabled !== prevProps.disabled) { | ||
if (!this.props.disabled && this.props.marqueeOnMount) { | ||
this.startAnimation(this.props.marqueeDelay) | ||
} else if (this.props.disabled) { | ||
// Cancel any promises | ||
if (this.calculateMetricsPromise !== null) { | ||
this.calculateMetricsPromise.cancel() | ||
this.calculateMetricsPromise = null | ||
} | ||
this.stopAnimation() | ||
this.clearTimeout() | ||
} | ||
} | ||
@@ -97,7 +115,36 @@ } | ||
componentWillUnmount() { | ||
this.stopAnimation(); | ||
// Cancel promise to stop setState after unmount | ||
if (this.calculateMetricsPromise !== null) { | ||
this.calculateMetricsPromise.cancel() | ||
this.calculateMetricsPromise = null | ||
} | ||
this.stopAnimation() | ||
// always stop timers when unmounting, common source of crash | ||
this.clearTimeout(); | ||
this.clearTimeout() | ||
} | ||
makeCancelable = (promise) => { | ||
let cancel = () => {} | ||
const wrappedPromise = new Promise((resolve, reject) => { | ||
cancel = () => { | ||
resolve = null | ||
reject = null | ||
}; | ||
promise.then( | ||
value => { | ||
if (resolve) { | ||
resolve(value) | ||
} | ||
}, | ||
error => { | ||
if (reject) { | ||
reject(error) | ||
} | ||
} | ||
); | ||
}); | ||
wrappedPromise.cancel = cancel | ||
return wrappedPromise | ||
}; | ||
startAnimation = (timeDelay) => { | ||
@@ -208,3 +255,3 @@ if (this.state.animating) { | ||
const {shouldAnimateTreshold} = this.props | ||
return new Promise(async (resolve, reject) => { | ||
this.calculateMetricsPromise = this.makeCancelable(new Promise(async (resolve, reject) => { | ||
try { | ||
@@ -224,3 +271,2 @@ const measureWidth = node => | ||
}); | ||
const [containerWidth, textWidth] = await Promise.all([ | ||
@@ -235,3 +281,4 @@ measureWidth(this.containerRef), | ||
this.setState({ | ||
// console.log(`distance: ${this.distance}, contentFits: ${this.state.contentFits}`) | ||
resolve({ | ||
// Is 1 instead of 0 to get round rounding errors from: | ||
@@ -242,7 +289,12 @@ // https://github.com/facebook/react-native/commit/a534672 | ||
}) | ||
// console.log(`distance: ${this.distance}, contentFits: ${this.state.contentFits}`) | ||
resolve([]) | ||
} catch (error) { | ||
console.warn('react-native-text-ticker: could not calculate metrics', error); | ||
} | ||
})) | ||
await this.calculateMetricsPromise.then((result) => { | ||
this.setState({ | ||
contentFits: result.contentFits, | ||
shouldBounce: result.shouldBounce, | ||
}) | ||
return [] | ||
}) | ||
@@ -286,3 +338,3 @@ } | ||
render() { | ||
const { style, children, repeatSpacer, scroll, shouldAnimateTreshold, ... props } = this.props | ||
const { style, children, repeatSpacer, scroll, shouldAnimateTreshold, disabled, ... props } = this.props | ||
const { animating, contentFits, isScrolling } = this.state | ||
@@ -298,2 +350,35 @@ const additionalContainerStyle = { | ||
} | ||
const animatedText = disabled ? null : ( | ||
<ScrollView | ||
ref={c => (this.containerRef = c)} | ||
horizontal | ||
scrollEnabled={scroll ? !this.state.contentFits : false} | ||
scrollEventThrottle={16} | ||
onScrollBeginDrag={this.scrollBegin} | ||
onScrollEndDrag={this.scrollEnd} | ||
showsHorizontalScrollIndicator={false} | ||
style={[StyleSheet.absoluteFillObject, I18nManager.isRTL ? { flexDirection: 'row-reverse' } : null ]} | ||
display={animating ? 'flex' : 'none'} | ||
onContentSizeChange={() => this.calculateMetrics()} | ||
> | ||
<Animated.Text | ||
ref={c => (this.textRef = c)} | ||
numberOfLines={1} | ||
{... props} | ||
style={[style, { transform: [{ translateX: this.animatedValue }], width: null }]} | ||
> | ||
{this.props.children} | ||
</Animated.Text> | ||
{!contentFits && !isScrolling | ||
? <View style={{ paddingLeft: repeatSpacer }}> | ||
<Animated.Text | ||
numberOfLines={1} | ||
{... props} | ||
style={[style, { transform: [{ translateX: this.animatedValue }], width: null }]} | ||
> | ||
{this.props.children} | ||
</Animated.Text> | ||
</View> : null } | ||
</ScrollView> | ||
); | ||
return ( | ||
@@ -308,33 +393,3 @@ <View style={[styles.container, additionalContainerStyle]}> | ||
</Text> | ||
<ScrollView | ||
ref={c => (this.containerRef = c)} | ||
horizontal | ||
scrollEnabled={scroll ? !this.state.contentFits : false} | ||
scrollEventThrottle={16} | ||
onScrollBeginDrag={this.scrollBegin} | ||
onScrollEndDrag={this.scrollEnd} | ||
showsHorizontalScrollIndicator={false} | ||
style={[StyleSheet.absoluteFillObject, I18nManager.isRTL ? { flexDirection: 'row-reverse' } : null ]} | ||
display={animating ? 'flex' : 'none'} | ||
onContentSizeChange={() => this.calculateMetrics()} | ||
> | ||
<Animated.Text | ||
ref={c => (this.textRef = c)} | ||
numberOfLines={1} | ||
{... props} | ||
style={[style, { transform: [{ translateX: this.animatedValue }], width: null }]} | ||
> | ||
{this.props.children} | ||
</Animated.Text> | ||
{!contentFits && !isScrolling | ||
? <View style={{ paddingLeft: repeatSpacer }}> | ||
<Animated.Text | ||
numberOfLines={1} | ||
{... props} | ||
style={[style, { transform: [{ translateX: this.animatedValue }], width: null }]} | ||
> | ||
{this.props.children} | ||
</Animated.Text> | ||
</View> : null } | ||
</ScrollView> | ||
{animatedText} | ||
</View> | ||
@@ -341,0 +396,0 @@ ) |
{ | ||
"name": "react-native-text-ticker", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "React Native Text Ticker/Marquee Component", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -88,4 +88,4 @@ # react-native-text-ticker | ||
| shouldAnimateTreshold | number | true | 0 | If you have a view drawn over the text at the right (a fade-out gradient for instance) this should be set to the width of the overlaying view: ![examples](./example/media/example2.gif) | ||
| disabled | boolean | true | false | Disables text animation | ||
## Methods | ||
@@ -92,0 +92,0 @@ These methods are optional and can be accessed by accessing the ref: |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19321
398