SVG trouble with grouping - svg

I am new to SVG and am having difficulty grouping my multiple images into one. It should look like a baseball diamond with bases. I have been able to draw everything and can click and drag each item, one at a time. I am trying to move the entire image with one click. Any suggestions?
I have some JavaScript that allows my SVG to be moved around the page as separate pieces.
SVG I am trying to get this SVG element to stay together as one element when clicked and dragged around the page. I am not sure how to do this. I have tried using the tag as well as several other container tags. As it is currently, everything is dragged seperately
<rect class="draggable" x="62.226" y="62.227" transform="matrix(0.7071 0.7071 -0.7071 0.7071 210.7484 -87.2942)" fill="#088A08" stroke="#000000" width="297.043" height="297.041"
transform="matrix(1 0 0 1 0 0)" > </rect>
<rect class="draggable" x="197.138" y="25.591" transform="matrix(0.7071 0.7071 -0.7071 0.7071 89.4451 -137.5392)" fill="#FFFFFF" stroke="#000000" width="27.219" height="27.219"
transform="matrix(1 0 0 1 0 0)" ></rect>
<rect class="draggable" x="26.371" y="197.557" transform="matrix(0.7071 0.7071 -0.7071 0.7071 161.0362 33.5847)" fill="#FFFFFF" stroke="#000000" width="27.22" height="27.218"
transform="matrix(1 0 0 1 0 0)" ></rect>
<rect class="draggable" x="369.362" y="197.298" transform="matrix(0.7071 0.7072 -0.7072 0.7071 261.33 -209.0369)" fill="#FFFFFF" stroke="#000000" width="27.22" height="27.217"></rect>
<polygon class="draggable" fill="#FFFFFF" stroke="#000000" points="194.912,364.45 227.945,364.45 227.378,383.915 211.578,399.717 195.778,383.915 "
transform="matrix(1 0 0 1 0 0)" ></polygon>
</svg>
</html>

In order to drag all shapes simultaneously , you need to group them.
STEPS:-
1) place all shapes in a 'g' tag
2) apply 'drag' on this g tag ('mousemove'). means apply translate matrix to this g.
3) on 'mouseup' event , update the latest values of individual shapes.
<g class='draggable'>
<rect class="draggable" x="62.226" y="62.227" transform="matrix(0.7071 0.7071 -0.7071 0.7071 210.7484 -87.2942)" fill="#088A08" stroke="#000000" width="297.043" height="297.041"
transform="matrix(1 0 0 1 0 0)" > </rect>
<rect class="draggable" x="197.138" y="25.591" transform="matrix(0.7071 0.7071 -0.7071 0.7071 89.4451 -137.5392)" fill="#FFFFFF" stroke="#000000" width="27.219" height="27.219"
transform="matrix(1 0 0 1 0 0)" ></rect>
<rect class="draggable" x="26.371" y="197.557" transform="matrix(0.7071 0.7071 -0.7071 0.7071 161.0362 33.5847)" fill="#FFFFFF" stroke="#000000" width="27.22" height="27.218"
transform="matrix(1 0 0 1 0 0)" ></rect>
<rect class="draggable" x="369.362" y="197.298" transform="matrix(0.7071 0.7072 -0.7072 0.7071 261.33 -209.0369)" fill="#FFFFFF" stroke="#000000" width="27.22" height="27.217"></rect>
<polygon class="draggable" fill="#FFFFFF" stroke="#000000" points="194.912,364.45 227.945,364.45 227.378,383.915 211.578,399.717 195.778,383.915 "
transform="matrix(1 0 0 1 0 0)" ></polygon>
</g>

Related

How to rotate svg component around its axis

I want to rotate the pointer around its axis of the following SVG component.
How could I achieve that. I have tried it with following method but it doesn't rotate around it.
<g id="Group 1" transform = "translate(100, 100) rotate(45 0 0)">
<path id="Point" fill-rule="evenodd" clip-rule="evenodd" d="M302.248 291.371L230.862 209.521L212.309 230.492L302.248 291.371Z" fill="#72A1E7"/>
</g>
It is easier to:
rotate something if it can be centered around 0,0.
calculate the angle of the needle if you know the angle at the starting point.
Therefor the you could draw the needle like this, with the middle of the short line at 0,0 (yes, it is off-canvas) and then pointing at 6 o'clock:
svg {
background-color: silver;
}
<svg width="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<g id="Group 1">
<path id="Point" fill-rule="evenodd" clip-rule="evenodd"
d="M -10 0 L 10 0 L 0 75 Z" fill="#72A1E7"/>
</g>
</svg>
Now the needle can be moved to the center (or where ever) of the image:
svg {
background-color: silver;
}
<svg width="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<g id="Group 1" transform="translate(100 100)">
<path id="Point" fill-rule="evenodd" clip-rule="evenodd"
d="M -10 0 L 10 0 L 0 75 Z" fill="#72A1E7"/>
</g>
</svg>
The rotation can be done in different ways, but here I rotate the needle/path <path> itself to the imagined zero point of the meter and then use the group element <g> to give the meter a "value". So, here the calculation is that the meter takes up 300 deg, the zero value is at 30 deg (from 6 o'clock) and the max value is then at 330 deg. Here the value is 1/3 = 100 deg.
svg {
background-color: silver;
}
<svg width="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<circle transform="rotate(120 100 100)" cx="100" cy="100" r="85"
stroke="blue" stroke-width="5" stroke-dasharray="300 360" pathLength="360"
fill="none" />
<g id="Group 1" transform="translate(100 100) rotate(100)">
<path id="Point" transform="rotate(30)" fill-rule="evenodd"
clip-rule="evenodd" d="M -10 0 L 10 0 L 0 75 Z" fill="#72A1E7"/>
</g>
</svg>

svg Text Path renders weired in firefox

In Chrome, this fiddle renders just fine, however in firefox, the curved text is a complete mess:
https://jsfiddle.net/a1khn0cs/1/
<path id="curveBelow" d="M 25,75 A 40 40 0 0 0 95,75" stroke="none" fill="none"></path>
<text class="badge-circle-text" x="42" y="40">
<textPath alignment-baseline="middle" text-anchor="middle" href="#curveBelow">Text Belog</textPath>
</text>
I cannot find a reason why this happens in Firefox.
Could someone give a hint, how I could resolve or find the problem?
dominant-baseline="middle" and text-anchor="middle" are attributes of the text. Also in order to center text on a path you need to use startOffset = "50%" for the textPath and text-anchor="middle" for the text. I hope it helps.
<svg viewBox="0 0 120 120" width=120 height=120 version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="81512f4465f92d314502bc64-alpha">
<feColorMatrix type="saturate" values="0" result="desat"></feColorMatrix>
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1"></feFuncR>
<feFuncG type="discrete" tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1"></feFuncG>
<feFuncB type="discrete" tableValues="0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1"></feFuncB>
</feComponentTransfer>
</filter>
<mask id="81512f4465f92d314502bc64-grungeMask" x="0" y="0" width="180" height="180" maskUnits="objectBoundingBox">
<image x="0" y="0" width="180" height="180" filter="url(#81512f4465f92d314502bc64-alpha)" href="/grunge-mask.png"></image>
</mask>
<clipPath id="81512f4465f92d314502bc64-cutMiddle">
<rect x="0" y="0" width="120" height="45"></rect>
<rect x="0" y="75" width="120" height="45"></rect>
</clipPath>
<path id="81512f4465f92d314502bc64-curveAbove" d="M 25,45 A 40 40 0 0 1 95,45" stroke="none" fill="none"></path>
<path id="81512f4465f92d314502bc64-curveBelow" d="M 25,75 A 40 40 0 0 0 95,75" stroke="none" fill="none"></path>
<mask id="81512f4465f92d314502bc64-mainText">
<rect width="100%" height="100%" fill="#fff" x="0" y="0"></rect>
<text x="50%" y="50%" fill="#000" dominant-baseline="middle" text-anchor="middle">Text Center</text>
</mask>
</defs>
<g mask="url(#grungeMask)">
<circle class="badge-circle-outer-big" cx="60" cy="60" r="50" stroke="black" stroke-width="3" fill="none" clip-path="url(#81512f4465f92d314502bc64-cutMiddle)"></circle>
<circle class="badge-circle-outer-small" cx="60" cy="60" r="47" stroke="black" stroke-width="1" fill="none" clip-path="url(#81512f4465f92d314502bc64-cutMiddle)"></circle>
<circle class="badge-circle-inner-small" cx="60" cy="60" r="26" stroke="black" stroke-width=".5" fill="none" clip-path="url(#81512f4465f92d314502bc64-cutMiddle)"></circle>
<circle class="badge-circle-inner-big" cx="60" cy="60" r="24" stroke="black" stroke-width="1.5" fill="none" clip-path="url(#81512f4465f92d314502bc64-cutMiddle)"></circle>
<text dominant-baseline="middle" text-anchor="middle" class="badge-circle-text">
<textPath startOffset="50%" href="#81512f4465f92d314502bc64-curveAbove">Text Above</textPath>
</text>
<text dominant-baseline="middle" text-anchor="middle" class="badge-circle-text">
<textPath startOffset="50%" href="#81512f4465f92d314502bc64-curveBelow">Text Belog</textPath>
</text>
<path d="M 0,45 L 120,45 L 110,60 L 120,75 L 0,75 L 10,60" fill="black" class="badge-main" mask="url(#81512f4465f92d314502bc64-mainText)"></path>
</g>
</svg>

SVG textpath repeat text

Is it possible to easily define a short text which is repeated in an defined offset along a curve in an svg grafik? Did i have to use patterns for that purpose or is there a attribute for the textpath element (I couldn't find something at google)
If you want to have specific predefined offsets along the path, you will need to have multiple copies of the <textPath> element with different startOffset values.
<svg width="12cm" height="3.6cm" viewBox="0 0 1000 300" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="MyPath"
d="M 100 200
C 200 100 300 0 400 100
C 500 200 600 300 700 200
C 800 100 900 100 900 100" />
</defs>
<use xlink:href="#MyPath" fill="none" stroke="red" />
<text font-size="42.5" fill="blue" >
<textPath xlink:href="#MyPath" startOffset="0">Text</textPath>
</text>
<text font-size="42.5" fill="blue" >
<textPath xlink:href="#MyPath" startOffset="200">Text</textPath>
</text>
<text font-size="42.5" fill="blue" >
<textPath xlink:href="#MyPath" startOffset="400">Text</textPath>
</text>
<text font-size="42.5" fill="blue" >
<textPath xlink:href="#MyPath" startOffset="600">Text</textPath>
</text>
<text font-size="42.5" fill="blue" >
<textPath xlink:href="#MyPath" startOffset="800">Text</textPath>
</text>
</svg>
Or if instead you wanted to have specific gaps between the words, rather than placing them at specific offsets, you can use dx on <tspan> to set the word spacings.
<svg width="12cm" height="3.6cm" viewBox="0 0 1000 300" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="MyPath"
d="M 100 200
C 200 100 300 0 400 100
C 500 200 600 300 700 200
C 800 100 900 100 900 100" />
</defs>
<use xlink:href="#MyPath" fill="none" stroke="red" />
<text font-size="42.5" fill="blue" >
<textPath xlink:href="#MyPath">Text
<tspan dx="200">Text</tspan>
<tspan dx="200">Text</tspan>
<tspan dx="200">Text</tspan>
<tspan dx="200">Text</tspan>
</textPath>
</text>
</svg>

SVG overwrite with transparency

I have this svg:
<circle cx="50" cy="100" r="50" stroke-width="0" fill="orange"/>
<polygon points="0,100, 50,50 100,100" fill="white"/>
The background is transparent. The polygon overwrites the circle with white color, but I want this area to be transparent (instead of white). How can I do this?
You can use fill-rule: evenodd property with path:s to "cut holes" to your shapes:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<path fill="orange"
fill-rule="evenodd"
d="M50 50 L100 100 L0 100
A50 50 0 0 1 100 100
A50 50 0 0 1 0 100 z"/>
</svg>

SVG stroke as glued lines

Is there a way to define stroke of a single polygon so that it would look like multiple glued polygons? See this image:
No, not currently. (In the future, Vector Effects may let you do this.)
For the moment, you would need to have two polygons drawn with different stroke colours and thicknesses, and then use a clipping path to make sure that it looks like the thicker stroke does not also paint on the inside of the shape. For example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100" height="100">
<defs>
<polygon id="p" points="20,10 10,60 30,50 50,30"/>
<clipPath id="c">
<!-- a 100x100 square with the polygon cut out of it -->
<path d="M0,0 100,0 100,100 0,100 z M20,10 10,60 30,50 50,30 z"/>
</clipPath>
</defs>
<rect width="100" height="100"/>
<g clip-path="url(#c)" fill="none">
<use xlink:href="#p" stroke="yellow" stroke-width="8"/>
<use xlink:href="#p" stroke="blue" stroke-width="4"/>
</g>
</svg>
As with the last answer, you need 2 paths. However I would use 2 donut holes where the hole has nearly the diameter of the whole ring.The thing to note is that the outside of the inner ring forms the inside of the outer ring. Obviously stroke-width is zero.
You can emulate this with a morphology filter.
<svg width="2000px" height="2000px" viewBox="0 0 4000 4000">
<defs>
<filter id="dual-line" primitiveUnits="userSpaceOnUse">
<feColorMatrix result="just-stroke" type="matrix" values="0 0 0 0 0
0 1 0 0 0
0 0 1 0 0
-1 0 0 1 0"/>
<feColorMatrix in="SourceGraphic" result="just-fill" type="matrix"
values="0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0"/>
<feMorphology in="just-stroke" operator="dilate" radius="5"/>
<feGaussianBlur stdDeviation="6"/>
<feComponentTransfer result="pre-outer">
<feFuncA type="table" tableValues="0 0 .75 1">
</feComponentTransfer>
<feColorMatrix result="blackstroke" in="just-stroke" type="matrix" values=" 0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0"/>
<feComposite operator="over" in2="pre-outer" in="blackstroke"/>
<feComposite operator="in" in2="just-fill"/>
</filter>
</defs>
<g filter="url(#dual-line)">
<path d="M100 800 C 400 100, 650 100, 950 800 S 1500 1500, 100 800" stroke-width="5" stroke="green" fill="red"/>
</g>
</svg>

Resources