I want to use the same svg, but instead want the half circle svg to be rotated 90 degrees. How do I do this? Thanks.
<svg width="100" height="100">
<circle cx="50" cy="50" r="50" fill="grey" />
<path d="M0,50 a1,1 0 0,0 100,0" fill="orange" />
</svg>
SVG syntax
must not use units in the rotate() function
can state the rotation center only as part of the attribute
<svg width="100" height="100">
<circle cx="50" cy="50" r="50" fill="grey" />
<path d="M0,50 a1,1 0 0,0 100,0" transform="rotate(90, 50 50)" fill="orange" />
</svg>
CSS syntax
must use units for rotate() function and transform origin
can state the rotation center only as CSS transform-origin
path {
transform: rotate(90deg);
transform-origin: 50px 50px;
}
<svg width="100" height="100">
<circle cx="50" cy="50" r="50" fill="grey" />
<path d="M0,50 a1,1 0 0,0 100,0" fill="orange" />
</svg>
To use the same SVG (which is what is desired and differentiates this answer from other answers) you can reference the original SVG from a <use> element in a new SVG and apply a CSS rotation.
.rotate90 {
transform: rotate(90deg);
}
<svg id="mySVG" width="100" height="100">
<circle cx="50" cy="50" r="50" fill="grey" />
<path d="M0,50 a1,1 0 0,0 100,0" fill="orange" />
</svg>
<svg class="rotate90" width="100" height="100">
<use href="#mySVG"/>
</svg>
Related
I'm able to move an object along a Bezier Curve but am having some difficulty with 'defs' and 'use'. My object (circle) appears at 0,0 before the animation begins, then appears in the correct position.
<svg viewBox="0 0 500 300" style="border:1px solid black; width:500; height:500;" xmlns="http://www.w3.org/2000/svg" >
<path id="track" d="M100,200 C200,150 300,250 400,200" stroke-width="3" stroke="#000" fill="none"/>
<circle id="circ1" r="10" cx="0" cy="0" fill="red" >
<animateMotion begin="1s" dur="6s" fill="freeze">
<use href="#circ1" cx="100" cy="200"/>
<mpath xlink:href="#track"/>
</animateMotion>
</circle>
</svg>
How can I make it appear at the beginning of the Bezier line, not at 0,0?
You can use <set> elements to set the position of the circle at the begining of the curve. Next at 1s you need to set again the position of the circle on 0,0
<svg viewBox="0 50 500 300" style="border:1px solid black; width:500; height:300;" xmlns="http://www.w3.org/2000/svg" >
<path id="track" d="M100,200 C200,150 300,250 400,200" stroke-width="3" stroke="#000" fill="none"/>
<circle id="circ1" r="10" cx="0" cy="0" fill="red">
<set begin="0" attributeName="cx" to="100" />
<set begin="0" attributeName="cy" to="200" />
<set begin="1s" attributeName="cx" to="0" />
<set begin="1s" attributeName="cy" to="0" />
<animateMotion begin="1s" dur="6s" fill="freeze">
<!--<use href="#circ1" cx="100" cy="200"/>-->
<mpath xlink:href="#track"/>
</animateMotion>
</circle>
</svg>
Yet another solution would be changing the origin of the curve so that it begins in the 0,0.
Please observe that I've changed the value of the viewBox attribute so that you can still see the curve in the middle of the svg canvas.
<svg viewBox="-100 -150 500 300" style="border:1px solid black; width:500; height:300;" xmlns="http://www.w3.org/2000/svg" >
<path id="track" d="M0,0C100,-50,200,50,300,0" stroke-width="3" stroke="#000" fill="none"/>
<circle id="circ1" r="10" cx="0" cy="0" fill="red" >
<animateMotion begin="1s" dur="6s" fill="freeze">
<!--<use href="#circ1" cx="100" cy="200"/>-->
<mpath xlink:href="#track"/>
</animateMotion>
</circle>
</svg>
I need to draw an indeterminate number of circles in SVG like if they were a single shape. Making all circles have the same fill color does not work because I need those circles to have a filter applied in them, like in the picture, and as you can see the overlapping areas are in a different color.
<pattern
id="diagonalHatch"
patternUnits="userSpaceOnUse"
width="1"
height="3"
patternTransform="rotate(-45 2 2)">
<path
d="M -1,2 l 6,0"
[attr.stroke]="'#' + color"
stroke-width=".5"
/>
</pattern>
<ng-container *ngFor="let cone of cones, index as i">
<svg:circle
fill="url(#diagonalHatch)"
[attr.cx]="scaleX * (offset + cone.cX)"
[attr.cy]="cone.cY"
[attr.r]="scaleX * radius"
/>
</ng-container>
Result I am getting
Result I need
I suppose that what you have right now is something like this where due to the semitransparency of the pattern you can see the overlapped parts as darker:
<svg viewBox="0 0 100 50" width="400">
<pattern
id="diagonalHatch"
patternUnits="userSpaceOnUse"
width="1"
height="3"
patternTransform="rotate(-45 2 2)">
<path
d="M -1,2 l 6,0"
stroke="rgba(0, 100, 100, .3)"
stroke-width="0.5"
/>
</pattern>
<g>
<circle fill="url(#diagonalHatch)" r="20" cx="25" cy="25"/>
<circle fill="url(#diagonalHatch)" r="20" cx="50" cy="25"/>
<circle fill="url(#diagonalHatch)" r="20" cx="75" cy="25"/>
</g>
</svg>
As a possible solution you could use the circles as a clipping path and clip a rectangle the size of the svg canvas like so:
<svg viewBox="0 0 100 50" width="400">
<pattern
id="diagonalHatch"
patternUnits="userSpaceOnUse"
width="1"
height="3"
patternTransform="rotate(-45 2 2)">
<path
d="M -1,2 l 6,0"
stroke="rgba(0, 100, 100, .3)"
stroke-width="0.5"
/>
</pattern>
<clipPath id="c">
<circle r="20" cx="25" cy="25"/>
<circle r="20" cx="50" cy="25"/>
<circle r="20" cx="75" cy="25"/>
</clipPath>
<rect fill="url(#diagonalHatch)" width="100" height="50" clip-path="url(#c)"/>
</svg>
Is there a way to cut off a path when it is outside of a circle?
<svg width="100" height="100">
<circle cx="50" cy="50" r="50" fill="red" />
<path d="M0 0 L100 100" stroke-width="1px" stroke="black" />
</svg>
Is it possible to make that line stay inside the circle (and not be visible off of the circle) without changing the d="M200 175 L696 880" in the path?
You can use a clipPath to prevent things drawing outside another shape.
<svg width="100" height="100">
<clipPath id="clip">
<circle cx="50" cy="50" r="50" fill="red" />
</clipPath>
<circle cx="50" cy="50" r="50" fill="red" />
<path d="M0 0 L100 100" stroke-width="1px" stroke="black" clip-path="url(#clip)"/>
</svg>
I am displaying a diagrammatic map using SVG and it must be proportional (i.e., not skewed x/y).
The image fills the whole screen so the outer item is always 100%/100%. In other words I want the viewport to always fill the browser windows (within the constraints of aspect ratio), for example:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events" >
<defs>
<solidColor xml:id="solidBlack" solid-color="black" />
<solidColor xml:id="solidLightGray" solid-color="lightgrey" />
</defs>
<style>
.Border { fill:none; stroke:red; stroke-width="2px" }
.TitleBlock { fill:none; stroke:black; stroke-width="1px" }
</style>
<svg x="0" y="0" width="100%" height="100%" viewbox="0 0 1000 1000" >
<rect x="2" y="2" width="99%" height="99%" class="Border" />
<svg viewbox="500 500 500 500">
<circle cx="30" cy="20" r="10px" fill="red" />
<circle cx="450" cy="30" r="10px" fill="blue" />
<circle cx="40" cy="490" r="10px" fill="green" />
</svg>
</svg>
</svg>
When this renders, the values are being interpreted as pixels, not user coordinates. So, for example, the green dot should be near the bottom of the screen (since it is at the bottom of the viewbox) but in actuality it is in the middle of the screen because it is interpreting 490 as 490 pixels.
To further clarify, the 1000 x 1000 dimensions of the total map area are user coordinates. For example, suppose I am making a space game and the game area is 1000 parsecs x 1000 parsecs. Any particular view of this map area should fill the screen.
Update
Based on the answer one fundamental problem is that to fill the screen I need to use 100% in the outer svg element. However, even after doing this, the image is not zooming in and using user coordinates:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
width="100%" height="100%"
viewBox="0 0 100000 100000" >
<defs>
<solidColor xml:id="solidBlack" solid-color="black" />
<solidColor xml:id="solidLightGray" solid-color="lightgrey" />
</defs>
<style>
.Border { fill:none; stroke:red; stroke-width="2px"; }
.TitleBlock { fill:none; stroke:black; stroke-width="1px"; }
}
</style>
<rect y="2" width="100%" height="100%" class="Border" />
<svg viewBox="50000 50000 100000 100000" >
<circle cx="52000" cy="52000" r="10px" fill="red" />
<circle cx="95000" cy="53000" r="10px" fill="blue" />
<circle cx="54000" cy="99000" r="10px" fill="green" />
</svg>
</svg>
This does not even appear at all, indicating it is using PIXELS not user coordinates.
I think you might be confused about how viewBox works. It describes the bounds of the document that should be scaled to fit the viewport (width & height). It doesn't perform a transform.
Your viewBox of "500 500 500 500" describes the area (500,500) -> (1000,1000). So your coordinate of (10,490) will normally end up way outside the viewport.
Having said that, it is not at all clear what you are actually trying to achieve with your nested set of <svg> elements.
I'm going to assume you are wanting to display a portion of your 1000x1000 world map so it fills the screen? Lets' start by simplifying your original SVG.
.Border { fill:none; stroke:red; stroke-width="2px" }
.TitleBlock { fill:none; stroke:black; stroke-width="1px" }
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
width="100%" height="100%"
viewBox="0 0 1000 1000">
<defs>
<solidColor xml:id="solidBlack" solid-color="black" />
<solidColor xml:id="solidLightGray" solid-color="lightgrey" />
</defs>
<rect x="2" y="2" width="99%" height="99%" class="Border" />
<circle cx="30" cy="20" r="10px" fill="red" />
<circle cx="450" cy="30" r="10px" fill="blue" />
<circle cx="40" cy="490" r="10px" fill="green" />
</svg>
Here we are displaying the whole world map in an SVG that is 100%x100%. Due to the way percentage width/height values are processed for SVGs and because the viewBox is square. This normally results in an SVG that is 100% width and whose height is equivalent to the width, resulting in an SVG that may end up off the bottom of the page.
If you want the SVG viewport to match the screen exactly you should use a width/height in pixels, not percents. For the sake of fitting in the snippet window, let's choose a tiny screen of 512x384 (1/2 of a 1024x768 screen).
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="512" height="384"
viewBox="0 0 1000 1000">
<rect x="-50%" y="-50" width="200%" height="200%" fill="#ffc"/>
<rect x="2" y="2" width="99%" height="99%" fill="none" stroke="red" stroke-width="2" />
<circle cx="30" cy="20" r="10px" fill="red" />
<circle cx="450" cy="30" r="10px" fill="blue" />
<circle cx="40" cy="490" r="10px" fill="green" />
</svg>
Here I've also added a light yellow rectangle to show the dimensions of the viewport (screen) and how the viewBox has resulted in the "world" being scaled to fit the screen.
If you want the world to fill the screen and not have the blank areas to the left and right you need to change the preserveAspectRatio attribute. By default it is set to xMidYMid meet which means scale the viewBox area up to neatly fit the viewport and centre it. If we change it to xMidYMid slice, it will scale it up to fill the widest part of the viewport. That results in the top and bottom of your "world" going off screen.
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="512" height="384"
viewBox="0 0 1000 1000"
preserveAspectRatio="xMidYMid slice">
<rect x="-50%" y="-50" width="200%" height="200%" fill="#ffc"/>
<rect x="2" y="2" width="99%" height="99%" fill="none" stroke="red" stroke-width="2" />
<circle cx="30" cy="20" r="10px" fill="red" />
<circle cx="450" cy="30" r="10px" fill="blue" />
<circle cx="40" cy="490" r="10px" fill="green" />
</svg>
Now, if you want to view a portion of your "world", for example the top left, you would set the viewBox to "0 0 500 500". If you want to see the whole of that area, use `preserveAspectRatio="xMidYMid meet":
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="512" height="384"
viewBox="0 0 500 500"
preserveAspectRatio="xMidYMid meet">
<rect x="-50%" y="-50" width="200%" height="200%" fill="#ffc"/>
<rect x="2" y="2" width="99%" height="99%" fill="none" stroke="red" stroke-width="2" />
<circle cx="30" cy="20" r="10px" fill="red" />
<circle cx="450" cy="30" r="10px" fill="blue" />
<circle cx="40" cy="490" r="10px" fill="green" />
</svg>
If you don't want to see parts of the world outside of that 500x500 area, and can live with part of it being offscreen, use xMidYMid slice.
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="512" height="384"
viewBox="0 0 500 500"
preserveAspectRatio="xMidYMid slice">
<rect x="-50%" y="-50" width="200%" height="200%" fill="#ffc"/>
<rect x="2" y="2" width="99%" height="99%" fill="none" stroke="red" stroke-width="2" />
<circle cx="30" cy="20" r="10px" fill="red" />
<circle cx="450" cy="30" r="10px" fill="blue" />
<circle cx="40" cy="490" r="10px" fill="green" />
</svg>
Here, your three circles end up just off screen.
Does this help?
I want to hide anything that outside a rectangle. (this i have achieved with clipping successfully). but another condition is that, 'also hide anything that comes inside the black big circle'. Now how i can achieve that?
in below example, 'yellow circle' must be eliminated'.
see below images for detail
Original:-
Desired:-
Below is my Svg code:-
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="500" height="500">
<g>
<rect x="50" y="50" width="200" height="200" stroke="1" fill="red"/>
<circle cx="180" cy="150" r="30" stroke="blue" />
</g>
<g clip-path = "url(#clip1)">
<circle cx="180" cy="150" r="10" stroke="blue" fill="yellow" />
</g>
<clipPath id = "clip1">
<rect x="50" y="50" width="200" height="200" stroke="1" fill="red"/>
</clipPath>
</svg>
Erik Dahlström is right, your clip can include the entire rectangle and the cutout for the circle. This way, anything you associate with #clip1 as the clip-path will not be visible inside your circle area. Here is what it looks like for your example:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="500" height="500">
<g>
<rect x="50" y="50" width="200" height="200" stroke="1" fill="red"/>
<circle cx="180" cy="150" r="30" stroke="blue" />
</g>
<g clip-path = "url(#clip1)">
<circle cx="180" cy="150" r="10" stroke="blue" fill="yellow" />
</g>
<clipPath id = "clip1">
<path d="M 50,50 l200 0 l0 200 l-200 0z M150,150 a30,30 1 0,0 60,0z M210,150 a30,30 1 0,0 -60,0z"/>
</clipPath>