Here’s how to do this, on both platforms, using react-native-svg's clipPath

First, you need to create this (or any other) shape in any vector drawing software, and export it as SVG. Here’s how it looks like exported from Adobe Illustrator:

<?xml version="1.0" encoding="utf-8"?>

<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 828.2 827.8" style="enable-background:new 0 0 828.2 827.8;" xml:space="preserve"> <path d="M762.2,189.9c-17.4-27.1-38.1-52.2-61.3-74.5c-23.9-22.9-50.8-43.1-79.8-59.8C528.3,2,419.9-13.5,315.9,11.9 c-50.6,12.4-97.8,33.8-140.2,63.6C131.9,106.3,95,144.9,65.9,190.1c-0.1,0.2-0.2,0.3-0.3,0.5c-3.4,5.8-1.4,13,4.4,16.4l308.3,178 c8.4-10.4,21.3-17.1,35.8-17.1c14.4,0,27.2,6.6,35.6,16.9l308.4-178c1.9-1.1,3.4-2.6,4.5-4.4C764.8,198.5,764.7,193.7,762.2,189.9z"/> </svg>

It contains a lot of junk like comments, headers, and other superfluous stuff which we don’t need. But we need the generated path value as well as viewBox size. Save those.

As stated in documentation available here you must put clipPath inside defs element of the SVG which is used to store graphical objects that will be used later on (more on that here).

For our example, it looks like this:

<Defs>

<ClipPath id="clipPath">

<Path fill="white" stroke="gray" strokeWidth="3"

d="M762.2,189.9c-17.4-27.1-38.1-52.2-61.3-74.5c-23.9-22.9-50.8-43.1-79.8-59.8C528.3,2,419.9-13.5,315.9,11.9 c-50.6,12.4-97.8,33.8-140.2,63.6C131.9,106.3,95,144.9,65.9,190.1c-0.1,0.2-0.2,0.3-0.3,0.5c-3.4,5.8-1.4,13,4.4,16.4l308.3,178 c8.4-10.4,21.3-17.1,35.8-17.1c14.4,0,27.2,6.6,35.6,16.9l308.4-178c1.9-1.1,3.4-2.6,4.5-4.4C764.8,198.5,764.7,193.7,762.2,189.9z"/>

</ClipPath>

</Defs>

After that, you must define Image which will be used to fill this area (an image that will be clipped by this path) and apply clipPath id to it so that the image knows which element to refer to.

The trick here is that you must wrap Image element with a Group element ( G ) in order for it to work on iOS, but without G for it to work on Android.

Here’s an example:

{Platform.OS === 'ios' ? (

<G clipPath="url(#clipPath)">

<Image

x="0"

y="0"

width="100%"

height="100%"

preserveAspectRatio="xMidYMid slice"

href={{ uri: 'image url here'}} />

</G>

) : (

<Image

clipPath="url(#clipPath)"

x="0"

y="0"

width="100%"

preserveAspectRatio="xMidYMid slice"

href={{ uri: 'image url here'}}/>

)}

For some reason, Android Image just doesn’t like being wrapped in G (it doesn’t clip properly), and if you add clipPath directly to the Image on iOS it will just fail to compile using Typescript. So there’s that.

I’ve used Platform module directly from react-native to detect the platform and apply changes accordingly. Note the clipPath reference to the path defined above using id which is defined in the path object.

Besides that, you just need to wrap it inside the SVG object containing the same ViewBox dimensions as in the exported SVG object from the start. You can find the entire example here: https://codesandbox.io/s/q8rn840nxq. It’s not runnable directly in the browser, sorry.

And that’s it. It’s quite simple, but somehow tutorials fail to provide all the steps for this to work out of the box for all platforms. I hope this helps!