Move a div to specific spots on an svg path - svg

I have an SVG path that currently has an image travelling around it. I need to make it so that when you click on a button on the path, the image will travel to that specific spot?
Anyone have any ideas? Thanks in advance.
My HTML is:
<div class="route">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" x="0px" y="0px" width="500px" viewBox="0 0 500 1920" xml:space="preserve">
<path class="cls-1" d="M288.56,7.45c1,1.17,13.77,15.18,14,16.67a8.66,8.66,0,0,1-.65,4.21,117.08,117.08,0,0,1-8.09,18.43c-.36.66-.82,1.39-1.56,1.55a2.71,2.71,0,0,1-1.88-.59L282.72,43a2.5,2.5,0,0,0-4.09.88C270.79,54.35,263,65.09,253.14,73.73c-3,2.61-6.16,5-8.71,8.06-.88,1-1.71,2.38-1.25,3.65a4.35,4.35,0,0,0,1.1,1.49,53.93,53.93,0,0,1,14.12,25.72,4.5,4.5,0,0,1,.12,2.12c-.59,2.2-3.69,2.33-5.41,3.84s-1.75,4.08-1.68,6.34a90,90,0,0,0,1.24,14.12c2,10.3,7.81,19.93,8.07,30.43-2.28,24.14-22.77,45.32-46.87,48.1-2.7.32-5.5.44-8,1.57a20.09,20.09,0,0,0-5,3.7c-32.78,29.91-57.73,67.22-82.35,104.13-2.88,4.32-5.79,8.7-7.48,13.61-2,5.91-2.2,12.26-2.35,18.5-.21,8.75-.38,17.73,2.58,26,3.67,10.22,11.8,18.29,15.91,28.34,4.49,10.93,3.91,23.44,8.47,34.35,1.61,3.85,3.84,7.44,5.16,11.4,2.32,6.94,1.68,14.52,3.28,21.65,2.18,9.7,8.12,20.64,3,29.16a373.16,373.16,0,0,0-36.31,54.7c-4.78,8.8-9.24,17.89-11.68,27.62-2.81,11.19-2.85,22.86-2.88,34.4,0,16.77,0,34,5.78,49.7,2.39,6.51,5.73,12.65,8,19.19,10.3,29.32-1.45,61.63,1,92.61.42,5.43,1.34,11,4,15.71,3.57,6.34,9.92,10.64,16.46,13.82,22.55,10.94,48.91,11,72.34,19.86,12.93,4.92,25.1,12.27,36.75,19.73,5.54-6.69,15.43-8.71,24.11-8.93s17.66.7,25.86-2.17a42.79,42.79,0,0,0,12.9-7.74c15.09-12.46,25-30,33.81-47.45,11.51-22.93,21.95-47.81,20.86-73.43-4.91-2.19-5.89-9.21-10.41-12.13-5.16-3.32-11.87-.21-18,0-7.93.27-15.06-4.5-21.47-9.19a604.83,604.83,0,0,1-70.37-60.38,24.51,24.51,0,0,1-5.05-6.35c-.8-1.66-1.24-3.5-2.27-5-2.1-3.15-6.11-4.31-9.77-5.27-35.8-9.32-70.81-22-104.91-36.35-4.52-7.11-4-16.94-4.71-25.34A85.91,85.91,0,0,0,99,520.19c-1.78-2.94-3.82-6-3.68-9.44a51.33,51.33,0,0,1,1-5.32c1-6.63-3.85-12.53-8-17.74-31.63-39.15-45.62-90.53-74.78-131.56a15.88,15.88,0,0,1-.82-14,14.43,14.43,0,0,1,10.56-8.1c2-.33,4.36-.43,5.38-2.16A5.54,5.54,0,0,0,28.8,328a120,120,0,0,0-3-11.95,21.64,21.64,0,0,0-2-4.93c-1.06-1.75-2.55-3.19-3.73-4.86a33.42,33.42,0,0,1-3.84-8.23c-3.28-9.13-6.58-18.33-8.06-27.92-1-6.17-1.14-12.44-2-18.62A86.93,86.93,0,0,0,.69,231a64.48,64.48,0,0,1,18.11-1.35c-14.94-40.19-3.59-88.94,27-119A156.85,156.85,0,0,1,64.48,95.09C80,83.88,96.75,74.38,113.42,64.9A46.07,46.07,0,0,1,124,60.05c5-1.35,10.31-.95,15.45-1.72C155.85,55.86,168,42.22,182.28,33.7c10.7-6.38,22.85-10,33.83-15.87,7.68-4.14,14.75-9.41,22.7-13s17.61-6.19,25.39-2.24c4.19,2.12,14.08-1.11,15-2.26"; />
<circle id="one" cx="295" cy="48" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" onclick="testFunc"/>
<circle id="two" cx="263" cy="65" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="three" cx="258" cy="103" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="four" cx="252" cy="135" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="five" cx="131" cy="305" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="six" cx="147" cy="502" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="seven" cx="125" cy="538" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="eight" cx="110" cy="563" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="nine" cx="96" cy="619" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="ten" cx="110" cy="791" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="eleven" cx="216" cy="841" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="twelve" cx="287" cy="846" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="thirteen" cx="323" cy="817" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="fourteen" cx="349" cy="766" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="fifteen" cx="355" cy="720" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="sixteen" cx="320" cy="705" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="seventeen" cx="265" cy="660" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="eighteen" cx="102" cy="528" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="nineteen" cx="96" cy="498" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="twenty" cx="22" cy="306" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="twentyone" cx="133" cy="59" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="twentytwo" cx="230" cy="8" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
</svg>
<div class="ship"></div>
</div>
Each circle needs to have a click function and the ship needs to move to that circle from where ever it is currently positioned. I currently have basic animation of the ship moving around the svg path using css but understand I'll need to use javascript/jquery.

It's actually quite easy to do. The simplest way is with a javascript animation using window.requestAnimationFrame().
See below. I've documented what I'm doing, so hopefully it should be quite easy to follow.
A couple of notes:
I've only configured the pathOffsets for the first five circles. I've left the rest up to you.
This code assumes that you are going to display the SVG at 1:1 scale. If you change that (ie. you change the SVG width), then the code will have to be modified, because otherwise the ship won't be positioned in the right place.
const ship = document.querySelector(".ship");
const routePath = document.querySelector("svg .cls-1");
// The distance along the path that each circle lies
const pathOffsets = {
"one": 45,
"two": 90,
"three": 141,
"four": 176,
"five": 407,
"six": 0,
"seven": 0,
"eight": 0,
"nine": 0,
"ten": 0,
"eleven": 0,
"twelve": 0,
"thirteen": 0,
"fourteen": 0,
"fifteen": 0,
"sixteen": 0,
"seventeen": 0,
"eighteen": 0,
"nineteen": 0,
"twenty": 0,
"twentyone": 0,
"twentytwo": 0
}
const shipSpeed = 1; // How far along the path to move for each animation step
var currentShipOffset = 0; // Where the ship is now
var shipTarget = 0; // The offset of where the ship is currently heading
var shipMoving = false;
// Position the ship at a particular offset along the path
function setShipOffset(offset) {
var pos = routePath.getPointAtLength(offset);
ship.style.left = pos.x + 'px';
ship.style.top = pos.y + 'px';
currentShipOffset = offset;
}
// Start the ship moving to a particular circle
function startShipMovement(evt) {
// Get the 'id' attribute of the circle we clicked on
var circleId = evt.target.id;
// Get the corresponding offset value
shipTarget = pathOffsets[circleId];
// If the ship isn't already moving, then begin the animation by requesting the first animation step
if (!shipMoving) {
window.requestAnimationFrame(doShipStep);
shipMoving = true;
}
}
function doShipStep() {
// If we are within one step of the target, then stop there.
if (Math.abs(shipTarget - currentShipOffset) <= shipSpeed) {
setShipOffset(shipTarget);
shipMoving = false;
return;
}
// Otherwise move one step in the correct direction
if (shipTarget > currentShipOffset) {
setShipOffset(currentShipOffset + shipSpeed);
} else {
setShipOffset(currentShipOffset - shipSpeed);
}
// and request another animation step
window.requestAnimationFrame(doShipStep);
}
// Set the initial ship position to the start of the path
setShipOffset(0);
// If you want to set it to a particular "port", then you can use:
//setShipOffset(pathOffsets["one"]);
// Add click hadlers to all the circles
var allCircles = document.querySelectorAll("svg circle");
allCircles.forEach(function(circle) {
circle.addEventListener("click", startShipMovement);
});
.route {
position: relative;
background-color: linen;
}
.ship {
position: absolute;
width: 16px;
height: 16px;
border-radius: 50%;
border: solid 1px white;
background-color: limegreen;
transform: translate(-50%, -50%);
}
<div class="route">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/" x="0px" y="0px" width="500px" viewBox="0 0 500 1920" xml:space="preserve">
<path class="cls-1" d="M288.56,7.45c1,1.17,13.77,15.18,14,16.67a8.66,8.66,0,0,1-.65,4.21,117.08,117.08,0,0,1-8.09,18.43c-.36.66-.82,1.39-1.56,1.55a2.71,2.71,0,0,1-1.88-.59L282.72,43a2.5,2.5,0,0,0-4.09.88C270.79,54.35,263,65.09,253.14,73.73c-3,2.61-6.16,5-8.71,8.06-.88,1-1.71,2.38-1.25,3.65a4.35,4.35,0,0,0,1.1,1.49,53.93,53.93,0,0,1,14.12,25.72,4.5,4.5,0,0,1,.12,2.12c-.59,2.2-3.69,2.33-5.41,3.84s-1.75,4.08-1.68,6.34a90,90,0,0,0,1.24,14.12c2,10.3,7.81,19.93,8.07,30.43-2.28,24.14-22.77,45.32-46.87,48.1-2.7.32-5.5.44-8,1.57a20.09,20.09,0,0,0-5,3.7c-32.78,29.91-57.73,67.22-82.35,104.13-2.88,4.32-5.79,8.7-7.48,13.61-2,5.91-2.2,12.26-2.35,18.5-.21,8.75-.38,17.73,2.58,26,3.67,10.22,11.8,18.29,15.91,28.34,4.49,10.93,3.91,23.44,8.47,34.35,1.61,3.85,3.84,7.44,5.16,11.4,2.32,6.94,1.68,14.52,3.28,21.65,2.18,9.7,8.12,20.64,3,29.16a373.16,373.16,0,0,0-36.31,54.7c-4.78,8.8-9.24,17.89-11.68,27.62-2.81,11.19-2.85,22.86-2.88,34.4,0,16.77,0,34,5.78,49.7,2.39,6.51,5.73,12.65,8,19.19,10.3,29.32-1.45,61.63,1,92.61.42,5.43,1.34,11,4,15.71,3.57,6.34,9.92,10.64,16.46,13.82,22.55,10.94,48.91,11,72.34,19.86,12.93,4.92,25.1,12.27,36.75,19.73,5.54-6.69,15.43-8.71,24.11-8.93s17.66.7,25.86-2.17a42.79,42.79,0,0,0,12.9-7.74c15.09-12.46,25-30,33.81-47.45,11.51-22.93,21.95-47.81,20.86-73.43-4.91-2.19-5.89-9.21-10.41-12.13-5.16-3.32-11.87-.21-18,0-7.93.27-15.06-4.5-21.47-9.19a604.83,604.83,0,0,1-70.37-60.38,24.51,24.51,0,0,1-5.05-6.35c-.8-1.66-1.24-3.5-2.27-5-2.1-3.15-6.11-4.31-9.77-5.27-35.8-9.32-70.81-22-104.91-36.35-4.52-7.11-4-16.94-4.71-25.34A85.91,85.91,0,0,0,99,520.19c-1.78-2.94-3.82-6-3.68-9.44a51.33,51.33,0,0,1,1-5.32c1-6.63-3.85-12.53-8-17.74-31.63-39.15-45.62-90.53-74.78-131.56a15.88,15.88,0,0,1-.82-14,14.43,14.43,0,0,1,10.56-8.1c2-.33,4.36-.43,5.38-2.16A5.54,5.54,0,0,0,28.8,328a120,120,0,0,0-3-11.95,21.64,21.64,0,0,0-2-4.93c-1.06-1.75-2.55-3.19-3.73-4.86a33.42,33.42,0,0,1-3.84-8.23c-3.28-9.13-6.58-18.33-8.06-27.92-1-6.17-1.14-12.44-2-18.62A86.93,86.93,0,0,0,.69,231a64.48,64.48,0,0,1,18.11-1.35c-14.94-40.19-3.59-88.94,27-119A156.85,156.85,0,0,1,64.48,95.09C80,83.88,96.75,74.38,113.42,64.9A46.07,46.07,0,0,1,124,60.05c5-1.35,10.31-.95,15.45-1.72C155.85,55.86,168,42.22,182.28,33.7c10.7-6.38,22.85-10,33.83-15.87,7.68-4.14,14.75-9.41,22.7-13s17.61-6.19,25.39-2.24c4.19,2.12,14.08-1.11,15-2.26"; />
<circle id="one" cx="295" cy="48" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="two" cx="263" cy="65" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="three" cx="258" cy="103" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="four" cx="252" cy="135" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="five" cx="131" cy="305" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="six" cx="147" cy="502" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="seven" cx="125" cy="538" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="eight" cx="110" cy="563" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="nine" cx="96" cy="619" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="ten" cx="110" cy="791" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="eleven" cx="216" cy="841" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="twelve" cx="287" cy="846" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="thirteen" cx="323" cy="817" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="fourteen" cx="349" cy="766" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="fifteen" cx="355" cy="720" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="sixteen" cx="320" cy="705" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="seventeen" cx="265" cy="660" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="eighteen" cx="102" cy="528" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="nineteen" cx="96" cy="498" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="twenty" cx="22" cy="306" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="twentyone" cx="133" cy="59" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
<circle id="twentytwo" cx="230" cy="8" r="6" stroke="#c7374f" stroke-width="4.5" fill="white" />
</svg>
<div class="ship"></div>
</div>

Related

Is it possible to center align <rect>'s inside a <g> for SVG?

Is it possible to vertically center align all the rects inside a tag without having to adjust the y attributes on <rect>? (see snippet for example)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3/org/1999/xlink" viewBox="0 0 225 38" preserveAspectRatio="none" width="100%" height="100%">
<g fill="black">
<rect x="10" y="1" width="6" height="5" />
<rect x="20" y="1" width="6" height="10" />
<rect x="30" y="1" width="6" height="20" />
<rect x="40" y="1" width="6" height="5" />
<rect x="50" y="1" width="6" height="15" />
</g>
</svg>
<h3>desired result</h3>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3/org/1999/xlink" viewBox="0 0 225 38" preserveAspectRatio="none" width="100%" height="100%">
<g fill="black">
<rect x="10" y="8" width="6" height="5" />
<rect x="20" y="6" width="6" height="10" />
<rect x="30" y="1" width="6" height="20" />
<rect x="40" y="8" width="6" height="5" />
<rect x="50" y="4" width="6" height="15" />
</g>
</svg>
No, it's not possible to center align <rect> elements.
But it is possible to center-align <line> elements and give them a stroke-width (note the viewBox is vertically centered around 0):
<svg viewBox="0 -19 225 38" width="100%" height="100%">
<g stroke="black">
<line x1="10" x2="16" stroke-width="5" />
<line x1="20" x2="26" stroke-width="10" />
<line x1="30" x2="36" stroke-width="20" />
<line x1="40" x2="46" stroke-width="5" />
<line x1="50" x2="56" stroke-width="15" />
</g>
</svg>
You could also achieve vertically centered <rect> elements by setting a transform: translate(0, -50%) css rule.
This approach also requires a transform-box: fill-box; (or content-box) property.
All <rect>elements get a y="50%" attribute to start at the vertical center of the svg viewBox.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3/org/1999/xlink" viewBox="0 0 225 38" width="100%" height="100%" style="border:1px solid #ccc">
<style>
rect {
transform: translate(0, -50%);
transform-origin: center;
transform-box: fill-box;
}
</style>
<g fill="black" >
<rect x="10" y="50%" width="6" height="5" />
<rect x="20" y="50%" width="6" height="10" />
<rect x="30" y="50%" width="6" height="20" />
<rect x="40" y="50%" width="6" height="5" />
<rect x="50" y="50%" width="6" height="15" />
</g>
</svg>
Browser support for transform-box is decent. (See caniuse).
However, if you need legacy browser (e.g. ie11) support, #ccprog's answer is a more robust solution.

How to create an SVG icon consisting of two overlapping shapes, one with a hole?

I have made a progress bar icon from two partially overlapping SVG shapes.
I would like the icon to have the same color as the surrounding text, so I set stroke and fill to currentColor.
The icon is displayed correctly if the color of the surrounding text doesn't have alpha channel e.g. color: black. However, if the color of the surrounding text has alpha channel e.g. color: rgba (0, 0, 0, 0.7), then the icon is darker where the shapes overlap.
How can I get the same color at each point of the icon?
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" fill="currentColor" />
</svg>
Question Prevent overlapping figures with alpha channel from shading each other? is very similar, but the accepted answer doesn't work in this case:
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<defs>
<clipPath id="myClip">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="black" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" />
</clipPath>
</defs>
<rect width="100%" height="100%" fill="currentColor" clip-path="url(#myClip)"/>
</svg>
Update:
I decided to draw the icon without overlapping parts, because it is much easier and it also looks good:
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="4" y="4" width="23" height="7" rx="2" ry="2" fill="currentColor" />
</svg>
One solution is to user a mask. But if you don't change the geometry, you will get the same issue as with #InvisibleGorilla's solution: you will get antialiasing artifacts.
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<defs>
<mask id="cutout">
<rect width="100%" height="100%" fill="white" />
<use xlink:href="#bar" fill="black" />
</mask>
<rect id="bar" x="2" y="2.5" width="24" height="10" />
</defs>
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent"
mask="url(#cutout)" />
<use xlink:href="#bar" fill="currentColor" />
</svg>
To fix the antialiasing artifacts, move your bar so that it is positioned at a whole pixel (y="2") instead of a half pixel (y="2.5"). You still might still see very slight artifacts at some scales. But it should be a lot better.
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<defs>
<mask id="cutout">
<rect width="100%" height="100%" fill="white" />
<use xlink:href="#bar" fill="black" />
</mask>
<rect id="bar" x="2" y="2" width="24" height="10" />
</defs>
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent"
mask="url(#cutout)" />
<use xlink:href="#bar" fill="currentColor" />
</svg>
Before the rect where fill has currentColor, add a rect with the exact same attributes but with a white fill directly before it (so that it gets drawn underneath it in the svg).
See snipped below:
<style>
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
</style>
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" fill="white" />
<rect x="2" y="2.5" width="24" height="10" fill="currentColor" />
</svg>
You could also change the order of your rects and add a matching white rect under the one where the stroke has currentColor.
Here's the updated snippet using background color and underlying both rects. I've tested on Chrome and Firefox on Mac and I don't see any lines from the background color rects.
<style>
body { background-color: #232b32; color: rgba(240, 240, 240, 0.7); }
</style>
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="#232b32" stroke-width="2" fill="transparent" />
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" fill="#232b32" />
<rect x="2" y="2.5" width="24" height="10" fill="currentColor" />
</svg>
<p>Some text</p>
Here's a screenshot of when I run this snippet.

SVG definition inheritance

Please look at eaExperiment. I want to make a definition which takes StartArrow definition and rotates it by 180 degrees.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="450" height="400" version="1.1">
<style type="text/css">
<![CDATA[
rect {fill:white; stroke: black; stroke-width: 1;}
text {fill: black; font-family: sans-serif; font-size: 10pt}
line {stroke:black; stroke-width:2}
]]>
</style>
<defs>
<marker orient="auto" refY="0.0" refX="0.0" id="StartArrow" style="overflow:visible;">
<path style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1" d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " />
</marker>
<use id="eaExperiment" href="#StartArrow" transform="rotate(180)" />
<marker orient="auto" refY="0.0" refX="0.0" id="EndArrow" style="overflow:visible;">
<path style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1" d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " transform="rotate(180)" />
</marker>
<svg id="Box">
<rect width="100" height="85" x="1" y="1" />
<text x="5" y="20">The box</text>
<svg x="10" y="25">
<rect width="70" height="50" x="1" y="1" />
<text x="5" y="20">Box</text>
<text x="5" y="40">Contents</text>
</svg>
</svg>
</defs>
<svg>
<svg x="10" y="120">
<rect width="100" height="50" x="1" y="1" />
<text x="5" y="20">Data</text>
<text x="5" y="40">source</text>
</svg>
<svg x="150">
<use href="#Box" y="1" />
<use href="#Box" y="100" />
<use href="#Box" y="200" />
</svg>
<svg x="300" y="120">
<rect width="100" height="50" x="1" y="1" />
<text x="5" y="20">Database</text>
<text x="5" y="40">server</text>
</svg>
<line x1="100" y1="120" x2="148" y2="40" style="marker-end:url(#EndArrow)" />
<line x1="110" y1="150" x2="147" y2="150" style="marker-end:url(#EndArrow)" />
<line x1="100" y1="170" x2="148" y2="240" style="marker-end:url(#EndArrow)" />
<line x1="254" y1="40" x2="297" y2="120" style="marker-start:url(#StartArrow); marker-end:url(#EndArrow)" />
<line x1="250" y1="150" x2="297" y2="150" style="marker-start:url(#eaExperiment); marker-end:url(#EndArrow)" />
<line x1="250" y1="240" x2="297" y2="170" style="marker-end:url(#EndArrow)" />
</svg>
</svg>
I am definitely doing it wrong, but what is the right way?
You need separate <marker> elements, but their content can be reused with <use> elements. For example like this:
<defs>
<path id="arrow" style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1" d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " />
<marker orient="auto" refY="0.0" refX="0.0" id="StartArrow" style="overflow:visible;">
<use xlink:href="#arrow" />
</marker>
<marker orient="auto" refY="0.0" refX="0.0" id="EndArrow" style="overflow:visible;">
<use xlink:href="#arrow" transform="rotate(180)" />
</marker>
</defs>
(While the use of the xlink namespace with href is deprecated and also from a practical perspective no longer needed in current browsers, I tend to still use it for the sake of other renderers, Inkscape for example.)

Changeing an SVG from 238 to 266 and now I'm stuck

This was originally 238, I want to change it to 266, and now I'm stuck.
I've done this before, but I forgot how to do it.
I know 7 goes into 266 38 times. See, I forgot how to do all this math, how you're supposed to calculate it.
I'm confused now.
It should all fit evenly I think, or does it not?
<svg width="266" height="266" viewBox="0 0 266 266">
<rect x="0" y="0" width="266" height="266" fill="blue" />
<rect x="7" y="7" width="224" height="224" fill="black" />
<rect x="14" y="14" width="210" height="210" fill="red" />
<rect x="21" y="21" width="196" height="196" fill="black" />
<rect x="28" y="28" width="182" height="182" fill="yellow" />
<rect x="35" y="35" width="168" height="168" fill="black" />
<rect x="42" y="42" width="154" height="154" fill="orange" />
<rect x="49" y="49" width="140" height="140" fill="black" />
<rect x="56" y="56" width="126" height="126" fill="lime" />
<rect x="63" y="63" width="112" height="112" fill="black" />
<rect x="70" y="70" width="98" height="98" fill="teal" />
<rect x="77" y="77" width="84" height="84" fill="black" />
<rect x="84" y="84" width="70" height="70" fill="silver" />
<rect x="91" y="91" width="56" height="56" fill="black" />
<rect x="98" y="98" width="42" height="42" fill="#1155cc" />
<rect x="105" y="105" width="28" height="28" fill="black" />
<rect x="112" y="112" width="14" height="14" fill="gold" />
</svg>
Assuming the original looked like this:
<svg width="238" height="238" viewBox="0 0 238 238">
<rect x="0" y="0" width="238" height="238" fill="blue" />
<rect x="7" y="7" width="224" height="224" fill="black" />
<rect x="14" y="14" width="210" height="210" fill="red" />
<rect x="21" y="21" width="196" height="196" fill="black" />
<rect x="28" y="28" width="182" height="182" fill="yellow" />
<rect x="35" y="35" width="168" height="168" fill="black" />
<rect x="42" y="42" width="154" height="154" fill="orange" />
<rect x="49" y="49" width="140" height="140" fill="black" />
<rect x="56" y="56" width="126" height="126" fill="lime" />
<rect x="63" y="63" width="112" height="112" fill="black" />
<rect x="70" y="70" width="98" height="98" fill="teal" />
<rect x="77" y="77" width="84" height="84" fill="black" />
<rect x="84" y="84" width="70" height="70" fill="silver" />
<rect x="91" y="91" width="56" height="56" fill="black" />
<rect x="98" y="98" width="42" height="42" fill="#1155cc" />
<rect x="105" y="105" width="28" height="28" fill="black" />
<rect x="112" y="112" width="14" height="14" fill="gold" />
</svg>
Then all you have to do to scale it up to 266x266 is to update the width and height attributes.
<svg width="266" height="266" viewBox="0 0 238 238">
Because the SVG has a viewBox, the browser will scale the contents automatically for you.
<svg width="266" height="266" viewBox="0 0 238 238">
<rect x="0" y="0" width="238" height="238" fill="blue" />
<rect x="7" y="7" width="224" height="224" fill="black" />
<rect x="14" y="14" width="210" height="210" fill="red" />
<rect x="21" y="21" width="196" height="196" fill="black" />
<rect x="28" y="28" width="182" height="182" fill="yellow" />
<rect x="35" y="35" width="168" height="168" fill="black" />
<rect x="42" y="42" width="154" height="154" fill="orange" />
<rect x="49" y="49" width="140" height="140" fill="black" />
<rect x="56" y="56" width="126" height="126" fill="lime" />
<rect x="63" y="63" width="112" height="112" fill="black" />
<rect x="70" y="70" width="98" height="98" fill="teal" />
<rect x="77" y="77" width="84" height="84" fill="black" />
<rect x="84" y="84" width="70" height="70" fill="silver" />
<rect x="91" y="91" width="56" height="56" fill="black" />
<rect x="98" y="98" width="42" height="42" fill="#1155cc" />
<rect x="105" y="105" width="28" height="28" fill="black" />
<rect x="112" y="112" width="14" height="14" fill="gold" />
</svg>

Rotate SVG group indefinitely 360 degrees without CSS or Java

This is my first time diving into SVG. Is it possible to rotate this group 360 indefinitely without css or javascript/jquery? So far I have it rotating in the top left corner but I cannot seem to figure out how to center it.
<?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="576" height="576" viewBox="0 0 288 288" xmlns="http://www.w3.org/2000/svg" version="1.1">
<g id="seed" transform="translate(144,144)" stroke-width="2" stroke="black" fill="none" >
<circle cx="0" r="64" />
<circle cx="64" r="64" />
<circle cx="64" r="64" transform="rotate(60)" />
<circle cx="64" r="64" transform="rotate(120)" />
<circle cx="64" r="64" transform="rotate(180)" />
<circle cx="64" r="64" transform="rotate(240)" />
<circle cx="64" r="64" transform="rotate(300)" />
<circle cx="0" r="128" />
<animateTransform attributeType="xml" attributeName="transform" type="rotate" values="0 0 0; 360 0 0" dur="5s" repeatCount="indefinite" />
</g>
</svg>
Your animateTransform overwrites the transform on the <g> element. Looks like you want to provide an additional transform which you would with the attribute additive="sum"
<svg width="576" height="576" viewBox="0 0 288 288" xmlns="http://www.w3.org/2000/svg" version="1.1">
<g id="seed" transform="translate(144,144)" stroke-width="2" stroke="black" fill="none" >
<circle cx="0" r="64" />
<circle cx="64" r="64" />
<circle cx="64" r="64" transform="rotate(60)" />
<circle cx="64" r="64" transform="rotate(120)" />
<circle cx="64" r="64" transform="rotate(180)" />
<circle cx="64" r="64" transform="rotate(240)" />
<circle cx="64" r="64" transform="rotate(300)" />
<circle cx="0" r="128" />
<animateTransform attributeType="xml" attributeName="transform" type="rotate" values="0 0 0; 360 0 0" dur="5s" additive="sum" repeatCount="indefinite" />
</g>
</svg>
PaEDIT: My bad you probally mean JavaScript.
Okay you can calculate the center with JavaScript and a nice SVG-method called getBBox();
A method to return center of SVG-elements so your should also be possible. Okay piece of code
var svg = {
getCenterPosition: function(elem) {
// use the native SVG interface to get it's boundingBox
var bbox = elem.getBBox();
// return the center of the bounding box
return {
px: (bbox.x + bbox.width / 2).toFixed(2),
py: (bbox.y + bbox.height / 2).toFixed(2)
};
}
}
svg.getCenterPosition(yourGElementAsParameter); will return the center-coordinates. (web developer console or Firebug or something) Then you can set these coordinates in your attributes but don't alter the viewbox or anything it will now rotate around it's center.

Resources