Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to paint a whole SVG except for the insides of a shape. #936

Closed
hirejohnsalcedo opened this issue Feb 13, 2019 · 2 comments
Closed

How to paint a whole SVG except for the insides of a shape. #936

hirejohnsalcedo opened this issue Feb 13, 2019 · 2 comments
Labels

Comments

@hirejohnsalcedo
Copy link

hirejohnsalcedo commented Feb 13, 2019

I've tried the Mask element for it. But, I'm not sure if I'm going the right path. Couldn't seem to figure out how to accomplish it. From what I understand, I'm trying to accomplish the reverse of a ClipPath. Basically paint everything outside but protect the inside of a shape.

wxbar
vfxdv

@hirejohnsalcedo hirejohnsalcedo changed the title Paint a whole SVG except for the insides of a shape. How to paint a whole SVG except for the insides of a shape. Feb 14, 2019
@msand
Copy link
Collaborator

msand commented Feb 15, 2019

You can use either one, but clipping will likely be more efficient, e.g. clipPath with clipRule set to evenodd and geometry something like this will probably be the easiest:

import React from 'react';
import { View } from 'react-native';
import Svg, { Defs, ClipPath, Circle, Rect } from 'react-native-svg';

export default class App extends React.Component {
  render() {
    return (
      <View
        style={{
          flex: 1,
          alignContent: 'center',
          justifyContent: 'center',
          backgroundColor: '#ecf0f1',
        }}
      >
        <Svg width="100%" height="100%" viewBox="0 0 100 100">
          <Defs>
            <ClipPath id="clip_out" clipRule="evenodd">
              <Rect width={100} height={100}/>
              <Circle cx={50} cy={50} r={25}/>
            </ClipPath>
          </Defs>
          <Rect width={100} height={100} fill="green" clipPath="url(#clip_out)" />
        </Svg>
      </View>
    );
  }
}

screenshot_1550272899

Alternatively you can use clipRule="nonzero" and draw path segments in opposite directions such that they cancel out in the parts you want to exclude:
https://www.w3.org/TR/SVG11/masking.html#ClipRuleProperty
https://www.w3.org/TR/SVG11/painting.html#FillRuleProperty
Something a bit like this:

        <Svg width="100%" height="100%" viewBox="0 0 200 200">
          <Defs>
            <ClipPath id="clip" clipRule="nonzero">
              <Path d="
              M50 50 h100 v100 H50z
              m25 25 v50  h50  V75z" />
            </ClipPath>
          </Defs>
          <Circle cx={100} cy={100} r={55} clipPath="url(#clip)" />
        </Svg>

@annebancroftsghost
Copy link

I've tried your solution but TS is telling me that clipRule is not a property of ClipPath, and sure enough when I inspect the module, it only has optional id. Did this implementation change recently?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants