reactjsreact-nativetextlinear-gradientsmaskedinput

Few words of Text to have linear gradient color - React native


I want to have some words of Text in linear gradient color. check desired output

To achieve gradient text I am doing -

import React from 'react';
import {Text} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import MaskedView from '@react-native-masked-view/masked-view';

const GradientText = props => {
  return (
    <MaskedView maskElement={<Text {...props} />}>
      <LinearGradient
        colors={['red', 'green', 'blue']}
        start={{x: 0, y: 0}}
        end={{x: 1, y: 0}}>
        <Text {...props} style={[props.style, {opacity: 0}]} />
      </LinearGradient>
    </MaskedView>
  );
};

export default GradientText;

When wrapping inside is not giving the required result -

<Text style={{color: 'white'}}>
    hello
    <GradientText>Gradient Text here</GradientText>
 </Text>

Flex is not helpful as multi-line sentence is not achievable using that.

Attached image of the desired output. Please help


Solution

  • Modify the GradientText component to accept children and apply the gradient to each character individually.

    Here is working example:

    
    import React from 'react';
    import { Text, TextProps, TextStyle, View } from 'react-native';
    import LinearGradient from 'react-native-linear-gradient';
    import MaskedView from '@react-native-masked-view/masked-view';
    
    interface GradientTextProps extends TextProps {
      children: React.ReactNode;
      style?: TextStyle;
    }
    
    const GradientText = ({ children, style, ...rest }: GradientTextProps) => {
      const gradientColors = ['red', 'green', 'blue'];
      return (
        <MaskedView
          maskElement={
            <Text style={style} {...rest}>
              {children}
            </Text>
          }>
          <LinearGradient
            colors={gradientColors}
            start={{ x: 0, y: 0 }}
            end={{ x: 1, y: 0 }}>
            <Text style={[style, { opacity: 0 }]} {...rest}>
              {children}
            </Text>
          </LinearGradient>
        </MaskedView>
      );
    };
    
    export default function App() {
      return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <GradientText style={{ fontSize: 40 }}>{`Hello World
          Hello World
          Hello World
          `}</GradientText>
        </View>
      );
    }