I'm trying to clip a circle so that it only shows for the part that falls within certain bounds. However, the circle is within a g element that is transformed. When I apply the clip path to either the g element or the path within this element ("g.site" or "g.site path") the circle complete gets clipped off. Short example showing my problem:
<svg width="600" height="600">
<defs>
<clipPath id="myClip">
<path d="M435.1256860398758,144.76407538624122L419.76193083948306,273.83328117717105L469.9933509829825,301.0396981292212L483.3234271019269,296.67464757752555L535.23683445551,247.72472220603692L574.3496211247055,127.3184557867296Z"
/>
</clipPath>
</defs>
<g id="voronoi">
<g id="cells">
<path class="cell" d="M435.1256860398758,144.76407538624122L419.76193083948306,273.83328117717105L469.9933509829825,301.0396981292212L483.3234271019269,296.67464757752555L535.23683445551,247.72472220603692L574.3496211247055,127.3184557867296Z"
/>
</g>
<g id="sites">
<g class="site" transform="translate(483.29548177370367,267.14072835257724)" clip-path="url(#myClip)">
<path fill="rgba(0, 255, 0, 0.5)" d="M0,30A30,20 0 1,1 0,-30A30,20 0 1,1 0,30M0,1A1,1 0 1,0 0,-1A1,1 0 1,0 0,1Z"
/>
</g>
<g class="site" transform="translate(483.29548177370367,267.14072835257724)">
<path fill="rgba(0, 0, 255, 0.5)" d="M0,30A30,20 0 1,1 0,-30A30,20 0 1,1 0,30M0,1A1,1 0 1,0 0,-1A1,1 0 1,0 0,1Z"
/>
</g>
</g>
</g>
</svg>
A working demo of my problem can be found in this fiddle: http://jsfiddle.net/xRh6A/
I added two circles. The first one is clipped off (because the clip-path attribute is set), the second is shown but (obviously) not clipped.
I suppose this is related to the fact that the clip-path is defined in absolute terms while the circle element has local coordinates and is then transformed. Can I use the clipPath with a transformed group or do I have to either change the clip path or the circle path in order to make them match?
Edit I solved it by placing the "sites" with absolute coordinates. However, this meant that I couldn't use d3.svg.arc (which is generating the code in the simplified example I attached) because it creates arcs in a local coordinate system.
I'd still be interested to see if it could be solved otherwise as well.
The clip-path property in CSS allows you to specify a specific region of an element to display, with the rest being hidden (or “clipped”) away. There used to be a clip property, but note that is deprecated. The most common use case would be an image, but it's not limited to that.
The <clipPath> SVG element defines a clipping path, to be used by the clip-path property. A clipping path restricts the region to which paint can be applied. Conceptually, parts of the drawing that lie outside of the region bounded by the clipping path are not drawn.
The clip-path CSS property creates a clipping region that sets what part of an element should be shown. Parts that are inside the region are shown, while those outside are hidden.
Your translation on the g
element is affecting how the clipPath
is rendered. You have 2 options:
Add the clip-path
attribute to a static parent element. You can then apply your translation on the child element without it affecting the clipPath
rendering.
Apply the inverse translation on the clipPath
element. I've never implemented this method, but I read about it here: https://stackoverflow.com/a/16166249/3123187. This option requires that you update the clipPath
tranform each time you change the g
transform.
In your case, you already have a parent g
element so you can add the clip-path
attribute there, if you intend to apply the clipPath
to every element in your g#sites
element.
<g id="sites" clip-path="url(#myClip)">
<g class="site" transform="translate(483.29548177370367,267.14072835257724)">
<path fill="rgba(0, 255, 0, 0.5)" d="M0,30A30,20 0 1,1 0,-30A30,20 0 1,1 0,30M0,1A1,1 0 1,0 0,-1A1,1 0 1,0 0,1Z" />
</g>
<g class="site" transform="translate(483.29548177370367,267.14072835257724)">
<path fill="rgba(0, 0, 255, 0.5)" d="M0,30A30,20 0 1,1 0,-30A30,20 0 1,1 0,30M0,1A1,1 0 1,0 0,-1A1,1 0 1,0 0,1Z" />
</g>
</g>
(jsfiddle: http://jsfiddle.net/SWyeD/)
If you only intend for that clipPath
to be applied to the first circle, you'd just add an intermediate container element.
<g id="sites">
<g clip-path="url(#myClip)">
<g class="site" transform="translate(483.29548177370367,267.14072835257724)">
<path fill="rgba(0, 255, 0, 0.5)" d="M0,30A30,20 0 1,1 0,-30A30,20 0 1,1 0,30M0,1A1,1 0 1,0 0,-1A1,1 0 1,0 0,1Z" />
</g>
</g>
<g class="site" transform="translate(483.29548177370367,267.14072835257724)">
<path fill="rgba(0, 0, 255, 0.5)" d="M0,30A30,20 0 1,1 0,-30A30,20 0 1,1 0,30M0,1A1,1 0 1,0 0,-1A1,1 0 1,0 0,1Z" />
</g>
</g>
(jsfiddle: http://jsfiddle.net/bdB65/)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With