Search code examples
react-nativesvgreact-native-svg

Make child views or Text view scroll behind SVG shape with transparent background in react-native


I am trying to get the text or any other child views inside the scrollview to appear behind the SVG shape which is transparent, the following SVG shape code in react-native:

import React, { Component } from 'react';
import { View, Text, Image, Dimensions } from 'react-native';
import  { Path, G, Svg, Rect } from 'react-native-svg'

const shapes = {
    pathOne: "M380.279 107.377C380.279 107.377 295.739 13.1031 187.625 107.25C79.5108 201.397 -1.97128 107.125 -1.97128 107.125L-1.89778 1.07516e-06L380.353 0.252415L380.279 107.377Z",
}


export class WaveShape extends Component {


  constructor(props) {
    super(props);
    this.state = {
    };
  }

  render() {

    const { width, height } = Dimensions.get("screen")

    return (
        <Svg width="357" height="187" viewBox="-1 -1 375 187">
            <Path fill="red" fillOpacity={0.5} d={shapes.pathOne}></Path>
        </Svg>
    );
  }
}

The component where I am trying to get SVG shape to appear:

import React, { Fragment, Component } from 'react';
import {
    SafeAreaView,
    StyleSheet,
    ScrollView,
    View,
    Text,
    StatusBar,
  } from 'react-native';

  import {
    Header,
    LearnMoreLinks,
    Colors,
    DebugInstructions,
    ReloadInstructions,
  } from 'react-native/Libraries/NewAppScreen';
import { WaveShape } from '../components/WaveShape';

export class Main extends Component {

  static navigationOptions = {
      header: null
  }

  constructor(props) {
    super(props);
    this.state = {
    };
  }

  render() {
    return (
        <Fragment>
            <StatusBar barStyle="dark-content" />
            <SafeAreaView>
            <WaveShape></WaveShape>
            <ScrollView
                contentInsetAdjustmentBehavior="automatic"
                style={styles.scrollView}>
                {global.HermesInternal == null ? null : (
                <View style={styles.engine}>
                    <Text style={styles.footer}>Engine: Hermes</Text>
                </View>
                )}
                <View style={styles.body}>
                <View style={styles.sectionContainer}>
                    <Text style={styles.sectionTitle}>Step One</Text>
                    <Text style={styles.sectionDescription}>
                    Edit <Text style={styles.highlight}>App.js</Text> to change this
                    screen and then come back to see your edits.
                    </Text>
                </View>
                <View style={styles.sectionContainer}>
                    <Text style={styles.sectionTitle}>See Your Changes</Text>
                    <Text style={styles.sectionDescription}>
                    <ReloadInstructions />
                    </Text>
                </View>
                <View style={styles.sectionContainer}>
                    <Text style={styles.sectionTitle}>Debug</Text>
                    <Text style={styles.sectionDescription}>
                    <DebugInstructions />
                    </Text>
                </View>
                <View style={styles.sectionContainer}>
                    <Text style={styles.sectionTitle}>Learn More</Text>
                    <Text style={styles.sectionDescription}>
                    Read the docs to discover what to do next:
                    </Text>
                </View>
                <LearnMoreLinks />
                </View>
            </ScrollView>
            </SafeAreaView>
        </Fragment>
    );
  }
}

const styles = StyleSheet.create({
    scrollView: {
      backgroundColor: "white",
    },
    engine: {
      position: 'absolute',
      right: 0,
    },
    body: {
      backgroundColor: Colors.white,
    },
    sectionContainer: {
      marginTop: 32,
      paddingHorizontal: 24,
    },
    sectionTitle: {
      fontSize: 24,
      fontWeight: '600',
      color: Colors.black,
    },
    sectionDescription: {
      marginTop: 8,
      fontSize: 18,
      fontWeight: '400',
      color: Colors.dark,
    },
    highlight: {
      fontWeight: '700',
    },
    footer: {
      color: Colors.dark,
      fontSize: 12,
      fontWeight: '600',
      padding: 4,
      paddingRight: 12,
      textAlign: 'right',
    },
  });

This is what I am getting as a result:

enter image description here

Now my goal is to make child views or text appear behind the wave shape path and not the viewbox that contains the path of the SVG.


Solution

  • Thanks to hong develop I was able to achieve what I wanted by doing the following:

    The code for the SVG shape:

    import React, { Component } from 'react';
    import { View, Text, Image, Dimensions } from 'react-native';
    import  { Path, G, Svg, Rect } from 'react-native-svg'
    
    const shapes = {
        pathOne: "M380.279 107.377C380.279 107.377 295.739 13.1031 187.625 107.25C79.5108 201.397 -1.97128 107.125 -1.97128 107.125L-1.89778 1.07516e-06L380.353 0.252415L380.279 107.377Z",
    }
    
    
    export class WaveShape extends Component {
    
    
      constructor(props) {
        super(props);
        this.state = {
        };
      }
    
      render() {
    
        const { width, height } = Dimensions.get("screen")
        const { style, ...props } = this.props
    
        return (
            <Svg style={[style]} {...props} width="357" height="187" viewBox="-1 -1 375 187">
                <Path fill="red" fillOpacity={0.5} d={shapes.pathOne}></Path>
            </Svg>
        );
      }
    }
    

    Code where I am calling SVG shape:

    import React, { Fragment, Component } from 'react';
    import {
        SafeAreaView,
        StyleSheet,
        ScrollView,
        View,
        Text,
        StatusBar,
      } from 'react-native';
    
      import {
        Header,
        LearnMoreLinks,
        Colors,
        DebugInstructions,
        ReloadInstructions,
      } from 'react-native/Libraries/NewAppScreen';
    import { WaveShape } from '../components/WaveShape';
    
    export class Main extends Component {
    
      static navigationOptions = {
          header: null
      }
    
      constructor(props) {
        super(props);
        this.state = {
        };
      }
    
      render() {
        return (
            <Fragment>
                <StatusBar barStyle="dark-content" />
                <SafeAreaView>
                <WaveShape style={{ position: "absolute" ,top: 0, zIndex: 1 }}></WaveShape>
                <ScrollView
                    contentInsetAdjustmentBehavior="automatic"
                    style={styles.scrollView}>
                    <View style={{ paddingTop: "45%" }}></View>
                    {global.HermesInternal == null ? null : (
                    <View style={styles.engine}>
                        <Text style={styles.footer}>Engine: Hermes</Text>
                    </View>
                    )}
                    <View style={styles.body}>
                    <View style={styles.sectionContainer}>
                        <Text style={styles.sectionTitle}>Step One</Text>
                        <Text style={styles.sectionDescription}>
                        Edit <Text style={styles.highlight}>App.js</Text> to change this
                        screen and then come back to see your edits.
                        </Text>
                    </View>
                    <View style={styles.sectionContainer}>
                        <Text style={styles.sectionTitle}>See Your Changes</Text>
                        <Text style={styles.sectionDescription}>
                        <ReloadInstructions />
                        </Text>
                    </View>
                    <View style={styles.sectionContainer}>
                        <Text style={styles.sectionTitle}>Debug</Text>
                        <Text style={styles.sectionDescription}>
                        <DebugInstructions />
                        </Text>
                    </View>
                    <View style={styles.sectionContainer}>
                        <Text style={styles.sectionTitle}>Learn More</Text>
                        <Text style={styles.sectionDescription}>
                        Read the docs to discover what to do next:
                        </Text>
                    </View>
                    <LearnMoreLinks />
                    </View>
                </ScrollView>
                </SafeAreaView>
            </Fragment>
        );
      }
    }
    
    const styles = StyleSheet.create({
        scrollView: {
          backgroundColor: "white",
        },
        engine: {
          position: 'absolute',
          right: 0,
        },
        body: {
          backgroundColor: Colors.white,
        },
        sectionContainer: {
          marginTop: 32,
          paddingHorizontal: 24,
        },
        sectionTitle: {
          fontSize: 24,
          fontWeight: '600',
          color: Colors.black,
        },
        sectionDescription: {
          marginTop: 8,
          fontSize: 18,
          fontWeight: '400',
          color: Colors.dark,
        },
        highlight: {
          fontWeight: '700',
        },
        footer: {
          color: Colors.dark,
          fontSize: 12,
          fontWeight: '600',
          padding: 4,
          paddingRight: 12,
          textAlign: 'right',
        },
      });
    

    Result:

    enter image description here