1

I'm trying to create the below crude example using react-native-svg.

The background image is dynamic and requires a hollow circular mask. This also needs to blur that section of the background image. Whilst I can get a cutout blurred with no problem, I cannot figure out how to create it exactly like the hollow one below. Advice appreciated.

hollow circle cutout

Code Example:

  <ImageBackground
    resizeMode="cover"
    source={{ uri: route.params?.image }}
    style={{ flex: 1}}
    blurRadius={0}
  >
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
      }}
    >
      <Svg width={300} height={300}>
        <Circle cx={150} cy={150} r={120} fill={"transparent"} />
        <Circle
          cx={150}
          cy={150}
          r={120}
          strokeWidth={60}
          stroke={hexToRgba("#000", "0.4")}
          fill="transparent"
        />
      </Svg>
    </View>
  </ImageBackground>

Result:

enter image description here

wbdlc
  • 1,070
  • 1
  • 12
  • 34
  • 1
    Have you made any attempts to to do this? What (relevant) "*[mcve]*" HTML and CSS have you written so far? If you share your code then we can make suggestions, otherwise - with just a picture - we can't really offer anything without making profound, and probably incorrect, guesses. – David Thomas Jul 22 '23 at 17:26
  • @DavidThomas Indeed, I downed tools in despair and in search of a warm libation, clarity is returning. I've included up to where I'm stuck. I'm in search now of how to blur the image in the Circle stroke, if that makes sense. – wbdlc Jul 22 '23 at 17:44

1 Answers1

2

You can create a blurred version of the image on top of the image itself and add a mask to the blurred image with a circle.

<svg viewBox="0 0 256 171" width="400" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="blur1">
      <feGaussianBlur stdDeviation="2" />
    </filter>
    <mask id="m1">
      <circle cx="50%" cy="50%" r="28%" stroke="white" stroke-width="13%" />
    </mask>
  </defs>
  <image id="img" width="100%" href="https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Hopetoun_falls.jpg/512px-Hopetoun_falls.jpg" >
    <title>Photo by DAVID ILIFF, CC BY-SA 3.0 &lt;https://creativecommons.org/licenses/by-sa/3.0&gt;, via Wikimedia Commons</title>
  </image>
  <use href="#img" filter="url(#blur1)" mask="url(#m1)"/>
</svg>

Update

I don't know react-native-svg, but I guess you can use their converter SVGR Playground - SVGR. It returns the following code that includes the filter:

import * as React from "react"
const SvgComponent = (props) => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    width={400}
    viewBox="0 0 256 171"
    {...props}
  >
    <defs>
      <filter id="b">
        <feGaussianBlur stdDeviation={2} />
      </filter>
      <mask id="c">
        <circle cx="50%" cy="50%" r="28%" stroke="#fff" strokeWidth="13%" />
      </mask>
    </defs>
    <image
      id="a"
      width="100%"
      href="https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Hopetoun_falls.jpg/512px-Hopetoun_falls.jpg"
    >
      <title>
        {
          "Photo by DAVID ILIFF, CC BY-SA 3.0 <https://creativecommons.org/licenses/by-sa/3.0>, via Wikimedia Commons"
        }
      </title>
    </image>
    <use filter="url(#b)" href="#a" mask="url(#c)" />
  </svg>
)
export default SvgComponent

chrwahl
  • 8,675
  • 2
  • 20
  • 30