skip to Main Content

I am trying to create this effect, which can be found in the Spotify UI:

enter image description here

It seems that there are the following components:

  • A parent <View> (black)

  • The child <View> (pink)

  • The <Text> inside the child

  • The <Image>, which is a square shape, part of which is visible (on the pink background) and part of which is obscured (behind the black)

The problem is, how do they make this work zIndex-wise?

  • The parent <View> appears above the <Image> – "P > I"

  • The <Image> appears above the child <View> – "I > C"

  • The child <View> appears above the parent <View> – "C > P"

This leaves us with P > I > C > P, so P > P which isn’t possible with normal numbers, like those that zIndex is set to. This kind of property is called intransitivity and appears in situations like the game Rock Paper Scissors, where R > S > P > R.

Nevertheless, Spotify somehow managed to pull this off. Does anybody have any idea as to how this might be achieved?

Maybe the fact that React Native uses hierarchy-specific zIndexes rather than global ones could somehow help?

2

Answers


  1. Chosen as BEST ANSWER

    I found the solution - don't use zIndex. It's simply overflow: "hidden".

    <View style={{ overflow: "hidden" }}> {/* pink box */}
      {/* all content inside here will be clipped by the boundary of this view */}
    </View>
    

  2. Perhaps you shouldn’t use z-index. I think using backgrounds will be sufficient.

    import React from 'react';
    import { View, Text, Image, StyleSheet } from 'react-native';
    
    const MusicCard = () => {
      return (
        <View style={styles.container}>
          <Text style={styles.title}>Muzyka</Text>
          <Image
            source={{ uri: 'https://path-to-your-image.png' }} // replace with your image path
            style={styles.image}
          />
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        backgroundColor: '#d21b78', // pink background color
        padding: 20,
        borderRadius: 10,
        margin: 20,
        height: 200,
        justifyContent: 'space-between',
        alignItems: 'flex-start',
        position: 'relative',
      },
      title: {
        fontSize: 24,
        fontWeight: 'bold',
        color: '#fff',
      },
      image: {
        width: 100,
        height: 150,
        position: 'absolute',
        bottom: 10,
        right: 10,
        transform: [{ rotate: '-10deg' }],
      },
    });
    
    export default MusicCard;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search