How to set the common background In SVG? - svg

How to set the common background for all svg?
<svg>
<g id="dsfdf">
-----------
</g>
<g id="dsfgfdgdf">
-----------
</g>
</svg>
How to set the common background for G tags. Please any one help

By specifying the fill in the svg element itself, you can always specify another color in the containing elements, like the red circle on the first position in the sample.
<svg fill="green" id="svg1" xmlns="http://www.w3.org/2000/svg" style="width: 3.5in; height: 1in">
<circle id="circle1" r="30" cx="100" cy="34" style="fill: red; stroke: blue; stroke-width: 2"/>
<circle id="circle2" r="30" cx="200" cy="34"/>
<circle id="circle3" r="30" cx="300" cy="34"/>
</svg>

Related

SVG patterns scaling the way pattern is not cut off

I'm trying to discover the way to scale svg patterns so that the pattern is not cut by the bounds of the element using it. And yet so that pattern is beeing repeated to cover that element.
Let's say i have a 20px radius circle as a pattern.
Applying it to 80px width element:
Now the element is beeing scaled to 90px, the pattern should stretch horizontally (no need to keep aspect ratio):
And at last, scale up above 90px adds another circle occurance (95px width in this example - aspect ratio is still ignored):
I can add some scripting to achieve that effect. But i'm curious about if i can get that behavior with pure SVG.
<svg style='display: block; height: 60px; width: 95px; '>
<defs>
<pattern patternUnits='userSpaceOnUse' viewBox='0 0 20 20' width='20' height='20' id='the_pattern'>
<circle cx='10' cy='10' r='10' stroke-width='0' fill='black'></circle>
</pattern>
</defs>
<rect x='0' y='0' width='80' height='20' fill='url(#the_pattern)'></rect>
<rect x='0' y='20' width='90' height='20' fill='url(#the_pattern)'></rect>
<rect x='0' y='40' width='95' height='20' fill='url(#the_pattern)'></rect>
</svg>
The answer is no. You cannot achieve that with pure SVG. Unless by "pure SVG" you include SVGs that have embedded Javascript (ie <script> elements).
You could do it with CSS border-image though.
https://developer.mozilla.org/en-US/docs/Web/CSS/border-image
Here's an example:
Ignore the fact that I've used a diamond image here. Just replace it with a circle version of the border image file. :)
.circle-border {
border-top: 30px solid;
border-image: url('https://interactive-examples.mdn.mozilla.net/media/examples/border-diamonds.png') 30 / 20px 0 0 0;
border-image-repeat: round;
}
div {
width: 80px;
height: 0px;
margin-bottom: 50px;
}
div:nth-child(2) {
width: 90px;
}
div:nth-child(3) {
width: 100px;
}
<div class="circle-border"></div>
<div class="circle-border"></div>
<div class="circle-border"></div>
Idea
You set the dimension of the container elements in 2 passes.
Pass 1:
Set the width of the container element to the value such that the desired number of pattern elements would just fit in horizontally. That would be 80 for the first two cases and 100 for the last.
Pass 2:
Scale the container elements horizontally to the actual target widths ( 80, 90, 95 ).
In the code example below, the transform attribute specifies the scaling. Note that the translate verbs first shift the element position to the origin before scaling is applied and revert the translation thereafter (the verbs inside the `translate attribute are evaluated from right to left).
The x scaling factor is the quotient of target width and specified width, y just leaves the height as it is.
SVG Sample
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="8cm" height="4cm" viewBox="0 0 800 500" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<defs>
<pattern id="circlePattern" patternUnits="userSpaceOnUse"
x="0" y="0" width="20" height="20"
>
<circle cx="10" cy="10" r="10" fill="black" stroke="black" stroke-width="0"/>
</pattern>
</defs>
<!-- 1. base case 80 px width -->
<rect fill="url(#circlePattern)" stroke="white" stroke-width="0"
x="100" y="200" width="80" height="20"
/>
<!-- 2. scale width to 90px -->
<rect fill="url(#circlePattern)" stroke="white" stroke-width="0"
x="100" y="300" width="80" height="20"
transform="translate(100, 300) scale (1.125, 1.0) translate(-100, -300)"
/>
<!-- 3. scale width to 95px -->
<rect fill="url(#circlePattern)" stroke="white" stroke-width="0"
x="100" y="400" width="100" height="20"
transform="translate(100, 400) scale (0.95, 1.0) translate(-100, -400)"
/>
</svg>
Inline Sample
The SVG parts pertaining to the question is the same as above.
.showcase {
/* background-image: url('#glyph');
background-size:100% 100%;*/
filter: url(#embedded);
}
.showcase:before {
display:block;
content:'';
color:transparent;
}
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg id="embedded" width="16cm" height="8cm" viewBox="0 0 800 500" version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<pattern id="circlePattern" patternUnits="userSpaceOnUse"
x="0" y="0" width="20" height="20"
>
<circle cx="10" cy="10" r="10" fill="black" stroke="black" stroke-width="0"/>
</pattern>
</defs>
<!-- 1. base case 80 px width -->
<rect fill="url(#circlePattern)" stroke="white" stroke-width="0"
x="100" y="200" width="80" height="20"
/>
<!-- 2. scale width to 90px -->
<rect fill="url(#circlePattern)" stroke="white" stroke-width="0"
x="100" y="300" width="80" height="20"
transform="translate(100, 300) scale (1.125, 1.0) translate(-100, -300)"
/>
<!-- 3. scale width to 95px -->
<rect fill="url(#circlePattern)" stroke="white" stroke-width="0"
x="100" y="400" width="100" height="20"
transform="translate(100, 400) scale (0.95, 1.0) translate(-100, -400)"
/>
</svg>
<div id="showcase"/>

Chartist.js, SVG circle element is not showing up in the container

I'm using Chartist.js to work on a pie chart.
I am trying to add a simple circle in the background, but for some reason the circle element just ends up in the top left corner with 0x0 dimensions.
Here is the SVG:
<div class="contents" id="chart-container">
<svg xmlns:ct="http://gionkunz.github.com/chartist-js/ct" width="100%" height="100%" class="ct-chart-pie" style="width: 100%; height: 100%;" viewBox="0 0 359 219">
<g class="basecircle">
<cirlce class="basecircleelement" cx="10" cy="10" fill="black" cr="181.76999999999998">
</cirlce>
</g>
<g ct:series-name="value" class="ct-series ct-series-a">
<path d="M147.071,10.108A104.375,104.375,0,1,0,179.325,5L179.325,109.375Z" class="ct-slice-pie" ct:value="95" style="fill: gray; stroke: white; stroke-width: #fff;"></path>
</g>
<g ct:series-name="rest" class="ct-series ct-series-b">
<path d="M179.325,5A104.375,104.375,0,0,0,146.725,10.222L179.325,109.375Z" class="ct-slice-pie" ct:value="5" style="fill: transparent;"></path>
</g>
</svg>
</div>
I expected the "g.basecircle" and "circle.basecircleelement" should be showing up(It's supposed to be in the center of the container but I didn't calculate the cx and cy yet) with radius of 181.76999999999998 -this value is calculated to be half of the clientWidth-, but it ends up in the upper left corner of the SVG element with dimension of 0 x 0
Is there anything I am missing?
this value is calculated to be half of the clientWidth-, but it ends
up in the upper left corner of the SVG element with dimension of 0 x 0
Typos must be fixed:
circle instead ofcirlce
Radius designation -r instead ofcr
Svg canvas borders are bounded by a red square style = "border: 1px solid red;"
It is very convenient to visually see the borders of SVG. When you finish debugging your application, this line can be removed.
To place the black circle in the center of the svg canvas, you need to set the coordinates cx =" 359/2 " cy =" 219/2 "
<div class="contents" id="chart-container">
<svg xmlns:ct="http://gionkunz.github.com/chartist-js/ct" width="100%" height="100%" class="ct-chart-pie" viewBox="0 0 359 219" style="border:1px solid red;">
<g class="basecircle">
<circle class="basecircleelement" cx="179.5" cy="109.5" fill="black" r="179.5">
</circle>
</g>
<g ct:series-name="value" class="ct-series ct-series-a">
<path d="M147.071,10.108A104.375,104.375,0,1,0,179.325,5L179.325,109.375Z" class="ct-slice-pie" ct:value="95" style="fill: gray; stroke: white; stroke-width: #fff;"></path>
</g>
<g ct:series-name="rest" class="ct-series ct-series-b">
<path d="M179.325,5A104.375,104.375,0,0,0,146.725,10.222L179.325,109.375Z" class="ct-slice-pie" ct:value="5" style="fill: transparent;"></path>
</g>
</svg>
</div>
Update
If you want the black circle to not form and completely fit on the canvas svg you need to set its radius equal to half the height of the canvas r= 219 / 2 = 109.5
<div class="contents" id="chart-container">
<svg xmlns:ct="http://gionkunz.github.com/chartist-js/ct" width="100%" height="100%" class="ct-chart-pie" viewBox="0 0 359 219" style="border:1px solid red;">
<g class="basecircle">
<circle class="basecircleelement" cx="179.5" cy="109.5" fill="black" r="109.5">
</circle>
</g>
<g ct:series-name="value" class="ct-series ct-series-a">
<path d="M147.071,10.108A104.375,104.375,0,1,0,179.325,5L179.325,109.375Z" class="ct-slice-pie" ct:value="95" style="fill: gray; stroke: white; stroke-width: #fff;"></path>
</g>
<g ct:series-name="rest" class="ct-series ct-series-b">
<path d="M179.325,5A104.375,104.375,0,0,0,146.725,10.222L179.325,109.375Z" class="ct-slice-pie" ct:value="5" style="fill: transparent;"></path>
</g>
</svg>
</div>

SVG Use -- Unable to repostion polygon after rotation

I am trying to create a 16 point star inside a circle using SVG and pure CSS -- no JS!
My strategy is to create 16 equilateral triangles (via Defs and Use, to keep it DRY), rotating each Use iteration by 22.5 degrees.
My problem is that when I apply the rotate() transform to the second triangle, SVG changes the center point of the triangle -- which CSS3 does not (it rotates around a fixed axis).
I have tried adding x and y parameters, adding a class and doing a translate() transform, doing that inline... nothing works -- I just cant figure out how to move the triangle back into position (with a rotation) inside the circle (centered at 150, 150 I reckon).
Any help would be appreciated. Here is the SVG line of code that I am having trouble with.
<use xlink:href="#triangle" style="transform: rotate(22.5deg);" />
You can see it in action here.
<style > .toile {
display: flex;
flex-direction: column;
max-width: 400px;
max-height: 800px;
justify-content: center;
align-items: center;
/* centers outer containing element (the circle) horizontally & vertically */
border: 5px #009000;
/* green */
border-style: groove;
background-color: #f9e4b7;
margin: 0 auto;
/* centers surface on a page */
}
<div class="toile">
<svg>
<defs>
<pattern id="grid" width="15" height="15" patternUnits="userSpaceOnUse">
<rect fill="white" x="0" y="0" width="14" height="14"/>
<rect fill="#009000" x="14" y="0" width="1" height="14"/>
<rect fill="#009000" x="0" y="14" width="14" height="5"/>
</pattern>
<g id="triangle">
<svg>
<polygon points="150,18 200,100 100,100"
style="stroke:#009000;stroke-width:1; fill:#afeeee; opacity:.7" />
</svg>
</g>
</defs>
<rect fill="url(#grid)" x="0" y="0" width="100%" height="100%" />
<svg viewBox="0 100 400 400" stroke="#009000" stroke-width=".5" width="300" height="300" class="cercle">
<circle cx="50%" cy="50%" r="75" fill="transparent" /> </svg>
<svg viewBox="0 100 400 400" stroke="#ce2029" stroke-width=".5" width="300" height="300">
<circle cx="50%" cy="50%" r="2" fill="#ce2029" /> </svg>
<use xlink:href="#triangle" />
<use xlink:href="#triangle" style="transform: rotate(22.5deg);" />
</svg>
</div>
Thank you for any solution to this problem; I just can't figure it out! Please no JS solutions!
UPDATE:
I've changed the 16-point gon to a 15 point one, as for some reason a series of 22.5 degree rotations create an unbalanced hexadecagon. I got rid of the red circle center point, and the background grid, and added SVG animation. Here is the (final) working example.
Sorry about the CodePen but I am trying to figure out how to make snippets work for an entire HTML/CSS/SVG program.
This is one way of doing it:
First I simplified your code. Unless you have a good reason to do it like this, it's always better to keep things simple.
I calculated the points tor the triangle around the center of the svg canvas:
<polygon id="triangle" points="200,125 264.95,237.5 135.05,237.5"
I rotate the triangle using svg transforms: transform="rotate(22.5,200,200)"
The first value is the rotation in degs and next you have the x and y of the rotation center.
As it comes out with SVG transforms you don't have IE issues. Please read this article about Transforms on SVG Elements
.toile {
display: flex;
flex-direction: column;
max-width: 400px;
max-height: 800px;
justify-content: center;
align-items: center;
/* centers outer containing element (the circle) horizontally & vertically */
border: 5px #009000;
/* green */
border-style: groove;
background-color: #f9e4b7;
margin: 0 auto;
/* centers surface on a page */
}
<div class="toile">
<svg viewBox="0 0 400 400" stroke="#009000" stroke-width=".5" width="300" height="300" >
<defs>
<pattern id="grid" width="15" height="15" patternUnits="userSpaceOnUse">
<rect fill="white" x="0" y="0" width="14" height="14"/>
<rect fill="#009000" x="14" y="0" width="1" height="14"/>
<rect fill="#009000" x="0" y="14" width="14" height="5"/>
</pattern>
<polygon id="triangle" points="200,125 264.95,237.5 135.05,237.5"
style="stroke:#009000;stroke-width:1; fill:#afeeee; opacity:.7" />
</defs>
<rect fill="url(#grid)" x="0" y="0" width="100%" height="100%" />
<circle class="cercle" cx="50%" cy="50%" r="75" fill="transparent" />
<circle cx="50%" cy="50%" r="2" fill="#ce2029" />
<use xlink:href="#triangle" />
<use xlink:href="#triangle" transform="rotate(22.5,200,200)" />
</svg>
</div>
UPDATE
To calculate the points for the triangle you may use javascript. In the case of a regular polygon like a triangle all 3 vertices are on a circumscribed circle at a 2*Math.PI/3 angle one from each other. I'm starting with an offset of -Math.PI/2 (-90 degs) for the first vertex.
// the center of the SVG canvas calculated from the values of the viewBox attribute. Alternatively you can choose a different point
let c = {x:200,y:200}
let radius = 75;
let points = [];
for(let a = -Math.PI/2; a < 3*Math.PI/2; a+= 2*Math.PI/3){
let x = c.x + radius*Math.cos(a);
let y = c.y + radius*Math.sin(a);
points.push(x);
points.push(y);
}
tri.setAttributeNS(null, "points", points.join());
svg{border:1px solid;height:90vh}
<svg viewBox="0 0 400 400">
<polygon id="tri" />
</svg>

Growing svg with fixed-size elements?

I have an arrow SVG, set up like this one:
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 100 100" class="arrow">
<g class="tail">
<circle (...)></circle>
</g>
<g class="body">
<rect (...)></rect>
</g>
<g class="head">
<polygon (...)>
</g>
</svg>
And I want to set it up so that when resizing it via CSS, regardless of its size,
the tail will remain in the left hand side with the same proportions,
the head will stay in the right hand side, also with the same proportions, and
the body will stretch horizontally indefinitely.
Can I do that? How can I do that?
Basically, you can create such SVG graphics by using nested svg elements with relative positioning (%value of root svg element's size), like this.
svg{
overflow:visible;
}
svg.root{
width:200px;
height:100px;
margin:0 10px;
background-color:rgba(255,255,0,.5);
transition: 1s ease-in-out 0s;
}
svg.root:hover{
width:300px;
height:150px;
}
<svg class="root">
<svg class="tail" y="50%">
<circle r="10" fill="red"/>
</svg>
<svg class="head" x="100%" y="50%">
<polygon points="-10,-10 10,0 -10,10" fill="blue"/>
</svg>
<svg class="body" y="50%">
<rect x="0" y="-2" width="100%" height="4" fill="green"/>
</svg>
</svg>

SVG reuse a group but change fill color

So I have a <g> element with some <rect>s inside it, they all have same fill color, but can be of different sizes. I want to reuse the <g>, but fill it with a different color, is it possible?
I can change the markup any way I like.
You can define the rect group using <defs> like so:
<defs>
<g id="rect-group">
<rect x="0" y="0" width="60" height="30"/>
<rect x="20" y="10" width="20" height="50"/>
</g>
</defs>
Then you can use this group multiple times, putting it in different places with with transform if you like:
<g class="group-1" transform="translate(10.5,20.5)">
<use xlink:href="#rect-group" />
</g>
<g class="group-2" transform="translate(55.5,32.5)">
<use xlink:href="#rect-group" />
</g>
You can style these groups directly or give them different classes as above and use CSS to style as you like:
<style>
.group-1{
fill: red;
stroke: white;
}
.group-2{
fill: blue;
stroke: black;
}
</style>
For an example, see: http://dl.dropbox.com/u/169269/rect_group.svg

Resources