React-native-blur: blur tha half of screen

Created on 16 Feb 2019  ·  9Comments  ·  Source: Kureev/react-native-blur

hi
i emplement code to blur the half of screen and it work before, but for some reasons im delete my android folder and regenrate the android folder and now it blur the entire screen, this is my code.

    this.state = {
      viewRef: null,
         ...
    };


  imageLoaded() {
    setTimeout(() => {
      this.setState({ viewRef: findNodeHandle(this.backgroundImage) });
    }, 100);
  }

  render() {
    return (
     <View
        style={{
          flex: 1
        }}
      >
        <Image
          ref={img => {
            this.backgroundImage = img;
          }}
          source={require("../../res/Images/backSign.jpg")}
          style={{
            position: "absolute",
               top: 0,
            left: 0,
            bottom: 0,
            right: 0
          }}
          onLoadEnd={this.imageLoaded.bind(this)}
        />
        <BlurView
          style={{
            position: "absolute",
            top: Metrics.HEIGHT * 0.5,
            left: 0,
            bottom: 0,
            right: 0
          }}
          viewRef={this.state.viewRef}
          blurType="light"
        />
 <View
          style={{
            position: "absolute",
            top: Metrics.HEIGHT * 0.5
          }}
        >
      .....
 </View>
 </View>
)}

thanks in advance

Most helpful comment

Hi,

I was just struggling with the same issue of applying margin to BlurView and what worked for me was wrapping BlurView with another View, applying the viewStyle there with overflow: hidden added to it. For example:

        <Image
          ref={img => {
            this.backgroundImage = img;
          }}
          source={require("../../res/Images/backSign.jpg")}
          style={{
            position: "absolute",
            top: 0,
            left: 0,
            bottom: 0,
            right: 0
          }}
          onLoadEnd={this.imageLoaded.bind(this)}
        />
        <View
          style={{
            position: "absolute",
            top: Metrics.HEIGHT * 0.5,
            left: 0,
            bottom: 0,
            right: 0,
            overflow: "hidden"
          }}
          pointerEvents={"none"}
        >
          <BlurView style={StyleSheet.absoluteFillObject} viewRef={this.state.viewRef} blurType="light" />
        </View>

All 9 comments

Hi,

I was just struggling with the same issue of applying margin to BlurView and what worked for me was wrapping BlurView with another View, applying the viewStyle there with overflow: hidden added to it. For example:

        <Image
          ref={img => {
            this.backgroundImage = img;
          }}
          source={require("../../res/Images/backSign.jpg")}
          style={{
            position: "absolute",
            top: 0,
            left: 0,
            bottom: 0,
            right: 0
          }}
          onLoadEnd={this.imageLoaded.bind(this)}
        />
        <View
          style={{
            position: "absolute",
            top: Metrics.HEIGHT * 0.5,
            left: 0,
            bottom: 0,
            right: 0,
            overflow: "hidden"
          }}
          pointerEvents={"none"}
        >
          <BlurView style={StyleSheet.absoluteFillObject} viewRef={this.state.viewRef} blurType="light" />
        </View>

hi @abendi, In iOS BlurView is working fine but in Android it is not working properly. How to display half part of image should be blurred. Give me any suggestion for this.
code:-

componentDidMount() {
    InteractionManager.runAfterInteractions(() => {
      setTimeout(() => {
        const viewRef = findNodeHandle(this._viewRef);
        this.setState({ viewRef });
      }, 250);
    });
  }
render() {

    return (
  <View style={styles.container}>
          <View
            ref={ref => (this._viewRef = ref)}
            style={{
              backgroundColor: "transparent"
            }}
          >
            <Image
              source={{
                uri:
                  "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRWcrnWgito6J4J-EmACyiRlPoCW73FZLvwI7bUJk2jWdmMC1z2JQ"
              }}
              style={{ width: width, height: height / 3 }}
            />
          </View>
          {(Platform.OS == "ios" || this.state.viewRef !== null) && (
            <BlurView
              viewRef={this.state.viewRef}
              blurAmount={3}
              blurType="light"
              style={{
                position: "absolute",
                top: height / 5,
                left: 0,
                right: 0,
                bottom: 0
              }}
            />
          )}
        </View>
)}
const styles = StyleSheet.create({
  container: {
    marginTop: 10

  },
  absolute: {
    position: "absolute",
    top: height / 5,
    left: 0,
    bottom: 0,
    right: 0

  }
});

Here is my screenshots:-
iOS:-
Simulator Screen Shot - iPhone 5s - 2019-05-06 at 16 53 08
Android:-
Screenshot_2019-05-06-16-58-20

As I mentioned earlier, you need to wrap absolutely positioned BlurView with View and control style from there with overflow: hidden (important) applied. For this image hack I also needed to wrap outer View with overflow: hidden. Also, you shouldn't rely on constant timeout (250ms) to wait for image to be loaded. Use Image event onLoad or onLoadEnd. This works for me on Android, untested on iOS:

  onImageRef = (ref: Image) => {
    this._imageRef = ref;
  };

  onImageLoad = () => {
    this.setState({
      imageNodeHandle: findNodeHandle(this._imageRef)!
    });
  };

  render() {
    return (
      <View style={{ marginTop: 10, overflow: "hidden" }}>
        <Image
          ref={this.onImageRef}
          onLoad={this.onImageLoad}
          source={{
            uri:
              "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRWcrnWgito6J4J-EmACyiRlPoCW73FZLvwI7bUJk2jWdmMC1z2JQ"
          }}
          style={{ width: width, height: height / 3 }}
        />
        {(Platform.OS === "ios" || this.state && this.state.imageNodeHandle !== null) && (
          <View style={[StyleSheet.absoluteFillObject, {
            width: width,
            height: (height / 3) / 2,
            overflow: "hidden"
          }]}>
            <BlurView blurType={"light"}
                      blurAmount={3}
                      style={[StyleSheet.absoluteFillObject]}
                      viewRef={this.state.imageNodeHandle}/>
          </View>)}
      </View>
    );
  }

Hi @abendi, thank you for your reply. Half of the part is blurred is working fine. But BlurView is applied to top of the image. I don't know how to set the BlurView is applied to bottom of the image as i mentioned iOS screenshot. Please give any solution for this.

Below mentioned android screenshot:-
Screenshot_2019-05-07-12-03-24

Just apply top or marginTop to the View wrapping the BlurView?

@abendi , yes i applied top property to View. But BlurView is displaying like mentioned screenshot.
Screenshot_2019-05-08-09-40-16
Here is my code:-

import React, { Component } from "react";
import {
  Platform,
  StyleSheet,
  Dimensions,
  View,
  Text,
  Image,
  TouchableOpacity,
  findNodeHandle
} from "react-native";
import { BlurView } from "@react-native-community/blur";
const { width, height } = Dimensions.get("window");
type Props = {};
export default class HalfBlur extends Component<Props> {
  constructor(props) {
    super(props);
    this.state = { imageNodeHandle: null };
  }

  onImageRef = (ref: Image) => {
    this._imageRef = ref;
  };

  onImageLoad = () => {
    this.setState({
      imageNodeHandle: findNodeHandle(this._imageRef)
    });
  };
  render() {
    return (
      <View style={{ marginTop: 10, overflow: "hidden" }}>
        <Image
          ref={this.onImageRef}
          onLoad={this.onImageLoad}
          source={{
            uri:
              "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRWcrnWgito6J4J-EmACyiRlPoCW73FZLvwI7bUJk2jWdmMC1z2JQ"
          }}
          style={{ width: width, height: height / 3 }}
        />
        {(Platform.OS === "ios" ||
          (this.state && this.state.imageNodeHandle !== null)) && (
          <View
            style={{
              position: "absolute",
              top: 100,
              bottom: 0,
              left: 0,
              right: 0,
              overflow: "hidden"
            }}
          >
            <BlurView
              blurType={"light"}
              blurAmount={3}
              style={[StyleSheet.absoluteFillObject]}
              viewRef={this.state.imageNodeHandle}
            />
          </View>
        )}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "white"
  },
  image: {
    width: width,
    height: height / 3.5
  },
  overlayStyle: {
    position: "absolute",
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    justifyContent: "flex-end"
  },
  buttonView: {
    backgroundColor: "transparent",
    top: 0,
    alignItems: "center",
    justifyContent: "flex-end"
  },
  buttonStyle: {
    height: width / 6.9,
    width: width / 1.5,
    borderRadius: width / 2,
    backgroundColor: "black",
    alignItems: "center",
    justifyContent: "center",
    alignSelf: "center"
  },
  buttonTextColor: {
    color: "white",
    fontSize: width / 18.7,
    textAlign: "center",
    textAlignVertical: "center"
  }
});

hi @abendi , Any solution for this issue???

Haven't figured out a way to do this on android either... Seems like height / top isn't doing anything

Hey guys I'm slightly confused. This library has 13,000+ downloads per month.
Is partial image blur not supported on Android?
@charpeni @abendi solution only works if you want to blur the top of the image.

Was this page helpful?
0 / 5 - 0 ratings