SVG clipping "as you go" - svg

In the Windows API and the PostScript language you can setup clipping at any point along the way.
An unreal but simple example:
a) I draw a circle.
b) Then I set a clipping rectangle.
c) Then I draw another circle.
d) Then I remove the clipping.
I can't find a way of doing that with SVG. I'm probably missing something, and I can't find an example which could help me.
Do all the clipping rectangles windows I want to use in the file have to be setup at the beginning?
I've tried this:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" width="2678.000" height="1600.000" preserveAspectRatio="xMidYMid meet"
viewBox="0.000000 0.000000 2678.000000 1600.000000">
<g clip-path="EEE">
<clipPath id="EEE"> <rect x="40" y="40" width="1000" height="1000"/> </clipPath>
<polyline style="stroke:#FF5F42;stroke-width:4;fill:none;" points="0,0 2000,1500 "/>
<polyline style="stroke:#FF5F42;stroke-width:4;fill:none;" points="0,0 500,500 "/>
<polyline style="stroke:#00FF00;stroke-width:4;fill:none;" points="0,0 250,250 "/>
<text x="284" y="1365" style="text-anchor:start;dominant-baseline:hanging;font-size:36.0px;"> Flux 5300.00 lm</text>
</g>
</svg>
...however I can still see the text which should have been clipped out. It is at 1365 and the clipping rectangle ends at 1040...

Ooooops. Think I've got there.
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" width="2678.000" height="1600.000" preserveAspectRatio="xMidYMid meet"
viewBox="0.000000 0.000000 2678.000000 1600.000000">
<defs>
</defs>
<g clip-path="url(#EEE)">
<clipPath id="EEE">
<rect x="0" y="140" width="1000" height="800"/>
</clipPath>
<polyline style="stroke:#FF5F42;stroke-width:4;fill:none;" points="0,0 2000,1500 "/>
<polyline style="stroke:#FF5F42;stroke-width:4;fill:none;" points="0,0 500,500 "/>
<polyline style="stroke:#00FF00;stroke-width:4;fill:none;" points="0,0 150,1250 "/>
<text x="284" y="1365" style="text-anchor:start;dominant-baseline:hanging;font-size:36.0px;"> Flux 5300.00 lm</text>
</g>
</svg>
My first error was thinking I had to define something before using it. See how I use EEE before I define it above...
My second error was not understanding how to use "url(...)" agh.
Thanks to Robert Logson for nudging me along in the right direction.

Related

Clip Path not working in an SVG element

I'm trying to get a rectangular <clipPath> to clip a <circle> in an SVG element, but I can't seem to get it work.
Does anyone know what the problem is?
Many thanks in advance for any help.
Codepen: https://codepen.io/emilychews/pen/jpLMaV
Em
#circle {width: 10rem;}
<defs>
<clipPath id="myClipPath">
<rect x="30" y="30" width="100" height="100"/>
</clipPath>
</defs>
<svg id="circle" style="clip-path: url(#myClipPath)" viewBox="0 0 391 391">
<circle fill="#000" cx="195.5" cy="195.5" r="195"/>
</svg>
You forget <svg> around your clip path declaration .
<svg width=0 height=0 >
<defs>
<clipPath id="myClipPath">
<rect x="50px" y="50px" width="200px" height="200px"/>
</clipPath>
</defs>
</svg>
<svg style="clip-path: url(#myClipPath)" id="circle" width="400" height="400">
<circle fill="#000" cx="100px" cy="100px" r="100px"/> </svg>
edit: i simplified and i added a witdh and height attribute

SVG path mask not working

According to example of this tutorials I want to mask my icon (black and white) instead of text in this tutorial. but right side of icon is still dark. how can I make left side of my icon black stroke and right side of icon goes white stroke?
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="41px" height="50px" viewbox="-3 -3 40 48">
<defs>
<mask id="myMask" maskUnits="userSpaceOnUse"
x="0" y="0" width="18" height="50">
<rect x="0" y="0" width="15" height="50" fill="white"/>
</mask>
<path id="fire-icon" d="m 25.55134,17.573125 c 0.647761,1.273107 1.136636,2.596633 1.344412,4.021007 0.21999,1.47479 0.13444,2.924371 -0.342217,4.348739 -0.427768,1.273111 -1.124413,2.382358 -2.004391,3.378155 -0.977758,1.096637 -2.114394,1.991591 -3.348802,2.773105 -0.183328,0.113445 -0.366658,0.226895 -0.57443,0.365546 1.429964,-3.214282 1.686623,-5.760501 0.366659,-8.924365 -0.904421,-2.155462 -2.395495,-3.743696 -3.519909,-4.4874 0,0 0.305545,3.655466 -2.248829,5.9874 0.391098,-1.184876 -0.672208,-2.31933 -0.672208,-2.31933 -0.31777,1.386549 -0.8922,1.651268 -1.662178,2.836135 -0.366658,0.567227 -0.708873,1.159666 -0.941085,1.802516 -0.342214,0.970596 -0.403325,1.953785 -0.207778,2.96219 0.134444,0.668067 0.342218,1.310925 0.63554,1.941174 0.02446,0.05042 0.04889,0.113449 0.08556,0.226893 C 12.156129,32.308418 11.899468,32.169763 11.655035,31.993294 10.921719,31.463881 10.163961,30.959677 9.467313,30.37985 8.5628918,29.623547 7.8173555,28.715982 7.3284794,27.619344 7.0351536,26.951277 6.8640469,26.245395 6.8151593,25.514301 c -0.097775,-1.65126 0.2933257,-3.201685 0.9899743,-4.676472 0.5010979,-1.071427 0.9777525,-2.142852 1.4544067,-3.226887 0.1344411,-0.31513 0.2199942,-0.66807 0.3055478,-1.008411 0.085554,-0.327726 0.1344412,-0.668063 0.1955503,-1.033609 0.9777516,0.46639 1.4544056,2.521009 0.9044216,3.857144 0.02444,0 0.03666,0 0.06111,0 0.232216,-0.302517 0.464431,-0.605039 0.696652,-0.907563 0.977751,-1.323526 1.869945,-2.684872 2.566595,-4.184872 0.623316,-1.34874 1.099973,-2.735295 1.185527,-4.247902 0.02445,-0.5294123 -0.02445,-1.0714263 -0.03667,-1.6008383 0.01223,0 0.02445,0 0.03667,0 0.65998,0.315125 1.307741,0.680673 1.882172,1.134457 1.014423,0.8193243 1.857728,1.7899163 2.566601,2.8991563 0.892198,1.411766 1.515512,2.936975 1.955505,4.550418 0.01223,0.06302 0.03667,0.126055 0.06111,0.214286 1.344407,-1.210083 0.513317,-4.172266 0.501096,-4.222688 -0.02445,-0.0252 2.261053,2.029411 3.409911,4.512605 z"
fill="none" stroke="#303233" stroke-width="1.3" />
</defs>
<!-- Draw black rectangle in the background -->
<rect x="18" y="0" width="15" height="50" fill="#000" />
<!-- Draw the text string twice. First, the white text without mask.
Second, the black text with the mask applied-->
<use xlink:href="#fire-icon" stroke="white"/>
<use xlink:href="#fire-icon" stroke="black" mask="url(#myMask)"/>
</svg>
There's no mask issue. The stroke on the path overrides the stroke on the use element, so in the question there are two grey (#303233) stroked paths. Removing the path stroke atribute allows the use to set one.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="41px" height="50px" viewbox="-3 -3 40 48">
<defs>
<mask id="myMask" maskUnits="userSpaceOnUse"
x="0" y="0" width="18" height="50">
<rect x="0" y="0" width="15" height="50" fill="white"/>
</mask>
<path id="fire-icon" d="m 25.55134,17.573125 c 0.647761,1.273107 1.136636,2.596633 1.344412,4.021007 0.21999,1.47479 0.13444,2.924371 -0.342217,4.348739 -0.427768,1.273111 -1.124413,2.382358 -2.004391,3.378155 -0.977758,1.096637 -2.114394,1.991591 -3.348802,2.773105 -0.183328,0.113445 -0.366658,0.226895 -0.57443,0.365546 1.429964,-3.214282 1.686623,-5.760501 0.366659,-8.924365 -0.904421,-2.155462 -2.395495,-3.743696 -3.519909,-4.4874 0,0 0.305545,3.655466 -2.248829,5.9874 0.391098,-1.184876 -0.672208,-2.31933 -0.672208,-2.31933 -0.31777,1.386549 -0.8922,1.651268 -1.662178,2.836135 -0.366658,0.567227 -0.708873,1.159666 -0.941085,1.802516 -0.342214,0.970596 -0.403325,1.953785 -0.207778,2.96219 0.134444,0.668067 0.342218,1.310925 0.63554,1.941174 0.02446,0.05042 0.04889,0.113449 0.08556,0.226893 C 12.156129,32.308418 11.899468,32.169763 11.655035,31.993294 10.921719,31.463881 10.163961,30.959677 9.467313,30.37985 8.5628918,29.623547 7.8173555,28.715982 7.3284794,27.619344 7.0351536,26.951277 6.8640469,26.245395 6.8151593,25.514301 c -0.097775,-1.65126 0.2933257,-3.201685 0.9899743,-4.676472 0.5010979,-1.071427 0.9777525,-2.142852 1.4544067,-3.226887 0.1344411,-0.31513 0.2199942,-0.66807 0.3055478,-1.008411 0.085554,-0.327726 0.1344412,-0.668063 0.1955503,-1.033609 0.9777516,0.46639 1.4544056,2.521009 0.9044216,3.857144 0.02444,0 0.03666,0 0.06111,0 0.232216,-0.302517 0.464431,-0.605039 0.696652,-0.907563 0.977751,-1.323526 1.869945,-2.684872 2.566595,-4.184872 0.623316,-1.34874 1.099973,-2.735295 1.185527,-4.247902 0.02445,-0.5294123 -0.02445,-1.0714263 -0.03667,-1.6008383 0.01223,0 0.02445,0 0.03667,0 0.65998,0.315125 1.307741,0.680673 1.882172,1.134457 1.014423,0.8193243 1.857728,1.7899163 2.566601,2.8991563 0.892198,1.411766 1.515512,2.936975 1.955505,4.550418 0.01223,0.06302 0.03667,0.126055 0.06111,0.214286 1.344407,-1.210083 0.513317,-4.172266 0.501096,-4.222688 -0.02445,-0.0252 2.261053,2.029411 3.409911,4.512605 z"
fill="none" stroke-width="1.3" />
</defs>
<!-- Draw black rectangle in the background -->
<rect x="18" y="0" width="15" height="50" fill="#000" />
<!-- Draw the text string twice. First, the white text without mask.
Second, the black text with the mask applied-->
<use xlink:href="#fire-icon" stroke="white"/>
<use xlink:href="#fire-icon" stroke="black" mask="url(#myMask)"/>
</svg>

How do I perfectly center a single character inside an SVG circle?

I'd like to place a single character, perfectly centered, inside this circle:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="100" height="100">
<g>
<circle style="fill:#eeeeee" cx="50" cy="50" r="50">
</circle>
<text>C</text>
</g>
</svg>
Ideally, the solution works for any single ASCII character.
Thanks for the help!
Use a combination of text-anchor="middle" to centre the text horizontally, and dominant-baseline="central" to centre it vertically.
To simplify things, I've added a transform attribute to your <g> element to move the origin to the middle of your canvas.
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<g transform="translate(50,50)">
<circle style="fill:#eeeeee" r="50" />
<text text-anchor="middle" dominant-baseline="central">C</text>
</g>
</svg>

Drawing a grid using SVG markup

I'm seeking to draw a grid onto which i will be adding a number of simple rectangles, again using SVG. The grid should fit on a single page when viewed in a browser. Suspect i'm missing something very simple but do i code the SVG (viewport and grid) for this outcome; namely a grid?
I've read advice to specify a viewbox that defines the internal coordinate system of the document's canvas; also that it's possible to set height and width attributes as percentages (?). Ideally final result (ultimately a map) is to have gridlines.
Use a pattern on a fully wide and high rectangle.
<svg width="800" height="600">
<defs>
<pattern id="tenthGrid" width="10" height="10" patternUnits="userSpaceOnUse">
<path d="M 10 0 L 0 0 0 10" fill="none" stroke="silver" stroke-width="0.5"/>
</pattern>
<pattern id="grid" width="100" height="100" patternUnits="userSpaceOnUse">
<rect width="100" height="100" fill="url(#tenthGrid)"/>
<path d="M 100 0 L 0 0 0 100" fill="none" stroke="gray" stroke-width="1"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid)"/>
</svg>

SVG clipPath to clip the *outer* content out

Normally, the <clipPath> element hides everything that is outside the clip path. To achieve the opposite effect - that is to "cut out" something from the image - i want to use two paths in the clipPath and the clip-rule="evenodd" attribute. Basically, I want to "xor" the clip paths.
But it doesn't work. It shows the region "ORed":
<clipPath clip-rule="evenodd" id="imageclippath" clipPathUnits = "objectBoundingBox">
<rect clip-rule="evenodd" x="0.3" y="0.3" height="0.6" width="6" />
<rect clip-rule="evenodd" x="0" y="0" height="0.5" width="0.5" />
</clipPath>
<rect clip-path="url(#imageclippath)" x="0" y="0" height="500" width="500" fill="red"/>
EDIT:
My problem is that AFAIK <mask> doesn't work in iOS WebKit.
It's much easier to do what you're after with a mask, see this example. Here's the mask definition:
<mask id="maskedtext">
<circle cx="50%" cy="50%" r="50" fill="white"/>
<text x="50%" y="55%" text-anchor="middle" font-size="48">ABC</text>
</mask>
Regions that are white inside the mask will be kept, everything else will be clipped away.
Here's another example that uses clipPath instead, is a bit trickier since you need to use a path element to get the clip-rule to apply. The clipPath that uses clip-rule there looks like this:
<clipPath id="clipPath1">
<path id="p1" d="M10 10l100 0 0 100 -100 0ZM50 50l40 0 0 40 -40 0Z" clip-rule="evenodd"/>
</clipPath>

Resources