I want to define grouped shapes in the <def> section and display them via the <use> tag with the transformation-origin being the group's center. Following is a minimal example illustrating my issue:
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200">
<defs>
<g id="triangle">
<path fill="green" d="m 24 0 l 24 41.569 l -48 0 z" />
<circle cx="24" cy="24" r="1" fill="red" />
<rect width="48" height="41.569" fill="purple" fill-opacity="20%" />
</g>
</defs>
<rect width="100" height="100" />
<rect fill="gray" x="100" width="100" height="100" />
<rect width="100" height="100" />
<rect fill="gray" y="100" width="100" height="100" />
<rect width="100" height="100" x="100" y="100" />
<use href="#triangle" transform-origin="50% 50%" transform="translate(100 100)" />
</svg>
As it is my understanding, the triangle should be centered in the background. But in actuality, the top left corner of the group is centered.
I have tested my example against the MDN transform-origin one. The MDN one works well in the same environment (Edge Browser & VSCode). This lets me believe I am missing some side effects of the used tags or attributes
Observed behavior
Expected behavior
A scale transform has a centre point i.e. a point that doesn't change position.
So does a rotation - there's a centre of rotation.
A translate transform does not, every location moves. There's therefore no origin so transform-origin does nothing.
I want to center the rect shape with something equivalent to
transform="translate(50% - 100,0)" for example:
<svg width="100%" height="100%" viewbox="0 0 100% 100%">
<g transform="translate(50% - 100,0)">
<rect width="200" height="100" fill="rgb(0,0,255)" />
</g>
</svg>
I can't find the right syntax.
You can use an inner <svg> element to do the percentage part via its x attribute then the rest with the <g> element as you already have.
I'm not sure what you intend with the viewBox but percentage values are not valid there. Looks like you just don't need that at all.
<svg width="100%" height="100%">
<svg x="50%" overflow="visible">
<g transform="translate(-100,0)">
<rect width="200" height="100" fill="rgb(0,0,255)" />
</g>
</svg>
</svg>
I have some SVG elements grouped together in a <g> element (exactly the barcode 1D, PHP generates a barcode).
<g
style="fill:#000000;stroke:none"
id="barcode1D"
transform="matrix(1.2083333,0,0,0.8247805,62.027778,573.54235)">
<rect
x="0"
y="0"
width="4"
height="30"
id="xyz" />
....
<rect
x="224"
y="0"
width="0"
height="30"
id="xyzn" /> </g>
The barcode is generated in various widths, lengths. How can I set the width permanently ?
Based on this example, I am asking for a hint. Thank you for your help in advance.
SVG g element does not have width and height attributes. Therefore, you can not set height and width on it.
You should use a foreignObject with a svg inside of it to do so.
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<foreignObject id="G" width="300" height="200">
<svg>
<!-- Barcode here -->
<rect fill="black" stroke-width="2" height="112" width="84" y="55" x="55" stroke="#000000"/>
<circle fill="#FF0000" stroke="#000000" stroke-width="5" cx="155" cy="65" id="svg_7" r="50"/>
</svg>
</foreignObject>
</svg>
Can I use <use> to refer to a previously declared object inside a <clipPath> declaration?
So that it uses that element as definition for the clip path?
For example:
<defs>
<rect id="foo" width="20" height="20" />
<clipPath id="bar">
<use href="#foo" />
</clipPath>
</defs>
Yes, you can use the <use> command inside the clipPath declaration to refer to any external objects inside the svg file.
In the example below, clipPath cuts a 80 x 80px square from the image.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 300 300" style="border:1px solid red">
<defs>
<rect id="foo" width="80" height="80" />
<clipPath id="bar">
<use href="#foo" />
</clipPath>
</defs>
<image clip-path="url(#bar)" xlink:href="http://lorempixel.com/600/600/nature/1" x="20" y="20" height="100%" width="100%" />
</svg>
The red square shows the border of the entire canvas svg.
I need help interpreting the svg which generates this graph paper.
I think I understand the general idea behind the code:
there are 3 layers/groups being created, one of which has the original rectangle
translation and transform operations appear to be used to replicate this rectangle all over the canvas.
but I'm having a hard time understanding some details behind the svg code.
I also don't understand how the layers interact with each other.
Questions
How do you interpret the transform="matrix(0,1,-1,0,400,0)" operation?
Can you explain the implied for-loop that's in this svg code which copies the rectangles?
What does the path tag do in the context of this code?
I am trying to understand this svg code well enough so I can modify it for my own uses.
Thank you.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.0"
width="400"
height="400"
id="svg2180">
<defs
id="defs2182" />
<g
style="opacity:1;display:inline"
id="layer1">
<g
style="stroke:#a9a9a9;stroke-opacity:1"
id="g8191">
<path
d="M 20,0 L 20,400"
style="fill:none;fill-rule:evenodd;stroke:#a9a9a9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path1872" />
<use
transform="translate(20,0)"
style="stroke:#a9a9a9;stroke-opacity:1"
id="use8185"
x="0"
y="0"
width="400"
height="400"
xlink:href="#path1872" />
<use
transform="translate(40,0)"
style="stroke:#a9a9a9;stroke-opacity:1"
id="use8187"
x="0"
y="0"
width="400"
height="400"
xlink:href="#path1872" />
<use
transform="translate(60,0)"
style="stroke:#a9a9a9;stroke-opacity:1"
id="use8189"
x="0"
y="0"
width="400"
height="400"
xlink:href="#path1872" />
</g>
<use
transform="translate(100,0)"
id="use8197"
x="0"
y="0"
width="400"
height="400"
xlink:href="#g8191" />
<use
transform="translate(200,0)"
id="use8199"
x="0"
y="0"
width="400"
height="400"
xlink:href="#g8191" />
<use
transform="translate(300,0)"
id="use8201"
x="0"
y="0"
width="400"
height="400"
xlink:href="#g8191" />
<use
transform="matrix(0,1,-1,0,400,0)"
id="use8203"
x="0"
y="0"
width="400"
height="400"
xlink:href="#g8191" />
<use
transform="translate(0,100)"
id="use8205"
x="0"
y="0"
width="400"
height="400"
xlink:href="#use8203" />
<use
transform="translate(0,200)"
id="use8207"
x="0"
y="0"
width="400"
height="400"
xlink:href="#use8203" />
<use
transform="translate(0,300)"
id="use8209"
x="0"
y="0"
width="400"
height="400"
xlink:href="#use8203" />
</g>
<g
style="display:inline"
id="layer2">
<g
style="stroke:#366;stroke-opacity:1"
id="g8225">
<path
d="M 100,0 L 100,400"
style="fill:none;fill-rule:evenodd;stroke:#366;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="path8215" />
<use
transform="translate(100,0)"
style="stroke:#366;stroke-opacity:1"
id="use8217"
x="0"
y="0"
width="400"
height="400"
xlink:href="#path8215" />
<use
transform="translate(200,0)"
style="stroke:#366;stroke-opacity:1"
id="use8219"
x="0"
y="0"
width="400"
height="400"
xlink:href="#path8215" />
</g>
<use
transform="matrix(0,1,-1,0,400,0)"
id="use8232"
x="0"
y="0"
width="400"
height="400"
xlink:href="#g8225" />
</g>
<g
id="layer3">
<rect
width="399"
height="399"
x="0.5"
y="0.5"
style="fill:none;stroke:#366;stroke-opacity:1"
id="rect10078" />
</g>
</svg>
Don't misinterpret the "layers" in this document. They aren't really about layering, they're about grouping.
How do you interpret the transform="matrix(0,1,-1,0,400,0)" operation?
That is a transformation matrix for an affine transform. It's a fancy way to combine rotation, skew, and translation into one function. They can be difficult to wrap one's mind around though, and I usually only see them used in code generated by a drawing application.
Can you explain the implied for-loop that's in this svg code which copies the rectangles?
In SVG, you can re-use any object that you have given an id to, using the <use .../> tag. This can be used as a sort of DRY, to keep repetition low in the code. In this case, a group of horizontal lines is created, then copies are made by referencing them with use tags. each use has it's own transform attribute to move it into place. Halfway down the list, the line group get rotated 90 degrees (using the transform matrix) and then copied across the image.
What does the path tag do in the context of this code?
It just draws the thick line. This could have been done with a line element, but drawing software output that, and it wasn't smart enough to replace it, I guess. Usually path elements are used for more complex shapes, since they support arcs and bezier curves.