Any idea why the rotation does not seem to take place in the clip path coordinates? 0.5 0.5 should denote the center of the shape, i.e. where the two squares meet.
svg {
background: green;
}
<svg width="100" height="100" viewBox="0 0 100 100">
<clipPath id="rel" clipPathUnits="objectBoundingBox" transform="rotate(20 0.5 0.5)">
<rect width="0.5" height="0.5"/>
<rect x="0.5" y="0.5" width="0.5" height="0.5"/>
</clipPath>
<rect width="100" height="100" x="0" y="0" clip-path="url(#rel)" fill="red"/>
</svg>
I expected to see something like this:
svg {
background: green;
}
<svg width="100" height="100" viewBox="0 0 100 100">
<clipPath id="abs" transform="rotate(20 50 50)">
<rect width="50" height="50"/>
<rect x="50" y="50" width="50" height="50"/>
</clipPath>
<rect width="100" height="100" x="0" y="0" clip-path="url(#abs)" fill="red"/>
</svg>
I have found an SVG layer on the net. There should be a transparent hole in it. But I don't know how to change the colour around the hole from black to e.g. #5BBB74.
<svg viewbox="0 0 100 50" width="100%">
<defs>
<mask id="mask" x="0" y="0" width="80" height="30">
<rect x="0" y="0" width="100" height="40" fill="#fff"/>
<circle cx="50" cy="20" r="10" />
</mask>
</defs>
<rect x="0" y="0" width="100" height="50" mask="url(#mask)" fill-opacity=""/>
</svg>
You can add fill property to the rect affected by the mask.
<svg viewbox="0 0 100 50" width="100%">
<defs>
<mask id="mask" x="0" y="0" width="80" height="30">
<rect x="0" y="0" width="100" height="40" fill="#fff"/>
<circle cx="50" cy="20" r="10" />
</mask>
</defs>
<rect x="0" y="0" width="100" height="50" mask="url(#mask)" fill-opacity="" fill="#5BBB74"/>
</svg>
I have some tile symbols that I would like to place on a grid. This is what I'm trying to achieve:
Use tile coordinates to position the symbols (e.g. 4,2 instead of 85,43)
Use pixel coordinates (not tile coordinates) for defining the vertices of symbols
Rotate symbols around their center without specifying absolute coordinates.
I have solutions to the first two (there might be better solutions though) but not the third. I can rotate the tile at 4,2 by a quarter turn with this:
<!-- 10/21 = 0.47619047619 -->
<use x="4" y="2" href="#rooftop-0" class="theme-0" transform="rotate(90 4.476 2.476)" />
I really don't like having to specify the tile coordinates twice. Ideally, I would like to write something like this instead:
<use x="4" y="2" href="#rooftop-0" class="theme-0 rotate-1" />
Defining .rotate-1 in the stylesheet doesn't seem to have any effect on the rotation. transform-origin="50% 50%" seems to be setting the origin to 50% of the viewport or something. Maybe defining the symbol with coordinates from -10 to 10 instead of 0 to 20 would help? Should I define the viewBox of the symbols?
Another solution would be manually changing the coordinates of the vertices in the symbol to create the other 3 orientations. I'd rather not!
Anyway, this is what I have so far:
<?xml version="1.0" standalone="no"?>
<!-- 21*10+1 = 211 -->
<svg width="211" height="211" version="2.0" xmlns="http://www.w3.org/2000/svg">
<style>
.grid-line {
fill: #DDD;
}
.grass-fill {
fill: #8C8;
}
.tile {
/* 1/21 = 0.04761904761 */
transform: scale(0.04761904761, 0.04761904761);
}
.theme-0 {
--roof-color-0: #F44;
--roof-color-1: #F66;
--roof-color-2: #F88;
--roof-color-3: #FAA;
}
.theme-1 {
--roof-color-0: #44F;
--roof-color-1: #66F;
--roof-color-2: #88F;
--roof-color-3: #AAF;
}
</style>
<defs>
<pattern id="grid" width="21" height="21" patternUnits="userSpaceOnUse">
<rect class="grid-line" x="0" y="0" width="1" height="21" />
<rect class="grid-line" x="0" y="0" width="21" height="1" />
</pattern>
<symbol id="rooftop-0">
<g class="tile">
<rect class="grass-fill" width="20" height="20" />
<polygon style="fill: var(--roof-color-0)" points="3,2 17,2 18,8 2,8" />
<polygon style="fill: var(--roof-color-1)" points="2,8 18,8 17,14 3,14" />
<polygon style="fill: var(--roof-color-2)" points="8,8 11,14 11,18 8,18" />
<polygon style="fill: var(--roof-color-3)" points="8,8 8,18 5,18 5,14" />
</g>
</symbol>
<symbol id="rooftop-1">
<g class="tile">
<rect class="grass-fill" width="20" height="20" />
<polygon style="fill: var(--roof-color-0)" points="2,11 18,11 17,17 3,17" />
<polygon style="fill: var(--roof-color-1)" points="3,5 17,5 18,11 2,11" />
<polygon style="fill: var(--roof-color-2)" points="10,11 10,3 13,3 13,5" />
<polygon style="fill: var(--roof-color-3)" points="10,11 7,5 7,3 10,3" />
</g>
</symbol>
</defs>
<g>
<rect fill="#999" width="100%" height="100%" />
<rect fill="url(#grid)" width="100%" height="100%" />
</g>
<g transform="translate(1, 1) scale(21, 21)">
<use x="3" y="2" href="#rooftop-0" class="theme-1" />
<!-- 10/21 = 0.47619047619 -->
<use x="4" y="2" href="#rooftop-0" class="theme-0" transform="rotate(90 4.476 2.476)" />
<use x="5" y="2" href="#rooftop-1" class="theme-1" />
</g>
</svg>
Here's a screenshot:
Is there a clean way of doing what I'm trying to do? Rotating a symbol around its center seems like something one would do all the time.
Instead of setting your <use> attributes using xand y coordinates, you can set them using transform="translate(x, y), this way, the origin parameters of the rotate() method will stay the same (0.5, 0.5):
<svg viewBox="0 0 211 211">
<style>
.grid-line {
fill: #DDD;
}
.grass-fill {
fill: #8C8;
}
.theme-0 {
--roof-color-0: #F44;
--roof-color-1: #F66;
--roof-color-2: #F88;
--roof-color-3: #FAA;
}
.theme-1 {
--roof-color-0: #44F;
--roof-color-1: #66F;
--roof-color-2: #88F;
--roof-color-3: #AAF;
}
</style>
<defs>
<pattern id="grid" x="-0.5" y="-0.5" width="20" height="20" patternUnits="userSpaceOnUse">
<rect class="grid-line" x="0" y="0" width="1" height="20" />
<rect class="grid-line" x="0" y="0" width="20" height="1" />
</pattern>
<symbol id="rooftop-0" viewBox="0 0 20 20">
<g class="tile" transform="translate(0.5, 0.5) scale(0.95)">
<rect class="grass-fill" width="20" height="20" />
<polygon style="fill: var(--roof-color-0)" points="3,2 17,2 18,8 2,8" />
<polygon style="fill: var(--roof-color-1)" points="2,8 18,8 17,14 3,14" />
<polygon style="fill: var(--roof-color-2)" points="8,8 11,14 11,18 8,18" />
<polygon style="fill: var(--roof-color-3)" points="8,8 8,18 5,18 5,14" />
</g>
</symbol>
<symbol id="rooftop-1" viewBox="0 0 20 20">
<g class="tile"transform="translate(0.5, 0.5) scale(0.95)">
<rect class="grass-fill" width="20" height="20" />
<polygon style="fill: var(--roof-color-0)" points="2,11 18,11 17,17 3,17" />
<polygon style="fill: var(--roof-color-1)" points="3,5 17,5 18,11 2,11" />
<polygon style="fill: var(--roof-color-2)" points="10,11 10,3 13,3 13,5" />
<polygon style="fill: var(--roof-color-3)" points="10,11 7,5 7,3 10,3" />
</g>
</symbol>
</defs>
<g>
<rect fill="#999" width="100%" height="100%" />
<rect fill="url(#grid)" width="100%" height="100%" />
</g>
<g transform="scale(20, 20)">
<use xlink:href="#rooftop-0" class="theme-1" width="1" height="1" transform="translate(4, 2) rotate(0,0.5,0.5)"/>
<use xlink:href="#rooftop-1" class="theme-0" width="1" height="1" transform="translate(5, 2) rotate(90,0.5,0.5)"/>
<use xlink:href="#rooftop-0" class="theme-1" width="1" height="1" transform="translate(6, 2) rotate(180,0.5,0.5)"/>
</g>
</svg>
I hope this is what you were asking: The symbol has now a wiewBox attribute: viewBox="0 0 20 20" This means that the symbol has a width of 20 units and a height of 20 units. Now you can use the symbol like this:
<use xlink:href="#rooftop-0" width="20" height="20" x="63" y="21" />
As you can see I can give the symbol a width and a height in this case width="20" height="20" but you can give it any size you need. Also you can use the x and y attributes to reposition the used symbol.
Now you can also rotate the use element around it's center by using transform="rotate(90,73,31)" This is rotating the element 90degs around the point {x:73,y:31}
<svg viewBox="0 0 211 211">
<style>
.grid-line {
fill: #DDD;
}
.grass-fill {
fill: #8C8;
}
.theme-0 {
--roof-color-0: #F44;
--roof-color-1: #F66;
--roof-color-2: #F88;
--roof-color-3: #FAA;
}
.theme-1 {
--roof-color-0: #44F;
--roof-color-1: #66F;
--roof-color-2: #88F;
--roof-color-3: #AAF;
}
</style>
<defs>
<pattern id="grid" width="21" height="21" patternUnits="userSpaceOnUse">
<rect class="grid-line" x="0" y="0" width="1" height="21" />
<rect class="grid-line" x="0" y="0" width="21" height="1" />
</pattern>
<symbol id="rooftop-0" viewBox="0 0 20 20">
<g class="tile">
<rect class="grass-fill" width="20" height="20" />
<polygon style="fill: var(--roof-color-0)" points="3,2 17,2 18,8 2,8" />
<polygon style="fill: var(--roof-color-1)" points="2,8 18,8 17,14 3,14" />
<polygon style="fill: var(--roof-color-2)" points="8,8 11,14 11,18 8,18" />
<polygon style="fill: var(--roof-color-3)" points="8,8 8,18 5,18 5,14" />
</g>
</symbol>
</defs>
<g>
<rect fill="#999" width="100%" height="100%" />
<rect fill="url(#grid)" width="100%" height="100%" />
</g>
<g transform="translate(1, 1)">
<use x="42" y="21" xlink:href="#rooftop-0" class="theme-1" width="20" height="20" />
<use x="63" y="21" xlink:href="#rooftop-0" class="theme-0" width="20" height="20" transform="rotate(90,73,31)" />
</g>
</svg>
I have an SVG with four coloured blocks that I want to clip by a rotated ellipse. It works as expected in Chrome and Safari, but Firefox (63.0.3 on Mac) ignores the transformation of the ellipse.
Here is a CodePen that illustrates the issue.
SVG
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 500 500">
<defs>
<clipPath id="myClip">
<ellipse id = "ellipse" cx="250" cy="250" rx="200" ry="100" />
</clipPath>
</defs>
<g class="clip-this">
<rect class="color-1" x="0" y="0" width="250" height="250" />
<rect class="color-2" x="250" y="0" width="250" height="250" />
<rect class="color-3" x="0" y="250" width="250" height="250" />
<rect class="color-4" x="250" y="250" width="250" height="250" />
</g>
</svg>
CSS
#ellipse{
transform:rotate(-30deg);
transform-origin:center;
}
.color-1,.color-4{
fill:#ababab;
}
.color-2,.color-3{
fill:#3a3a3a;
}
svg {
max-width: 400px;
}
.clip-this{
clip-path: url(#myClip);
}
This is a known bug. As a workaround, you can use the SVG transform attribute instead of the CSS property. Note that for full browser compatibility the transform function must not have units for the numbers, and the center of rotation is noted in userspace coordinates.
.color-1,.color-4{
fill:#ababab;
}
.color-2,.color-3{
fill:#3a3a3a;
}
svg {
max-width: 400px;
}
.clip-this{
clip-path: url(#myClip);
}
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 500 500">
<defs>
<clipPath id="myClip">
<ellipse id = "ellipse" cx="250" cy="250" rx="200" ry="100" transform="rotate(-30, 250, 250)" />
</clipPath>
</defs>
<g class="clip-this">
<rect class="color-1" x="0" y="0" width="250" height="250" />
<rect class="color-2" x="250" y="0" width="250" height="250" />
<rect class="color-3" x="0" y="250" width="250" height="250" />
<rect class="color-4" x="250" y="250" width="250" height="250" />
</g>
</svg>
I have an svg rect chart like:
<div style="width:300px;height:300px;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="width:100%;height:100%" viewBox="0 0 300 300">
<g>
<rect width="14.55" height="40%" x="0" y="0" fill="black"></rect>
<rect width="14.55" height="20%" x="50" y="0" fill="green"></rect>
<rect width="14.55" height="80%" x="100" y="0" fill="red"></rect>
<rect width="14.55" height="90%" x="150" y="0" fill="yellow"></rect>
<rect width="14.55" height="10%" x="200" y="0" fill="pink"></rect>
<rect width="14.55" height="60%" x="250" y="0" fill="orange"></rect>
</g>
</svg>
</div>
What I want to do is to display it upside down.
The code and a given solution, are coming from http://jsfiddle.net/rhvP8/5/
Although, I want to keep each bar in the same X place. So, rotation approach is not that useful in this case.
Any help is welcome.
Rotation of the x-axis only seems be be what you require.
svg {
border: 1px solid green;
transform: rotateX(180deg);
}
<div style="width:300px;height:300px;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="width:100%;height:100%" viewBox="0 0 300 300">
<g>
<rect width="14.55" height="40%" x="0" y="0" fill="black"></rect>
<rect width="14.55" height="20%" x="50" y="0" fill="green"></rect>
<rect width="14.55" height="80%" x="100" y="0" fill="red"></rect>
<rect width="14.55" height="90%" x="150" y="0" fill="yellow"></rect>
<rect width="14.55" height="10%" x="200" y="0" fill="pink"></rect>
<rect width="14.55" height="60%" x="250" y="0" fill="orange"></rect>
</g>
</svg>
</div>