Open thurt opened 7 years ago
Tried it also same issue...
Here is the code I used based of the example:
/**
* Basic [Android] Example for react-native-blur
* https://github.com/react-native-community/react-native-blur
*/
'use strict';
import React, { Component } from 'react';
import {
AppRegistry,
Image,
findNodeHandle,
StyleSheet,
Text,
View,
ScrollView,
Dimensions,
Switch,
InteractionManager,
} from 'react-native';
import AndroidSegmented from 'react-native-segmented-android';
import { BlurView } from 'react-native-blur';
const BLUR_TYPES = ['xlight', 'light', 'dark'];
class Basic extends Component {
constructor() {
super();
this.state = {
showBlur: true,
viewRef: null,
activeSegment: 2,
blurType: 'dark',
};
}
componentDidMount() {
this.imageLoaded();
}
imageLoaded() {
// Workaround for a tricky race condition on initial load.
InteractionManager.runAfterInteractions(() => {
setTimeout(() => {
this.setState({ viewRef: findNodeHandle(this.refs.backgroundImage) });
}, 500);
});
}
_onChange(selected) {
this.setState({
activeSegment: selected,
blurType: BLUR_TYPES[selected],
});
}
renderBlurView() {
const tintColor = ['#ffffff', '#000000'];
if (this.state.blurType === 'xlight') tintColor.reverse();
return (
<View
// style={[styles.container, {
style={[{
position: 'absolute',
top: 0,
left: 100,
right: 0,
height: 400,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'transparent',
}]}
>
{this.state.viewRef && <BlurView
viewRef={this.state.viewRef}
style={styles.blurView}
blurRadius={9}
blurType={this.state.blurType}
// The following props are also available on Android:
// blurRadius={20}
// downsampleFactor={10}
// overlayColor={'rgba(0, 0, 255, .6)'} // set a blue overlay
/>}
<Text style={[styles.text, { color: tintColor[0] }]}>
Blur component (Android)
</Text>
<AndroidSegmented
tintColor={tintColor}
style={{
width: Dimensions.get('window').width,
height: 28,
justifyContent: 'center',
alignItems: 'center',
}}
childText={BLUR_TYPES}
orientation='horizontal'
selectedPosition={this.state.activeSegment}
onChange={this._onChange.bind(this)} />
</View>
)
}
render() {
return (
<View
style={styles.container}
>
<ScrollView
style={{
flex: 1,
backgroundColor: 'red',
}}
ref={'backgroundImage'}
// onScroll={this.imageLoaded.bind(this)}
onScroll={() => console.log("scrolling")}
>
<Image
source={require('./bgimage.jpeg')}
style={styles.image}
/>
<Image
source={require('./bgimage.jpeg')}
style={styles.image}
// ref={'backgroundImage'}
// onLoadEnd={this.imageLoaded.bind(this)}
/>
</ScrollView>
{ this.state.showBlur ? this.renderBlurView() : null }
<View
style={styles.blurToggle}>
<Switch
onValueChange={(value) => this.setState({showBlur: value})}
value={this.state.showBlur} />
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: 'transparent',
},
image: {
// position: 'absolute',
// left: 0,
// top: 0,
// bottom: 0,
// right: 0,
resizeMode: 'cover',
width: 200,
height: 400,
},
blurView: {
position: 'absolute',
left: 0,
top: 0,
bottom: 0,
right: 0,
},
text: {
fontSize: 22,
fontWeight: 'bold',
textAlign: 'center',
margin: 10,
color: '#FFFFFF',
},
blurToggle: {
position: 'absolute',
top: 30,
right: 10,
alignItems: 'flex-end',
},
});
AppRegistry.registerComponent('Basic', () => Basic);
It seems as though Blur View takes a snapshot of the view you want to blur and uses that as the background.
So any offsets will not work on Android.
So 2 things:
Is there a way to adjust the representation of the Blur View by the ability to crop the BlurView's reference?
And is there a way to refreshing the BlurView onScroll.
Ow and one thing I noticed, the BlurView stops working when Debug JS Remotely is on.
@Kureev - any advice?
@julesmoretti unfortunately, nothing specific. Blur takes a snapshot of underlying view and blurs it. If you refresh onScroll, it will literally kill your performance 😞
@Kureev - thank you very much :(
to refresh I would have to call the imageLoaded() again right?
And last question for you is there any limitations, for example would it still work on Animated.View's?
Depends what you want to do. One important thing you need to keep in mind is that once the screen is drawn, it'll remain "unchanged" till the next re-draw. Simply put, it isn't aware of any changes in the child / underlying components.
I know that it isn't quite useful, but that's a known issue. Taking snapshot of underlying views and calculating blur every frame may significantly drop performance of the app :(
Someone opened an PR some time ago, but you would still need to invalidate the view on scroll events. Something, that is not supported yet, but could be implemented in react-native-blur. https://github.com/500px/500px-android-blur/pull/10/files
for whoever gets here looking for solutions, I fixed this by changing the order elements in the hierarchy tree.
<BlurView
blurType="dark"
blurAmount={12}
blurRadius={24}
style={{
position: 'absolute',
zIndex: 999,
left: 0,
right: 0,
top: 0,
height: 500,
}}
>
{children}
</BlurView>
<ScrollView>
{children}
</ScrollView>
<ScrollView>
{children}
</ScrollView>
<BlurView
blurType="dark"
blurAmount={12}
blurRadius={24}
style={{
position: 'absolute',
zIndex: 999,
left: 0,
right: 0,
top: 0,
height: 500,
}}
>
{children}
</BlurView>
Above fixed it for me. Thanks @f-ricci!
Hi,
I have only tried setting this up on android for starters and I have hit a road block. The initial blurring works fine so I'm confident I have setup the viewRef correctly.
This shows the issue I am experiencing: http://recordit.co/9k6dztRzBo
The BlurView does not update as I scroll the underlying ScrollView. The component order looks something like:
My best guess is that the BlurView is not updating b/c the positioning of the overall ScrollView box doesn't change (just the contents inside are scrolling). Any other ideas?
Thanks!