How to iterate in SVG? - svg

I would like to render a watch in SVG. I have the circles and now I would like to render the index for the hours and minutes.
svg {
width: 100vmin;
height: 100vmin;
overflow: hidden;
}
line, circle {
stroke: black;
stroke-width: 0.3px;
}
circle {
fill: none;
}
circle.filled {
stroke: none;
fill: black;
}
<svg viewBox="0 0 100 100">
<!-- center dot -->
<circle cx="50" cy="50" r="1" class="filled" />
<!-- hour circle -->
<circle cx="50" cy="50" r="35" />
<line x1="50" y1="17" x2="50" y2="15" />
<!-- minute circle -->
<circle cx="50" cy="50" r="40" />
<line x1="50" y1="10" x2="50" y2="8" />
</svg>
I know that I can use the transform attribute to rotate the lines around the center. But how to express the loop in SVG to do it 59 times for the minutes and 11 times for the hours? Do I have to use JavaScript for this, or is it possible to draw the lines directly in SVG without writing 72 line elements? Something less verbose than this:
<line x1='50' y1='17' x2='50' y2='15' id='h0' />
<use href='#h0' transform='rotate ( 30, 50, 50)' />
<use href='#h0' transform='rotate ( 60, 50, 50)' />
<use href='#h0' transform='rotate ( 90, 50, 50)' />
<use href='#h0' transform='rotate (120, 50, 50)' />
<use href='#h0' transform='rotate (150, 50, 50)' />
<use href='#h0' transform='rotate (180, 50, 50)' />
<use href='#h0' transform='rotate (210, 50, 50)' />
<use href='#h0' transform='rotate (240, 50, 50)' />
<use href='#h0' transform='rotate (270, 50, 50)' />
<use href='#h0' transform='rotate (300, 50, 50)' />
<use href='#h0' transform='rotate (330, 50, 50)' />
and this
<line x1='50' y1='10' x2='50' y2='8' id='m0' />
<use href='#h0' transform='rotate ( 30, 50, 50)' />
<use href='#m0' transform='rotate ( 6, 50, 50)' />
<use href='#m0' transform='rotate ( 12, 50, 50)' />
<use href='#m0' transform='rotate ( 18, 50, 50)' />
<use href='#m0' transform='rotate ( 24, 50, 50)' />
<use href='#m0' transform='rotate ( 30, 50, 50)' />
<use href='#m0' transform='rotate ( 36, 50, 50)' />
<use href='#m0' transform='rotate ( 42, 50, 50)' />
<use href='#m0' transform='rotate ( 48, 50, 50)' />
<use href='#m0' transform='rotate ( 54, 50, 50)' />
<use href='#m0' transform='rotate ( 60, 50, 50)' />
<use href='#m0' transform='rotate ( 66, 50, 50)' />
<use href='#m0' transform='rotate ( 72, 50, 50)' />
<use href='#m0' transform='rotate ( 78, 50, 50)' />
<use href='#m0' transform='rotate ( 84, 50, 50)' />
<use href='#m0' transform='rotate ( 90, 50, 50)' />
<use href='#m0' transform='rotate ( 96, 50, 50)' />
<use href='#m0' transform='rotate (102, 50, 50)' />
<use href='#m0' transform='rotate (108, 50, 50)' />
<use href='#m0' transform='rotate (114, 50, 50)' />
<use href='#m0' transform='rotate (120, 50, 50)' />
<use href='#m0' transform='rotate (126, 50, 50)' />
<use href='#m0' transform='rotate (132, 50, 50)' />
<use href='#m0' transform='rotate (138, 50, 50)' />
<use href='#m0' transform='rotate (144, 50, 50)' />
<use href='#m0' transform='rotate (150, 50, 50)' />
<use href='#m0' transform='rotate (156, 50, 50)' />
<use href='#m0' transform='rotate (162, 50, 50)' />
<use href='#m0' transform='rotate (168, 50, 50)' />
<use href='#m0' transform='rotate (174, 50, 50)' />
<use href='#m0' transform='rotate (180, 50, 50)' />
<use href='#m0' transform='rotate (186, 50, 50)' />
<use href='#m0' transform='rotate (192, 50, 50)' />
<use href='#m0' transform='rotate (198, 50, 50)' />
<use href='#m0' transform='rotate (204, 50, 50)' />
<use href='#m0' transform='rotate (210, 50, 50)' />
<use href='#m0' transform='rotate (216, 50, 50)' />
<use href='#m0' transform='rotate (222, 50, 50)' />
<use href='#m0' transform='rotate (228, 50, 50)' />
<use href='#m0' transform='rotate (234, 50, 50)' />
<use href='#m0' transform='rotate (240, 50, 50)' />
<use href='#m0' transform='rotate (246, 50, 50)' />
<use href='#m0' transform='rotate (252, 50, 50)' />
<use href='#m0' transform='rotate (258, 50, 50)' />
<use href='#m0' transform='rotate (264, 50, 50)' />
<use href='#m0' transform='rotate (270, 50, 50)' />
<use href='#m0' transform='rotate (276, 50, 50)' />
<use href='#m0' transform='rotate (282, 50, 50)' />
<use href='#m0' transform='rotate (288, 50, 50)' />
<use href='#m0' transform='rotate (294, 50, 50)' />
<use href='#m0' transform='rotate (300, 50, 50)' />
<use href='#m0' transform='rotate (306, 50, 50)' />
<use href='#m0' transform='rotate (312, 50, 50)' />
<use href='#m0' transform='rotate (318, 50, 50)' />
<use href='#m0' transform='rotate (324, 50, 50)' />
<use href='#m0' transform='rotate (330, 50, 50)' />
<use href='#m0' transform='rotate (336, 50, 50)' />
<use href='#m0' transform='rotate (342, 50, 50)' />
<use href='#m0' transform='rotate (348, 50, 50)' />
<use href='#m0' transform='rotate (354, 50, 50)' />

You can nest use blocks, which might save you some lines, e.g.
circle {
fill: none;
stroke: black;
}
line {
stroke: black;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<!-- center dot -->
<circle cx="50" cy="50" r="1" class="filled" />
<!-- hour circle -->
<circle cx="50" cy="50" r="35" />
<!-- minute circle -->
<circle cx="50" cy="50" r="40" />
<g id='five-block'>
<line x1="50" y1="17" x2="50" y2="15" />
<line id="minute" x1="50" y1="10" x2="50" y2="8" />
<use href='#minute' transform='rotate (6, 50, 50)' />
<use href='#minute' transform='rotate (12, 50, 50)' />
<use href='#minute' transform='rotate (18, 50, 50)' />
<use href='#minute' transform='rotate (24, 50, 50)' />
</g>
<g id="quarter-block">
<use href='#five-block' transform='rotate (30, 50, 50)' />
<use href='#five-block' transform='rotate (60, 50, 50)' />
<use href='#five-block' transform='rotate (90, 50, 50)' />
</g>
<use href='#quarter-block' transform='rotate (90, 50, 50)' />
<use href='#quarter-block' transform='rotate (180, 50, 50)' />
<use href='#quarter-block' transform='rotate (270, 50, 50)' />
</svg>
You could nest the use blocks even more if you wanted to make it slightly less verbose.
Or you could use Javascript to create the elements.

Since the javascript option hasn't been written out, here is an implementation:
var svg = document.querySelector("svg");
var xmlns = "http://www.w3.org/2000/svg";
var scales = [{ref: 'h0', ticks: 12}, {ref: 'm0', ticks: 60}];
scales.forEach(function(scale){
var ticks = scale.ticks;
var degrees = 360/ticks;
while (ticks) {
var use = document.createElementNS(xmlns, "use");
use.setAttribute("href", "#" + scale.ref);
use.setAttribute("transform", "rotate(" + degrees*ticks + ", 50, 50)")
svg.appendChild(use);
ticks--;
}
});
You can see it in action here: https://jsfiddle.net/dhd8g3tg/

Related

SVG renders incorrectly

I have done this on CodePen and it works but when I see it on a browser it doesn't render correctly. It stays on the original size (145, 90) but the svg seems to be scaling.
Once I change the viewbox property in the browser to something else manually and then back to "0 0 145 90" it works as I want it to.
<svg data-v-1d986156="" viewbox="0 0 145 90">
<g data-v-1d986156="">
<text data-v-1d986156="" text-anchor="end" x="13" y="71" style="font-size: 6px; fill: rgb(0, 51, 102);">7</text>
<text data-v-1d986156="" text-anchor="end" x="13" y="61" style="font-size: 6px; fill: rgb(0, 51, 102);">14</text>
<text data-v-1d986156="" text-anchor="end" x="13" y="51" style="font-size: 6px; fill: rgb(0, 51, 102);">21</text>
<text data-v-1d986156="" text-anchor="end" x="13" y="41" style="font-size: 6px; fill: rgb(0, 51, 102);">28</text>
<text data-v-1d986156="" text-anchor="end" x="13" y="31" style="font-size: 6px; fill: rgb(0, 51, 102);">35</text>
<text data-v-1d986156="" text-anchor="end" x="13" y="21" style="font-size: 6px; fill: rgb(0, 51, 102);">42</text>
<text data-v-1d986156="" text-anchor="end" x="13" y="11" style="font-size: 6px; fill: rgb(0, 51, 102);">49</text>
<line data-v-1d986156="" x1="15" y1="69" x2="145" y2="69" stroke="#003366" stroke-width="0.2"></line>
<line data-v-1d986156="" x1="15" y1="59" x2="145" y2="59" stroke="#003366" stroke-width="0.2"></line>
<line data-v-1d986156="" x1="15" y1="49" x2="145" y2="49" stroke="#003366" stroke-width="0.2"></line>
<line data-v-1d986156="" x1="15" y1="39" x2="145" y2="39" stroke="#003366" stroke-width="0.2"></line>
<line data-v-1d986156="" x1="15" y1="29" x2="145" y2="29" stroke="#003366" stroke-width="0.2"></line>
<line data-v-1d986156="" x1="15" y1="19" x2="145" y2="19" stroke="#003366" stroke-width="0.2"></line>
<line data-v-1d986156="" x1="15" y1="9" x2="145" y2="9" stroke="#003366" stroke-width="0.2"></line>
</g>
<line data-v-1d986156="" x1="0" y1="79" x2="145" y2="79" stroke="#003366"></line>
<g data-v-1d986156="">
<rect data-v-1d986156="" fill="#49e5a6" id="outstanding" x="22.5" y="53" width="25" height="25.57"></rect>
<text data-v-1d986156="" text-anchor="middle" x="35" y="88" class="percent" style="font: 8px serif;">15.8%</text>
</g>
<g data-v-1d986156="">
<rect data-v-1d986156="" fill="#00b9c1" id="good" x="52.5" y="13.3" width="25" height="65.34"></rect>
<text data-v-1d986156="" text-anchor="middle" x="65" y="88" class="percent" style="font: 8px serif;">40.4%</text>
</g>
<g data-v-1d986156="">
<rect data-v-1d986156="" fill="#e76d93" id="requires_improvement" x="82.5" y="21.8" width="25" height="56.82"></rect>
<text data-v-1d986156="" text-anchor="middle" x="95" y="88" class="percent" style="font: 8px serif;">35.1%</text>
</g>
<g data-v-1d986156="">
<rect data-v-1d986156="" fill="#ffcb4b" id="inadequate" x="112.5" y="64.4" width="25" height="14.2"></rect>
<text data-v-1d986156="" text-anchor="middle" x="125" y="88" class="percent" style="font: 8px serif;">8.8%</text>
</g>
</svg>
Images:

SVG Piechart with stroke-dasharray: box-shadow on slice not working

I generated a SVG piechart with stroke-dasharray but unfortunately I could not set a box-shadow for a specific slice (to mark is as active etc.). Normally it would work with filter: drop-shadow(0 4px 25px rgba(0, 0, 0, 0.75));. I also tried some different ways to integrate <filter> inside the svg but then it changed the whole size of the slide. Can somebody help to achieve this?
body {
padding: 1rem;
background: #bbb;
text-align: center;
}
svg:not(:root) {
overflow: visible;
}
svg {
height: 280px;
width: 280px;
border: 20px solid white;
border-radius: 50%;
[id="1"] {
filter: drop-shadow(0 4px 25px rgba(0, 0, 0, 0.75));
}
}
<!-- 4 Elements -->
<svg height="20" width="20" viewBox="0 0 20 20">
<circle id="1" r="5" cx="10" cy="10"
stroke="tomato"
stroke-width="10"
stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
transform="rotate(-90)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="blue"
stroke-width="10"
stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="yellow"
stroke-width="10"
stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
transform="rotate(90) scale(1.15)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="green"
stroke-width="10"
stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
transform="rotate(180)"
transform-origin="center center"
/>
</svg>
<!-- 5 Elements -->
<!-- <svg height="20" width="20" viewBox="0 0 20 20">
<circle r="10" cx="10" cy="10" fill="white" />
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="tomato"
stroke-width="10"
stroke-dasharray="calc(72 * 31.42 / 360) 31.42"
transform="rotate(-90)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="blue"
stroke-width="8"
stroke-dasharray="calc(72 * 31.42 / 360) 31.42"
transform="rotate(-18)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="yellow"
stroke-width="8"
stroke-dasharray="calc(72 * 31.42 / 360) 31.42"
360-6 transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="magenta"
stroke-width="8"
stroke-dasharray="calc(72 * 31.42 / 360) 31.42"
transform="rotate(126)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="green"
stroke-width="8"
stroke-dasharray="calc(72 * 31.42 / 360) 31.42"
transform="rotate(198)"
transform-origin="center center"
/>
</svg> -->
<!-- <svg height="20" width="20" viewBox="0 0 20 20">
<circle r="10" cx="10" cy="10" stroke="pink" />
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="tomato"
stroke-width="10"
stroke-dasharray="calc(60 * 31.42 / 360) 31.42"
transform="rotate(-90)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="blue"
stroke-width="10"
stroke-dasharray="calc(60 * 31.42 / 360) 31.42"
transform="rotate(-30)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="yellow"
stroke-width="10"
transform="rotate(30)"
stroke-dasharray="calc(60 * 31.42 / 360) 31.42"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="magenta"
stroke-width="10"
stroke-dasharray="calc(60 * 31.42 / 360) 31.42"
transform="rotate(90)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="green"
stroke-width="10"
stroke-dasharray="calc(60 * 31.42 / 360) 31.42"
transform="rotate(150)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="aqua"
stroke-width="10"
stroke-dasharray="calc(60 * 31.42 / 360) 31.42"
transform="rotate(210)"
transform-origin="center center"
/>
</svg> -->
What it should look like
The shape that you want to apply the shadow to, has to be drawn last, so the shadow is not overdrawn by the other shapes. Also, the CSS filter version doesn't seem to be working for some reason - so you will have to replace it with an SVG version. Here is something that works. Note that the shape is rotated, but feOffset applies dx and dy pre-rotation, so adding a dx = 2 doesn't move the shadow to the right.
body {
padding: 1rem;
background: #bbb;
text-align: center;
}
svg:not(:root) {
overflow: visible;
}
svg {
height: 280px;
width: 280px;
border: 20px solid white;
border-radius: 50%;
}
<!-- 4 Elements -->
<svg height="20" width="20" viewBox="0 0 20 20">
<defs>
<filter id="dshadow" x="-100%" y="-100%" width="300%" height="300%">
<feGaussianBlur stdDeviation="1"/>
<feOffset dx="-1" result="shadow"/>
<feFlood flood-color="black" flood-opacity="0.75"/>
<feComposite operator="in" in2="shadow"/>
<feComposite operator="over" in="SourceGraphic"/>
</filter>
</defs>
<circle id="1" r="5" cx="10" cy="10"
stroke="tomato"
stroke-width="10"
stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
transform="rotate(-90)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="blue"
stroke-width="10"
stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="green"
stroke-width="10"
stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
transform="rotate(180)"
transform-origin="center center"
/>
<circle r="5" cx="10" cy="10" fill="transparent"
stroke="yellow"
stroke-width="10"
stroke-dasharray="calc(90 * 31.42 / 360) 31.42"
transform="rotate(90) scale(1.15)"
transform-origin="center center"
filter="url(#dshadow)"
/>
</svg>

SVG is not correctly rendered with canvg

I need to convert svg to png and I'm using currently canvg to do this. But it's not working properly. As for example, using the demo app on https://canvg.js.org/demo/index.html with the svg:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" style="overflow: hidden; position: relative;" viewBox="-174 -90 468 452" width="468" height="452" preserveAspectRatio="xMinYMin">
<path fill="none" stroke="#333333" d="M60,0L60,128" stroke-width="3" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<path fill="none" stroke="#333333" d="M60,128L60,128" stroke-width="3" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<path fill="none" stroke="#333333" d="M60,128L60,272" stroke-width="3" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<path fill="none" stroke="#333333" d="M-84,0L60,0" stroke-width="3" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<path fill="none" stroke="#333333" d="M60,0L204,0" stroke-width="3" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaƫl 2.3.0</desc>
<defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<linearGradient id="ikr5p45-_ffffff:0-_B8B8B8:100" x1="0" y1="0.9999999999999998" x2="1" y2="0" gradientTransform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#ffffff" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#b8b8b8" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</linearGradient>
<linearGradient id="f8x0o45-_ffffff:0-_B8B8B8:100" x1="0" y1="0.9999999999999998" x2="1" y2="0" gradientTransform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#ffffff" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#b8b8b8" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</linearGradient>
<linearGradient id="lsc6m0-_ffffff:0-_B8B8B8:100" x1="0" y1="0" x2="1" y2="0" gradientTransform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#ffffff" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#b8b8b8" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</linearGradient>
<linearGradient id="ewq130-_ffffff:0-_B8B8B8:100" x1="0" y1="0" x2="1" y2="0" gradientTransform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#ffffff" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#b8b8b8" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</linearGradient>
<linearGradient id="z96gg0-_ffffff:0-_B8B8B8:100" x1="0" y1="0" x2="1" y2="0" gradientTransform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#ffffff" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#b8b8b8" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</linearGradient>
<linearGradient id="0muoy0-_ffffff:0-_B8B8B8:100" x1="0" y1="0" x2="1" y2="0" gradientTransform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#ffffff" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#b8b8b8" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</linearGradient>
<linearGradient id="v9b5l0-_ffffff:0-_B8B8B8:100" x1="0" y1="0" x2="1" y2="0" gradientTransform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#ffffff" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#b8b8b8" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</linearGradient>
<radialGradient id="o2zvpr_.5_.1__ccc-_ccc" fx="0.5" fy="0.1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#cccccc" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#cccccc" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</radialGradient>
<radialGradient id="mrqpyr_.5_.9_hsb_0.53__1__.75_-hsb_0.53__.5__.25_" fx="0.5" fy="0.9" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#009dbf" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#203a40" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</radialGradient>
<radialGradient id="utdacr_.5_.1__ccc-_ccc" fx="0.5" fy="0.1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#cccccc" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#cccccc" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</radialGradient>
<radialGradient id="wuajcr_.5_.9_hsb_0.53__1__.75_-hsb_0.53__.5__.25_" fx="0.5" fy="0.9" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#009dbf" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#203a40" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</radialGradient>
<radialGradient id="zg67dr_.5_.1__ccc-_ccc" fx="0.5" fy="0.1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#cccccc" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#cccccc" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</radialGradient>
<radialGradient id="hidu8r_.5_.9_hsb_0.53__1__.75_-hsb_0.53__.5__.25_" fx="0.5" fy="0.9" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#009dbf" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#203a40" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</radialGradient>
<radialGradient id="9tpgwr_.5_.1__ccc-_ccc" fx="0.5" fy="0.1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#cccccc" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#cccccc" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</radialGradient>
<radialGradient id="1ma5zr_.5_.9_hsb_0.53__1__.75_-hsb_0.53__.5__.25_" fx="0.5" fy="0.9" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<stop offset="0%" stop-color="#009dbf" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
<stop offset="100%" stop-color="#203a40" stop-opacity="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</radialGradient>
</defs>
<rect x="-30" y="182" width="180" height="180" rx="5" ry="5" fill="#009999" stroke="none" opacity="0" fill-opacity="0.35" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0; fill-opacity: 0.35;" />
<rect x="28.88730162779191" y="240.8873016277919" width="62.22539674441618" height="62.22539674441618" rx="0" ry="0" fill="#808080" stroke="none" opacity="0.3" fill-opacity="1" stroke-width="3" transform="matrix(0.7071,0.7071,-0.7071,0.7071,209.9066,41.4832)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0.3; fill-opacity: 1;" />
<rect x="28.88730162779191" y="240.8873016277919" width="62.22539674441618" height="62.22539674441618" rx="0" ry="0" fill="url('#ikr5p45-_ffffff:0-_B8B8B8:100')" stroke="#333333" opacity="1" fill-opacity="1" stroke-width="5.092592592592593" transform="matrix(0.7637,0.7637,-0.7637,0.7637,221.8992,18.4598)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 1; fill-opacity: 1;" />
<path fill="#595959" stroke="none" d="M9.182800000000002,25.3319C9.182800000000002,25.3319,0.8701000000000001,33.6424,0.8701000000000001,33.6424C0.8701000000000001,33.6424,3.8665000000000003,36.6388,3.8665000000000003,36.6388C3.8665000000000003,36.6388,12.177000000000001,28.3272,12.17744,28.3272C12.177000000000001,28.3272,14.425400000000002,30.574500000000004,14.425400000000002,30.574500000000004C14.425400000000002,30.574500000000004,17.1578,20.376400000000004,17.1578,20.376400000000004C17.1578,20.376400000000004,6.959700000000001,23.108800000000002,6.959700000000001,23.108800000000002C6.959700000000001,23.108800000000002,9.182800000000002,25.3319,9.182800000000002,25.331350000000004C9.182800000000002,25.3319,9.182800000000002,25.3319,9.182800000000002,25.3319" opacity="1" transform="matrix(1,0,0,1,2.8873,291.1127)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 1;" stroke-width="1" />
<rect x="-30" y="182" width="180" height="180" rx="0" ry="0" fill="#008000" stroke="none" opacity="0" fill-opacity="0.35" transform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0; fill-opacity: 0.35;" />
<rect x="114" y="-90" width="180" height="180" rx="5" ry="5" fill="#009999" stroke="none" opacity="0" fill-opacity="0.35" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0; fill-opacity: 0.35;" />
<circle cx="204" cy="0" r="40" fill="#808080" stroke="none" opacity="0.3" fill-opacity="1" stroke-width="3" transform="matrix(1,0,0,1,3,3)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0.3; fill-opacity: 1;" />
<circle cx="204" cy="0" r="40" fill="url('#lsc6m0-_ffffff:0-_B8B8B8:100')" stroke="#333333" opacity="1" fill-opacity="1" stroke-width="3" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 1; fill-opacity: 1;" />
<rect x="114" y="-90" width="180" height="180" rx="0" ry="0" fill="#008000" stroke="none" opacity="0" fill-opacity="0.35" transform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0; fill-opacity: 0.35;" />
<rect x="-174" y="-90" width="180" height="180" rx="5" ry="5" fill="#009999" stroke="none" opacity="0" fill-opacity="0.35" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0; fill-opacity: 0.35;" />
<rect x="-124" y="-40" width="80" height="80" rx="0" ry="0" fill="#808080" stroke="none" opacity="0.3" fill-opacity="1" stroke-width="3" transform="matrix(1,0,0,1,3,3)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0.3; fill-opacity: 1;" />
<rect x="-124" y="-40" width="80" height="80" rx="0" ry="0" fill="url('#z96gg0-_ffffff:0-_B8B8B8:100')" stroke="#333333" opacity="1" fill-opacity="1" stroke-width="3" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 1; fill-opacity: 1;" />
<rect x="-174" y="-90" width="180" height="180" rx="0" ry="0" fill="#008000" stroke="none" opacity="0" fill-opacity="0.35" transform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0; fill-opacity: 0.35;" />
<rect x="34" y="-32" width="52" height="92" rx="5" ry="5" fill="#009999" stroke="none" opacity="0" fill-opacity="0.35" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0; fill-opacity: 0.35;" />
<circle cx="60" cy="0" r="6.5" fill="#dc7868" stroke="#000000" stroke-width="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" /><text x="60" y="-20" text-anchor="middle" font-family="Tahoma" font-size="14px" stroke="none" fill="#000000" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); text-anchor: middle; font-family: Tahoma; font-size: 14px;">
<tspan dy="-20" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" />
</text>
<rect x="34" y="-32" width="52" height="92" rx="0" ry="0" fill="#008000" stroke="none" opacity="0" fill-opacity="0.35" transform="matrix(1,0,0,1,0,0)" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); opacity: 0; fill-opacity: 0.35;" />
</svg>
The results are different on png than svg as in the image:
I think this is called masking, but I'm not an svg guru and I don't really know.
Is there any solution or alternative that will raster the images properly?

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.

Move a div to specific spots on an svg path

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>

Resources