I am trying to understand how the coordinate systems works in svg.
In the following HTML, I am unable to understand why the images enlarge if I don't specify viewport.
There seems to be a default size of viewport if I don't specify any value. What is it?
<!-- what is the default dimension of a viewport? -->
<p> no viewport or view box. viewport seem to have a default size. anything outside is clipped</p>
<svg style="border-style: dotted">
<ellipse cx="50" cy="50" rx="50" ry="50"></ellipse>
</svg>
<p> no viewport or view box. viewport seem to have a default size. anything outside is clipped</p>
<svg style="border-style: dotted">
<ellipse cx="50" cy="50" rx="1500" ry="1500"></ellipse>
</svg>
<p>viewport but no viewbox. Only what is in viewport is visible. Same as default viewport value case but we are specifying the dimensions of viewport here</p>
<svg width="50" height="50" style="border-style: dotted">
<ellipse cx="50" cy="50" rx="50" ry="50"></ellipse>
</svg>
<p>viewport but no viewbox. Only what is in viewport is visible. Same as default viewport value case but we are specifying the dimensions of viewport here</p>
<svg width="50" height="50" style="border-style: dotted">
<ellipse cx="50" cy="50" rx="1500" ry="1500"></ellipse>
</svg>
<!-- why this is large?-->
<p>viewbox but no viewport. Viewport takes same space as viewbox</p>
<svg viewBox="0 0 50 50" style="border-style: dotted">
<ellipse cx="50" cy="50" rx="50" ry="50"></ellipse>
</svg>
<!-- why this is large?-->
<p>viewbox but no viewport. Viewport takes same space as viewbox</p>
<svg viewBox="20 20 100 100" style="border-style: dotted">
<ellipse cx="50" cy="50" rx="50" ry="50"></ellipse>
</svg>
<p>viewport and viewbox. Value of viewport determines what would be visible</p>
<svg width="10" height="10" viewBox="0 0 50 50" style="border-style: dotted">
<ellipse cx="50" cy="50" rx="50" ry="50"></ellipse>
</svg>
Related
Edit: Maybe I need to test my assumption...
Is there a way to render svg so an element underlying another element can receive events?
The red circle does not respond to its hover event where it is under the clipped circle.
The rectangle iindicates the masked and clipped area of the green circle.
I want the visible red and green areas to both receive pointer events.
How would I get the whole red circle to respond - It has to underly the green circle.
Fiddle
<svg id="svg_wrp" width="600" height="600" style='z-index:2'>
<defs>
<mask id="green_mask">
<circle cx="300" cy="300" r="200" fill="#fff"></circle>
<rect x="100" y="50" width="400" height="200" fill="#000"></rect>
</mask>
<clipPath id="green_clip">
<rect x="100" y="50" width="400" height="200" fill='#000'></rect>
</clipPath>
</defs>
<!-- Following for reference only -->
<rect x="100" y="50" width="400" height="200" stroke="#080" fill="none"></rect>
<circle cx="300" cy="300" r="200" fill="rgba(0 0 255 /.2)" stroke="#080"></circle>
<!-- Above for reference only -->
<g>
<circle cx="300" cy="50" r="100" fill="rgba(255 0 0 /1)" class="hover_it" ></circle>
<!-- Following circle will have top part hidden, but mask does not prevent events -->
<circle id="green_hide_area"
cx="300" cy="300" r="200" fill="rgba(0 255 0 /1)" class="hover_it" mask="url(#green_mask)" ></circle>
</g>
<g>
<!-- Following circle will prevent events -->
<circle id="green_event_stop"
cx="300" cy="300" r="200" fill="transparent" clip-path="url(#green_clip)" ></circle>
</g>
</svg>
.hover_it{opacity:.5}
.hover_it:hover{opacity:1}
I'm trying to create a filter for only the stroke of path in SVG, but the feImage keeps getting clipped to what I assume is that bounding box (see green rectangle below in code as bounding box). I've tried setting the filter's x/y and width/height to all sorts of positions/sizes, as seems to be the prevailing advice, but nothing works. x/y just offset the feImage and width/height of greater than 100% has no effect.
I won't know in advance if the stroke or fill is solid or something else (like linearGradient.
The below demonstrates what I'm looking to do - just get the stroke of a shape (regardless of size or fill) and apply a filter to it for all modern browsers.
Notes: FF doesn't even display the left-hand feImage. Chrome clips the left and top. Edge clips all 4 sides.
<html>
<body>
<svg width="960" height="540" >
<rect width="960" height="540" stroke="#385D8A" fill="white" stroke-width="3"/>
<svg name="BoundingBox1" class="rect" x="100" y="100" overflow="visible" fill="none" stroke="#00ff00" stroke-width="1">
<path d="M0,0L121.68,0L121.68,121.68L0,121.68Z" />
</svg>
<!-- BELOW IS MODIFIED "SPEECH" SHAPE. NEED A FILTER ON THE STROKE ONLY. -->
<svg name="Speech-strokeonly" x="100" y="100" overflow="visible" fill="blue" stroke="orange" stroke-width="12" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path d="M35.541,137.084L30.985,113.988A60.926,60.926 0 1 1 53.043,121.34Z" id="strokeOnly" fill="none"/>
<filter id="effs0sp9" color-interpolation-filters="sRGB" x="0" y="0">
<feImage xlink:href="#strokeOnly" />
</filter>
</defs>
<path d="M35.541,137.084L30.985,113.988A60.926,60.926 0 1 1 53.043,121.34Z" id="effs0sp9" filter="url(#effs0sp9)" overflow="visible" />
<text y="160" stroke="black" stroke-width="0.2">this is the one that has undesirable clipping of</text>
<text y="178" stroke="black" stroke-width="0.2">of stroke in Chrome/Edge. Doesn't appear at all in FF</text>
</svg>
<!-- BELOW IS ORIGINAL WITH BOTH FILL AND STROKE -->
<svg name="BoundingBox2" x="400" y="100" overflow="visible" fill="none" stroke="green" stroke-width="1">
<path d="M0,0L121.68,0L121.68,121.68L0,121.68Z" />
</svg>
<svg name="Speech-original" x="400" y="100" overflow="visible" fill="blue" stroke="orange" stroke-width="12">
<path d="M35.541,137.084L30.985,113.988A60.926,60.926 0 1 1 53.043,121.34Z" id="effs0sp9" />
<text y="-22" stroke="black" stroke-width="0.2">this is the original one</text>
<text y="-6" stroke="black" stroke-width="0.2">that I just want the stroke as feImage from</text>
</svg>
</svg>
</body>
</html>
Is there a way to grab the whole stroke of a shape only and use in a filter?
I have a svg carpet need to apply rug fringes on carpet.
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<!-- Points -->
<circle cx="50" cy="50" r="20" fill="red"/>
</svg>
consider this circle as a carpet and i want to apply rug as like border. how we can scale path dynamically.
Your question is not very clear. Do you mean you want to add a fringe-like effect to the edge of the circle?
Like this?
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<!-- Points -->
<circle cx="50" cy="50" r="20" fill="red"
stroke="black" stroke-width="6" stroke-dasharray="1 2"/>
</svg>
I'm struggling with an SVG clip path scaling behaviour. I would like to scale a clip path to fit the element size it's applied to. I've been reading about clipPath units but I can't get this working.
Here is an example of what I am trying to do without any scaling: http://jsfiddle.net/1196o7n0/1/
...and the SVG ( the main shape and the clippath shape are exactly the same ):
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<clipPath id="svgPath">
<circle r="40" cy="50" cx="50" />
<circle r="74.576" cy="235" cx="193.949" />
<circle r="47.034" cy="108.305" cx="426.576" />
<circle r="43.644" cy="255.763" cx="346.915" />
<circle r="35.17" cy="82.882" cx="255.39" />
</clipPath>
<g fill="#000">
<circle r="40" cy="50" cx="50" />
<circle r="74.576" cy="235" cx="193.949" />
<circle r="47.034" cy="108.305" cx="426.576" />
<circle r="43.644" cy="255.763" cx="346.915" />
<circle r="35.17" cy="82.882" cx="255.39" />
</g>
</svg>
Now if I define a viewbox and make that SVG scales to fit the document width and height, the clip path doesn't seem to scale: http://jsfiddle.net/1196o7n0/2/
Any idea on how I can make this work ? Am i missing out on something?
To scale a clip path to fit the element that you are applying it to you need to add clipPathUnits="objectBoundingBox" to your clippath element.
Here is a JsFiddle based on your example demonstrating how to do this.
<svg width="0" height="0" >
<defs>
<clipPath id="svgPath" clipPathUnits="objectBoundingBox">
<circle r="0.05" cy="0.0625" cx="0.1625" />
<circle r="0.09322" cy="0.29375" cx="0.2424" />
<!-- rest of path here-->
</clipPath>
</defs>
</svg>
<div class="content centered">
<div class="clipped"></div>
</div>
The catcher is that the units of the path need to be decimal numbers between 0 and 1; these represent fractions of the corresponding element's width or height.
The clipPath is defined in absolute units (pixels). If it was being applied to something in the SVG, it would get scaled. But the HTML side of things doesn't know that. It just applies the clipPath as defined.
In this example, the green circle is cut off
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" version="1.1" style="background-color: pink" viewBox="-300 -300 500 500">
<svg width="500" height="500" x="0" y="0"><circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" /></svg>
<svg width="500" height="500" x="0" y="0"><circle cx="0" cy="0" r="40" stroke="black" stroke-width="2" fill="green" /></svg>
</svg>
</body>
</html>
See: http://jsfiddle.net/sCzZT/
Notice each circle is wrapped in its own svg
In this example (no nested svgs), the green circle is not cut off
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" version="1.1" style="background-color: pink" viewBox="-300 -300 500 500">
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
<circle cx="0" cy="0" r="40" stroke="black" stroke-width="2" fill="green" />
</svg>
</body>
</html>
http://jsfiddle.net/jVH9q/
How do I get the green circle to not get cut off when using nested svgs?
The inner svg has a default viewport which is 0, 0, 500, 500 (x, y, width, height) and by default anything that overflows this area is hidden/clipped.
There are several things you could do...
add an overflow="visible" attribute on the inner svg elements
change the x, y values so that the circle is within the viewport
add a viewBox so that you define an explicit viewport showing the area you want to see in the inner svg.