I am trying to make use of react-native-animatable to make a sequence of images animated. Here's my code:
import * as Animatable from 'react-native-animatable';
constructor(props) {
super(props);
this.images = [
require('../../assets/img/04_rec_img/b1.png'),
require('../../assets/img/04_rec_img/b2.png'),
require('../../assets/img/04_rec_img/b3.png'),
];
this.next = this.next.bind(this);
this.state = {index: 0};
}
componentDidMount() {
this.next();
}
next() {
setTimeout(() => {
this.setState({index: (this.state.index+1)%3});
this.next();
}, 1000);
}
render(){
<View style={{backgroundColor:'rgba(142, 142, 147, 0.24)',
width:67,height: 67, borderRadius: 67/2, justifyContent:'center', alignItems:'center',
}}>
<Animatable.Image duration={500} ease="ease-out" animation="slideInRight" source={this.images[this.state.index]}
style={{width:36, height:36}} />
</View>
}
The first image slides but the rest two doesn't slides in instead they just appear.
I would like to achieve like this:
Please help!! If you have any other approach, also please share. Thanks in advance
Related
I'm new to react native and in my sample app I can't handle properly results returned from ImagePicker of this component https://github.com/react-native-image-picker/react-native-image-picker
I'm running react 0.65 and below is my code:
import * as ImagePicker from 'react-native-image-picker';
export class App extends Component {
constructor() {
super();
this.state = { imageSource: null };
}
selectImage = () => {
const selectImageFromGallery = async () => {
const response = await ImagePicker.launchImageLibrary('library', {
selectionLimit: 1,
mediaType: 'photo',
includeBase64: true,
});
const {img64base} = response.assets[0];
this.setState({img64base});
};
selectImageFromGallery();
// console.log(resp);
}
render() {
return (
<SafeAreaView style={{justifyContent: 'center', alignItems: 'center'}}>
<Button title='Select from gallery' onPress={() => this.selectImage()} />
<Image source={this.state.imageSource} />
</SafeAreaView>
);
};
}
Upon run of application I can press button and select image, but whenever I confirm my selection it is throwing error in console and on the screen of Android device:
Uncaught Error:
'Type Error: callback is not a function'
This call stack is not sybmolicated.
I do understand that I miss to handle correctly promise or callback but I cant figure out correct syntax. Could you please help? Tried zillion of times with 'await', without await, etc. The only thing I need to stay with component class and I won't change to function class - have single calls in componentDidMount functions to make sure some specific hardware is called only once. Pease help
selectImage = async () {
const response = await ImagePicker.launchImageLibrary('library', {
selectionLimit: 1,
mediaType: 'photo',
includeBase64: true,
});
const {img64base} = response.assets[0];
this.setState({img64base});
}
I built simple light box by Animated.View . on my light box I put Button to close light box .How can do that.I dont want to use package like react native router flux
class Baselightbox extends Component {
constructor(props) {
super(props);
this.state = {
opacity:new Animated.Value(0)
};
}
close(){ //here => how to close light box
Animated.timing(
this.state.opacity,{
duration:3000,
toValue:0
}).start()
}
renderlightbox(){
const {width=deviceWidth,height=deviceHeight/2,children,backgroundColor,Btitle}=this.props
return(<View style={{flex:1,justifyContent:'center'}}>
{children}
<Button title={Btitle} onPress={()=>{this.close()}} />
</View>)
}
componentWillMount(){
Animated.timing(
this.state.opacity,{
duration:3000,
toValue:1
}).start()
}
render() {
const { height : deviceHeight , width : deviceWidth} = Dimensions.get('window');
const {width=deviceWidth,height=deviceHeight/2,children,backgroundColor,Btitle}=this.props
return (
<Animated.View style={{opacity:this.state.opacity,borderRadius: 10,width,height,backgroundColor,padding:30}}>
{this.renderlightbox()}
</Animated.View>
);
}
}
My Code
Take a look at my codes :)
Am trying to animate an image to shrink when the onscreen keyboard is called (see code below). Got it working on IOS but not on Android :(
I have searched the web for solutions, but so far nothing works. Any suggestions?
Thanks in advance
constructor(props) {
super(props);
this.imageSize = new Animated.Value(imageSizeNormal);
}
componentWillMount() {
this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
}
componentWillUnmount() {
this.keyboardWillShowSub.remove();
this.keyboardWillHideSub.remove();
}
keyboardWillShow = (event) => {
Animated.timing(this.imageSize, {
toValue: imageSizeSmall
}).start();
};
keyboardWillHide = (event) => {
Animated.timing(this.imageSize, {
toValue: imageSize
}).start();
};
render() {
return (
<Animated.Image
source={require('../../assets/circle.png')}
resizeMode="contain"
style={[styles.logo, { height: this.imageSize, width: this.imageSize}]}
/>
)
}
const imageSizeNormal = Dimensions.get("window").width/2;
const imageSizeSmall = Dimensions.get("window").width/4;
Here's how I solved it.
First thing I did was change the keywords "keyboardWill..." to "keyboardDid...""
Second, I added the following to AndroidManifest.xml
android:fitsSystemWindows="true"
android:windowSoftInputMode="adjustResize"
Sources:
windowSoftInputMode="adjustResize" not working with translucent action/navbar
https://medium.freecodecamp.org/how-to-make-your-react-native-app-respond-gracefully-when-the-keyboard-pops-up-7442c1535580
I'm playing with react Native and I have a problem with the animation of transition.
Windows 10 - Hyper V, Visual Code Emulator Android - Ignite Boilerplate.
What I'm trying to do:
When I click, I want to show a circle with a scale animation from 0 to 2 on the click position.
What I have:
See the picture below (I have put a setTimout to see the first frame). On the first click, The component is displayed a first time very quickly with its natural width and height but the scale on 0,001 has no effect. After that, the animation begins from the scale 0,001 to 2.
With the other clicks, The circle start the first frames with the dimension of the previous circle. and then, the animation begins. But one more time, the scale : 0 has no effect at the first frame.
Here is the code of the Lunch screen:
export default class LaunchScreen extends Component {
state = {
clicks: []
};
handlePress(evt) {
console.log(evt.nativeEvent.locationX, evt.nativeEvent.locationY)
let xCoord = evt.nativeEvent.locationX;
let yCoord = evt.nativeEvent.locationY;
this
.state
.clicks
.push({x: xCoord, y: yCoord});
this.setState({clicks: this.state.clicks});
}
renderClick() {
if (this.state.clicks.length > 0) {
return this
.state
.clicks
.map((item, i) =>< ClickAnimation key = {
item.x
}
x = {
item.x
}
y = {
item.y
} />)
} else {
return <View/>
}
}
render() {
return (
<View style={styles.container}>
<ScrollView
style={styles.scrollView}
horizontal={true}
showsHorizontalScrollIndicator={true}
contentContainerStyle={styles.scrollView}>
<TouchableWithoutFeedback
style={styles.touchableWithoutFeedback}
onPress=
{evt => this.handlePress(evt)}>
<View style={styles.scrollView}>
{this.renderClick()}
</View>
</TouchableWithoutFeedback>
</ScrollView>
</View>
)
}
}
And here the component of the circle:
import React from 'react';
import PropTypes from 'prop-types';
import {Animated, View, Easing} from 'react-native';
export default class ClickAnimation extends React.Component {
constructor() {
super();
console.log(this.state)
this.state = {
scaleAnim: new Animated.Value(0.001);
};
}
componentDidMount() {
Animated
.timing(this.state.scaleAnim, {
toValue: 2,
duration: 2000
})
.start();
.scaleAnim
}
render() {
return (<Animated.View
style={{
zIndex: 10,
borderColor: "blue",
borderRadius: 400,
borderWidth: 1,
position: "absolute",
top: this.props.y,
left: this.props.x,
width: 60,
height: 60,
backgroundColor: "red",
transform: [
{
scaleY: this.state.scaleAnim
? this.state.scaleAnim
: 0
}, {
scaleX: this.state.scaleAnim
? this.state.scaleAnim
: 0
}
]
}}/>);
}
}
Do you have an Idea why this is so?
I have found the solution.
This come with this issue:
https://github.com/facebook/react-native/issues/6278
I had seen it and this is why I wrote 0,001. But 0,001 is still to little. With 0,01 it works great.
So the answer is:
Just replace 0.001 by 0.01 because it was too little.
Running RN v0.40.0 on a Physical device on Android 5.1. I'm trying to animate a text to appear with fade-in and slide up in the following way:
export default class Example extends PureComponent {
constructor(props) {
super(props);
this.translate = new Animated.Value(-15);
this.fade = new Animated.Value(0);
}
componentWillReceiveProps() {
setTimeout(() => {
Animated.timing(this.translate, {
toValue: 0,
duration: 800,
easing: Easing.inOut(Easing.ease),
}).start();
Animated.timing(this.fade, {
toValue: 1,
duration: 800,
easing: Easing.inOut(Easing.ease),
}
).start();
}, 150);
}
render() {
return (
<View>
<Animated.View
style={{
transform: [
{translateY: this.translate},
],
opacity: this.fade
}}
>
<Text>
{this.props.text}
</Text>
</Animated.View>
</View>
);
}
And after I reload JS bundle from the dev menu and go to that view app crashes with no error log, sometimes showing Application ... stopped working, sometimes not. If I start the app from the android menu again it loads ok, crashes only for the first time. It definitely has something to do with animations since before I introduced animations I had no crashes. There are no logs, no clues, please, give me some advice what could that be and what should I try and what should I check. Thanks.
Btw, on that view with animations I have a pretty heavy background image (~400k) could that be a problem?
UPD: I have narrowed it down to that it crashes when I'm trying to run animations in parallel, either with setTimeout or with Animation.parallel. What could be the problem?
Not sure what's causing the crash, but using Animated.parallel has worked for me:
Animated.parallel([
Animated.spring(
this.state.pan, {
...SPRING_CONFIG,
overshootClamping: true,
easing: Easing.linear,
toValue: {x: direction, y: -200}
}),
Animated.timing(
this.state.fadeAnim, {
toValue: 1,
easing: Easing.linear,
duration: 750,
}),
]).start();
where SPRING_CONFIG is something like
var SPRING_CONFIG = {bounciness: 0, speed: .5};//{tension: 2, friction: 3, velocity: 3};
and pan and fadeAnim values are set in the constructor this.state values as:
pan: new Animated.ValueXY(),
fadeAnim: new Animated.Value(0),
with the animated View as
<Animated.View style={this.getStyle()}>
<Text style={[styles.text, {color: this.state.textColor}]}>{this.state.theText}</Text>
</Animated.View>
and the getStyle function is
getStyle() {
return [
game_styles.word_container,
{opacity: this.state.fadeAnim},
{transform: this.state.pan.getTranslateTransform()}
];
}
This tutorial helped me set this up...good luck!