react-native-blur
react-native-blur copied to clipboard
Animate blurAmount
I'd like to be able to animate the blur amount. RIght now, it looks like this is not supported...
<Animated.BlurView blurAmount={this.state.blurAmount} />
Animated.timing(
this.state.blurAmount,
{
toValue: 20,
easing: Easing.inOut(Easing.ease),
duration: 300
}
).start();
I've got this kind of working in a branch: https://github.com/eliperkins/react-native-blur/tree/rewrite
By using UIViewPropertyAnimator
, we can create an animation from a fully blurred state, to a non-blurred state.
Unfortunately, UIViewPropertyAnimator
is only available on iOS 10+, so it won't fly for those people targeting iOS 9. It'd be nice to find a way to support this for iOS 10, and fall back to something else gracefully on iOS 9.
I'll see if I can polish things up and get a pull request up.
Not sure about performance, but I was able get it working and it looks pretty smooth. What I ended up doing was adding a listener to the Animated instance and then setting the blurAmount through state changes:
// Initialize animation and set the listener
this.animation = new Animated.Value(0);
this.animation.addListener((value) => {
this.setState({modalBlur: value.value});
});
// Start the animation as usual
this.animation.setValue(5);
Animated.timing(
this.animation,
{
duration: 100,
toValue: 15
}
).start()
// Render...
<BlurView blurType="light" style={{flex: 1}} blurAmount={this.state.modalBlur}>
<Button title="close" onPress={this.onCloseModal}/>
</BlurView>
@richardchim I've tried your solution, seams not to work. Does it work for u?
@gran33, I apologize, I should have tested my original post. Apparently, I discovered how to do it by accident. In my case, I was actually using a Modal. The Modal wraps the BlurView and has a transparent background. Here's a working example this time:
import React, {
Component
} from 'react';
import {
Animated,
Modal,
Text,
TouchableOpacity,
View,
} from 'react-native';
import {
BlurView,
} from 'react-native-blur';
class BlurExample extends Component {
componentWillMount() {
this.animation.setValue(0);
Animated.timing(
this.animation,
{
duration: 1000,
toValue: 20
}
).start();
}
constructor(props) {
super(props);
this.animation = new Animated.Value(0);
this.animation.addListener((value) => {
this.setState({modalBlur: value.value});
});
}
render() {
return (
<View>
<Modal
transparent={true}
>
<BlurView blurType="light" style={{flex: 1}} blurAmount={this.state.modalBlur}>
<View style={{flex: 1}}>
<Text style={{textAlign: 'center', padding: 22}}>This text is clear</Text>
</View>
</BlurView>
</Modal>
<View style={{flexDirection: 'column', alignItems: 'center'}}>
<Text>This gets blurred</Text>
<TouchableOpacity style={{backgroundColor: 'red', height: 80, width: 80}}/>
<TouchableOpacity style={{backgroundColor: 'green', height: 80, width: 80}}/>
<TouchableOpacity style={{backgroundColor: 'blue', height: 80, width: 80}}/>
</View>
</View>
)
}
}
export default BlurExample;
It would be awesome to have some support for real Animated animation => nativeDriver <3
@ahanriat It'll be great if you can contribute!
Did animating blurAmount
make it into 3.0.0? If not, is there any recommended workarounds to get similar functionality until it drops?
Absolutely position BlurView
and place it on top of your UI you want to blur. Then wrap that BlurView
in an Animated.View
and you can animate opacity to increase/decrease bluriness.
@zachgibson that's a really cool idea, that will work on iOS and Android, will give that a shot thanks for sharing!
Glad to help @Noitidart!
@zachgibson thanks for sharing, but this is not the same as animating blurAmount
. iOS 11 does gesture-controlled transitions everywhere that increase the blur radius, and the effect is much more rich than manipulating opacity.
@sjmueller Yeah you’re totally right. You lose movement on your blurring shapes.
The issue was really painful for me but thanks to the insights on this thread I finally implemented blur animation using UIViewPropertyAnimator. You can take a look at it here: https://github.com/AlpacaDB/react-native-blur/tree/animate
One PR I've sent earlier prevented setNativeProps from working correctly, so createAnimatedComponent() didn't work properly. This was an easy fix. The second issue I had based on @eliperkins repo was that it was not dynamically setting property and also the timing of configuring animation was a bit too early. I deferred it to after the view tree is complete. I'm not sending a PR for this since I completely rewrite BlurView using UIViewPropertyAnimator so it supports iOS 10+ only. Someone can try merge with old code, but basically I didn't want to include the use of private API, so I removed the old hack of setting blurAmount using the subclass approach.
For those who read this and wonder, yes setting opacity is an easy solution but the blur effect is pretty different. Even the subclass approach I noticed the text gets jaggy at lower blurAmount (like 1 or 2). With UIViewPropertyAnimator, it is the same or nearly the same as iOS behavior.
@umitanuki wow way cool start! Not submitting a PR yet makes sense. It would need < iOS10 and Android support I think.
By the way, how does the expo animated BlurView work? https://docs.expo.io/versions/latest/sdk/blur-view.html I thought expo just used this module from this repo?
Hi @Kureev ! I was investigation about why it isn't possible to animate BlurView, and I found that when Animated.interpolate is used, then suddenly the app. I happens that interpolate may generate float numbers, in order to properly interpolate values. But when I saw BlurViewManager.java file, it seems that defaultRadius and radius from setRadius are both int variables. Then When interpolating float numbers and using into int values crashes the app.
Could you transform those java variables properly to float? I could contribute to it, but I'm not an expert on pure Android development.
Thanks!