I created a "circle bar" (group of views) that switch from grey to yellow as the images move. The circles start to transform correctly but then go back to the first spot instead of going to the next circle spot to indict that you are on the next image. The yellow circle just always goes back to the first spot no matter what. Does anyone know why this might be happening?? How do I get it to stay in the next spot?
PLEASE see this video that I made of it: https://youtu.be/BCaSgNexPAs
Here is how I create and handle the circle view transformations:
let circleArray = [];
if (this.state.imgArray) {
this.state.imgArray.forEach((val, i) => {
const scrollCircleVal = this.imgXPos.interpolate({
inputRange: [deviceWidth * (i - 1), deviceWidth * (i + 1)],
outputRange: [-8, 8],
extrapolate: 'clamp',
});
const thisCircle = (
<View
key={'circle' + i}
style={[
styles.track,
{
width: 8,
height: 8,
marginLeft: i === 0 ? 0 : CIRCLE_SPACE,
borderRadius: 75
},
]}
>
<Animated.View
style={[
styles.circle,
{
width: 8,
height: 8,
borderRadius: 75,
transform: [
{translateX: scrollCircleVal},
],
backgroundColor: '#FFD200'
},
]}
/>
</View>
);
circleArray.push(thisCircle)
});
}
And here's my code for how I handle the image swiping:
handleSwipe = (indexDirection) => {
if (!this.state.imgArray[this.state.imgIndex + indexDirection]) {
Animated.spring(this.imgXPos, {
toValue: 0
}).start();
return;
}
this.setState((prevState) => ({
imgIndex: prevState.imgIndex + indexDirection
}), () => {
this.imgXPos.setValue(indexDirection * this.width);
Animated.spring(this.imgXPos, {
toValue: 0
}).start();
});
}
imgPanResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (e, gs) => {
this.imgXPos.setValue(gs.dx);
},
onPanResponderRelease: (e, gs) => {
this.width = Dimensions.get('window').width;
const direction = Math.sign(gs.dx);
if (Math.abs(gs.dx) > this.width * 0.4) {
Animated.timing(this.imgXPos, {
toValue: direction * this.width,
duration: 250
}).start(() => this.handleSwipe(-1 * direction));
} else {
Animated.spring(this.imgXPos, {
toValue: 0
}).start();
}
}
});
Html:
<Animated.Image
{...this.imgPanResponder.panHandlers}
key={'image' + this.state.imgIndex}
style={{left: this.imgXPos, height: '100%', width: '100%', borderRadius: 7}}
resizeMethod={'scale'}
resizeMode={'cover'}
source={{uri: this.state.imgArray[this.state.imgIndex]}}
/>
<View style={styles.circleContainer}>
{circleArray}
</View>
You can use this. spinValue. setValue(0) to reset it.
React Native provides two complementary animation systems: Animated for granular and interactive control of specific values, and LayoutAnimation for animated global layout transactions.
React Native comes with three primitive components: View , Text , Image and ScrollView . To use the animated versions of these, all you have to do is prefix them with Animated , so View becomes Animated.
Animations are started by calling start() on your animation. start() takes a completion callback that will be called when the animation is done. If the animation finished running normally, the completion callback will be invoked with {finished: true} .
It's hard to get your code at first as it's all in the same spot.
I would first suggest breaking your code into smaller parts: ImageView, CirclesView
Now after we got that done, I would want to try to make the CirclesView a bit simpler (unless you really want this animation view inside the circle).
But from your code, I didn't see the difference for the "selectedImage" (imgIndex)
As it has calculations for each index, but with no reference to the selected image.
Rough ballpark code I would think to do with the current code:
let circleArray = [];
if (this.state.imgArray) {
this.state.imgArray.forEach((val, i) => {
const scrollCircleVal = this.imgXPos.interpolate({
inputRange: [deviceWidth * (i - 1), deviceWidth * (i + 1)],
outputRange: [-8, 8],
extrapolate: 'clamp',
});
const thisCircle = (
<View
key={'circle' + i}
style={[
styles.track,
{
width: 8,
height: 8,
marginLeft: i === 0 ? 0 : CIRCLE_SPACE,
borderRadius: 75
},
]}
>
// LOOK AT THIS LINE BELOW
{this.state.imgIndex == i &&
<Animated.View
style={[
styles.circle,
{
width: 8,
height: 8,
borderRadius: 75,
transform: [
{translateX: scrollCircleVal},
],
backgroundColor: '#FFD200'
},
]}
/>}
</View>
);
circleArray.push(thisCircle)
});
}
checkout the line I added above the "animated" circle for the "selected" circle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With