I don't quite understand the transform-origin CSS rule.
If you have a plain <svg> with changing sizes (width, height) and some <rect> elements in it, how can you rotate a <g> element in it correctly?
It should be right next to the <rect>, so I am using transform: translate(x,y).
Then I'd like to rotate the group with rotate(45), but it ends up at strange places:
HTML
<div class="box">
<svg class="svg-main" width="600px" height="600px">
<rect x="0" y="50" width="90" height="40" fill="blue" stroke="blue"></rect>
<g transform="translate(100,50),rotate(7)"
transform-origin="center"
class="group">
<path d="M38.15,20.54,28.9,11.29a1.4,1.4,0,0,0-2.4,1v1.89a1.41,1.41,0,0,1-1.4,1.41H3.2A1.4,1.4,0,0,0,1.79,17v9.11a1.41,1.41,0,0,0,1.41,1.4H25.1a1.41,1.41,0,0,1,1.4,1.41v1.89a1.41,1.41,0,0,0,2.4,1l9.25-9.25A1.41,1.41,0,0,0,38.15,20.54Z" stroke="#000" strokeMiterlimit="10" strokeWidth="2"/>
</g>
</svg>
</div>
CSS
div.box {
padding: 30px;
background-color: #dfcfcf;
}
svg.svg-main {
background-color: white;
border: 2px solid #dedada;
}
svg.svg-main g.group path {
fill: rgba(215, 20, 45, 0.5);
}
JSFiddle
https://jsfiddle.net/bair_web/ajLgzoey/
Result for 17deg
Where is the origin?
Question
I would like to rotate the group with its <path> and using center for transform-origin.
MDN
How can I achieve a simple, centered rotation of a group in an SVG, which is also translated? It seems like transform-origin points to the parent element (the SVG)? So do I need to calculate the position of the<g> element relative to the <svg> elment and use it for transform-origin?
Because, when I just omit the origin, the rotated group also moves around and does not keep its center.
I have a large svg image that will be scrolled. I would like to add a tiled background image behind all the elements. This is currently leaving me with two problems:
I haven't found a way to keep a background image fixed, and not scroll it with the svg elements on top of it.
Assuming that's not possible, I wanted to size the tile elements to occupy 20% of the viewable area rather than 20% of the total svg size.
<svg width="3560.00px" height="1350.00px" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<pattern id="G-BG" width="20.00%" height="20.00%">
<image xlink:href="https://static.vecteezy.com/system/resources/thumbnails/000/301/800/small/jfyo_waxi_190121.jpg" x="0" y="0" width="20.00%" height="20.00%"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#G-BG)" fill-opacity="0.20"/>
<circle fill="green" cx="200" cy="200" r="100.00"/>
</svg>
If you run this little example, it sets a background composed of 5 x 5 copies of some arbitrary image, but the repeat interval of the tiling is based on 20% of the full svg size. If I try and use vw/vh units then the pattern size seems to go to zero, and so disappear.
My ideal choice would be to have a fixed 5 x 5 image that doesn't scroll, but the CSS background support doesn't seem to work for for svg.
My second choice would be to have a scrolling background image, but where there are 5 x 5 tiles visible at any one time.
Can either of these goals be achieved?
Not sure if there is anything here that might help?
html,body{
height: 100%;
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper{
width: 100%;
height: 100%;
}
.wrapper svg{
background-color: 'red';
top: 0;
left:0;
position: fixed;
width: 100%;
height: 100%;
}
<div class="wrapper">
<svg xmlns="http://www.w3.org/2000/svg" >
<pattern id="pattern" width="0.2" height="0.25" viewBox="0 0 1 1" preserveAspectRatio="xMidYMid meet">
<image width="0.5" height="0.5" href="https://static.vecteezy.com/system/resources/thumbnails/000/301/800/small/jfyo_waxi_190121.jpg" />
</pattern>
<rect x="0" y="0" width="100%" height="100%" fill="url(#pattern)"></rect>
</svg>
</div>
Why is this SVG image displayed at 150px height inside this 500px container? Why this specific value?
I found this weird behavior in both js bin and Codepen, so I think it is something to do with my code and not with the online editors.
Note: a 700px div container results in the same thing. So the height of the parent doesn't matter.
<div style="padding: 30px; background-color: yellow; height: 500px; width: 500px; ">
<svg>
<pattern id="basicPattern" x="10" y="10" width="40" height="40" patternUnits="userSpaceOnUse" >
<rect x= "0" y="0" width="4" height="4"
stroke = "red"
stroke-width = "1"
fill = "black"/>
</pattern>
<!-- <rect x="0" y="0" width="300" height="151" // why this deletes the bottom line? -->
<!-- <rect x="0" y="0" width="300" height="150" // why this deletes 1 px from the bottom line? -->
<!-- but this height="149" is the bottom limmit for this picture..
what prevent's it bor beeing extended further - we have unthil 500 px as you can see on the div.-->
<rect x="0" y="0" width="300" height="149"
stroke= "red"
stroke-width="2"
fill="url(#basicPattern)" />
</svg>
This is Jsbin and this is CodePen.
You didn't set the SVG width and height, so it goes to the default size of 300px width x 150px height (for some user-agents).
Here is your JSBin with the SVG width and height both set to 500px. Now the rectangle can go beyond 150px of height: https://jsbin.com/yafenemawe/1/edit?html,output
I'm working with an SVG that I don't want the stroke of <circle> to scale when resized. What happens when I add vector-effect="non-scaling-stroke" to the <circle> is that now the circumference becomes based on the viewport and not the original viewBox. This is a problem because when using stroke-dasharray for an animation, it's referencing the wrong circumference.
The following snippet shows a stroke-dasharray set to the circumference of two circles of the same size and the right circle showing the problem (using the viewport; effectively doubling its circumference):
svg {
width: 400px;
height: auto;
fill: none;
stroke: #000;
stroke-width: 6;
stroke-dasharray: 252
}
<body>
<svg viewBox="0 0 200 100">
<circle cx="50" cy="50" r="40" />
<circle cx="150" cy="50" r="40" vector-effect="non-scaling-stroke" />
</svg>
</body>
Is there any way to tell the <circle> to respect the viewBox and not the viewport?
This is what happens when you specify non-scaling stroke: it's "not-scaling" the "dash" in the stroke as well as the stroke itself. If you had a normal stroke dash array (rather than using it as an animation hack) - this is the behavior you would want :) There is currently no way to specify a different coordinate system just for the dash-array calculation, so javascript is your friend.
I've created some svg graphics that I would like to set as backgrounds in some variable height divs. I'm trying to use them as a sprite, so one svg file has a few groups, each with its own id, and I'm using those ids to specify which background is rendered in each div.
Here's a link to a (non-working) JSFiddle.
HTML:
<svg width="0" height="0">
<defs>
<!-- BLUE GRAPHIC -->
<g id="blue_background">
<polygon fill="#C8D9E5" points="[...in the fiddle...]"/>
</g>
<!-- GREEN GRAPHIC -->
<g id="green_background">
<path fill="#49B974" d="[...in the fiddle...]"/>
</g>
</defs>
</svg>
<div class="box">
<h1>asdasdasd</h1>
<h1>asdasdasd</h1>
<h1>asdasdasd</h1>
<svg class="svg1" viewBox="0 0 600 200" >
<use xlink:href="#blue_background" width="100%" height="100%"></use>
</svg>
</div>
<div class="box">
<h1>asdasdasd</h1>
<h1>asdasdasd</h1>
<h1>asdasdasd</h1>
<svg class="svg2" viewBox="0 0 200 200">
<use xlink:href="#green_background" width="100%" height="100%"></use>
</svg>
</div>
Ideally the graphic would be aligned with the right side, and stretch to fill the div's height.
Thanks
Since you're describing your SVGs as "backgrounds", I assume you don't need them to push text out of the way.
In that case, I would recommend using absolute positioning for the SVGs (relative to the "box" containers). With absolute positioning, a height of 100% is valid even if the parent element doesn't have fixed height.
.box {
position: relative;
width: 400px;
border: 1px solid #ddd;
}
svg {
position:absolute;
height:100%;
top:0; right:0;
z-index:-1;
}
http://jsfiddle.net/svag2/1/