When I use useNativeDriver in React Native Animated
state = {
chevronUp: new Animated.Value(-50),
};
Animated.spring(this.state.chevronUp, {
toValue: 50,
friction: 5,
useNativeDriver: true, // <----- this line
}).start();
and render
<Animated.View style={{bottom: this.state.chevronUp,position: "absolute", right: 20, width: 50, height: 50}}>
<Icon name="chevron-up" size={28} color="#666"/>
</Animated.View>
these errors give me
Style property 'bottom' is not supported by native animated module
and
Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
you need to use "translateY" property instead of "bottom" which is supported by the native driver, so your initial value will look like this:
state = {
chevronUp: new Animated.Value(50),
}
Animated.spring(this.state.chevronUp, {
toValue: -50,
friction: 5,
useNativeDriver: true, // <----- this line
}).start();
and in the render method:
<Animated.View style={{translateY: this.state.chevronUp,position: "absolute", right: 20, width: 50, height: 50}}>
<Icon name="chevron-up" size={28} color="#666"/>
</Animated.View>
This error comes from validateTransform function inside React Native lib.You can check the TRANSFORM_WHITELIST in NativeAnimatedHelper for the property supported by animated module.
Currently, there are these props supported
const TRANSFORM_WHITELIST = {
translateX: true,
translateY: true,
scale: true,
scaleX: true,
scaleY: true,
rotate: true,
rotateX: true,
rotateY: true,
rotateZ: true,
perspective: true,
};
You'd better use translateY instead of bottom here.
<Animated.View style={{translateY: this.state.chevronUp,position: "absolute", right: 20, width: 50, height: 50}}>
<Icon name="chevron-up" size={28} color="#666"/>
</Animated.View>
Related
I'm trying to fit my background image to cover the whole app but its not, even though i've tested most of similar threads here so any help is appreciated.
I've made some changes to the original source and added an arrow towards the left edge of the image that i was hoping to have at the edge when i open up the EXPO app on my phone, but i only see a few pixels of the arrow at the left edge.
**app.js**
function HomeScreen() {
return (
<ImageBackground source={require('./assets/bgImage.jpg')} style={styles.bgImage}>
<View>
<Text>Home Screen</Text>
</View>
</ImageBackground>
);
}
bgImage: {
flex: 1,
width: null,
height: null,
resizeMode: 'cover',
justifyContent: 'center',
alignItems: "center"
}
try this :-
import React from 'react';
import { ImageBackground, View, Text } from 'react-native';
const HomeScreen = () => {
return (
<ImageBackground source={require('../assets/apple.jpg')}
style={{
position: "absolute",
top: 0,
left: 0,
bottom: 0,
right: 0,
flex: 1,
alignItems: "center"
}}>
<View style={{
width: '90%',
height: 200,
backgroundColor: "red",
justifyContent: "center",
alignItems: "center",
}}>
<Text>Home Screen</Text>
</View>
</ImageBackground>
);
}
export default HomeScreen;
It is working fine.
I've been trying to cut a picture into several parts for hours now.
I thought it would work with ImageEditor.cropImage. Apparently I'm using the function wrong, or it doesn't do what I expect it to do.
Can someone please tell me what I'm doing wrong, or recommend a package I can use. Thank you.
My attempt:
const cropData = {
offset: {x: 25, y: 25},
size: {width: 250, height: 250},
displaySize: {width: 250, height: 250},
resizeMode: 'contain',
};
later..
ImageEditor.cropImage(require('../resources/images/pictures/categoryOne/c1b1.jpg'),
cropData);
I solved my issue not with ImageEditor.cropImage but with CSS
<View style={styles.topLeftView}>
<Image
style={styles.topLeftImage}
source={require('../resources/images/pictures/categoryOne/c1b1.jpg')}
resizeMode="contain"
/>
</View>
Style
topLeftView: {
width: 100,
height: 100,
overflow: 'hidden',
},
topLeftImage: {
right: 0,
bottom: 0,
},
React Native Animation does not scale. Animation is bigger. My code:
import { DangerZone } from 'expo';
const { Lottie } = DangerZone;
Styles:
animationContainer: {
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',z
},
View:
<Lottie
ref={(animation) => {
this.animation = animation;
}}
resizeMode="contain"
loop={Boolean(true)}
style={{
width: 300,
height: 30,
backgroundColor: '#ccc',
}}
source={this.state.animation}
/>
App screenshot
I don`t know why this does not work. Please help me
I have a simple progress bar that turns from green to red. The animate method is really very handy there. But is there a way to add actions while the animation is running (e.g. show a label after 1 second)?
views.js:
<View id="progressBar" height="40%" width="100%" left="0%" backgroundColor="green" onClick="checkAnimation"/>
controller.js:
$.progressBar.animate({
left: 0,
width: "1%",
backgroundColor: "red",
duration: 2000
});
You can simply use setTimeout method irrespective of whatever animation is running, like this:
$.progressBar.animate({
left: 0,
width: "1%",
backgroundColor: "red",
duration: 2000
});
setTimeout(function(){
$.someLabel.visible = true;
// or
$.someOtherLabel.text = "Label changed while animation is running...";
}, 1000);
I'm trying to make a slider animation, like the one you get when you power off iOS on iPhones. This is what I have so far and it is self-contained.
import {PanResponder, View, Text, Dimension} from 'react-native';
const {width} = Dimension.get('window');
const TOTAL_WIDTH = width - 50;
class slider extends React.Component {
t = <Text>Slide to Export & Delete</Text>;
state = {
button_translate_x: 0
};
move_right(event, dx) {
if (dx > 0 && event.nativeEvent.pageX <= TOTAL_WIDTH) {
if (dx === width - 50) {
this.setState({button_translate_x: 0});
} else {
this.setState({button_translate_x: dx});
}
}
}
release_handler(e, gs) {
const diff = Math.abs(e.nativeEvent.pageX - TOTAL_WIDTH);
if (diff <= 5) {
this.setState({button_translate_x: gs.dx});
} else {
this.setState({button_translate_x: 0});
}
}
pan_responder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onPanResponderMove: (evt, gestureState) => {
this.move_right(evt, gestureState.dx);
},
onPanResponderRelease: (evt, gestureState) => {
this.release_handler(evt, gestureState);
}
});
smoothing_margin() {
if (this.state.button_translate_x <= 25)
return Math.abs(this.state.button_translate_x - 20);
else return 0;
}
render() {
return (
<View style={{alignItems: 'center'}}>
<View
style={{
alignItems: 'center',
borderRadius: 25,
width: TOTAL_WIDTH,
backgroundColor: 'orange'
}}>
<View
style={{
width: this.state.button_translate_x,
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
backgroundColor: 'blue',
borderRadius: 25,
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: -1,
marginVertical: this.smoothing_margin()
}}
/>
<View
style={{
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: -2
}}>
{this.t}
</View>
<View
style={{
alignSelf: 'flex-start',
width: 50,
transform: [{translateX: this.state.button_translate_x}],
height: 50,
borderRadius: 25,
backgroundColor: 'red'
}}
{...this.pan_responder.panHandlers}
/>
</View>
</View>
);
}
}
But this is wrong though because the initial slide has the blue coming out of the rounded bounds of the orange view. I have tried to be clever with this with marginVertical but not sure if that is the correct way to go about it.
Sliding all the way to the right is incorrect because the blue should be covering at least to the middle of the circle but as currently written only goes up to the left side.
Help appreciated.
Figured it out!
import {PanResponder} from 'react-native';
const TOTAL_WIDTH = width - 50;
class slider extends React.Component {
t = <Text>Slide to Export & Delete</Text>;
state = {button_translate_x: 0};
pan_responder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onPanResponderMove: (evt, {dx}) => {
if (dx > 0 && TOTAL_WIDTH - 50 >= dx) {
this.setState({button_translate_x: dx});
}
},
onPanResponderRelease: ({nativeEvent: {pageX}}, {dx}) => {
if (TOTAL_WIDTH - 50 - dx <= 5) {
console.log('Success zone');
} else {
this.setState({button_translate_x: 0});
}
}
});
render() {
return (
<View style={{alignItems: 'center'}}>
<View
style={{
alignItems: 'center',
borderRadius: 25,
width: TOTAL_WIDTH,
backgroundColor: 'orange'
}}>
<View
style={{
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
top: 0,
left: 0,
right: 0,
bottom: 0,
zIndex: -2
}}>
{this.t}
</View>
<View
style={{
alignSelf: 'flex-start',
width: 50,
transform: [{translateX: this.state.button_translate_x}],
height: 50,
borderRadius: 25,
backgroundColor: 'red'
}}
{...this.pan_responder.panHandlers}
/>
<View
style={{
borderRadius: 25,
position: 'absolute',
top: 0,
bottom: 0,
right: 0,
left: 0,
backgroundColor: 'blue',
height: 50,
width: this.state.button_translate_x + 50,
zIndex: -1
}}
/>
</View>
</View>
);
}
}