update water level based on the value - javascript
I am trying to understand the svg and javascript implementation. I have a vessel with water to show the level of water. I need to update the water level based on the value I get from the input box. The path is used to show the water level and its very difficult to update the level. How should i update the water level?
Here is the code
// 100 - full
// 75 - average
// 50 - half
// 25 - Low
// 0 - Empty
document.getElementsByName('water-level')[0].addEventListener('change', updateWaterLevel);
function updateWaterLevel() {
console.log('e', this.value);
}
<input type="number" value="" name="water-level"/>
<svg viewBox="0 0 600 600" >
<defs>
<mask id="liquidMask">
<path id="tubeLiquidShape" fill="#FFFFFF" d="M246.6,358.9l110.2-0.6c0.6,0,1.1-0.2,1.5-0.6c0.1-0.1,0.2-0.3,0.3-0.4
c0.4-0.6,0.5-1.4,0.2-2c0,0-12.3-28.7-17.9-41.9c-28.6,6.6-55.4-3.9-78.1,0.1c-9,21-18.2,42.5-18.2,42.5c-0.2,0.7-0.2,1.4,0.2,2
C245.2,358.6,245.9,358.9,246.6,358.9z" />
<g id="bubbleGroup">
<circle cx="267.3" cy="371" r="10.3" fill="#000000" />
<circle cx="324.3" cy="390" r="10.3" fill="#111111" />
<circle cx="288.6" cy="386.3" r="6.6" fill="#7f7f7f" />
<circle cx="288.6" cy="368.5" r="7.6" fill="#2d2d2d" />
<circle cx="340.3" cy="370" r="3" fill="#333333" />
<circle cx="300" cy="378.3" r="3" />
<circle cx="279.4" cy="379.7" r="2" />
<circle cx="337.3" cy="363" r="2" />
<circle cx="309.7" cy="383.2" r="2" />
<circle cx="309.7" cy="371" r="4.3" />
<circle cx="327" cy="368.5" r="6.1" />
</g>
</mask>
</defs>
<g id="tubeGroup">
<path id="tubeOutline" fill="#444444" d="M268.4,224.7c-4.1,0-8,1.6-10.9,4.5c-2.9,2.9-4.5,6.8-4.5,10.9l0,12.3
c0,4.1,1.6,8,4.5,10.9c2,2,4.6,3.5,7.3,4.1l-35.4,82.8c-2.2,5.7-1.5,12.1,1.9,17.1c3.4,5.1,9.2,8.1,15.3,8.1l110.1-0.6
c4.8,0,9.3-1.8,12.7-5.1c0.1-0.1,0.3-0.3,0.3-0.3c0.9-0.9,1.7-1.9,2.4-2.9c3.4-5.2,4-11.8,1.5-17.4l-35-81.5c2.9-0.6,5.6-2,7.7-4.2
c2.9-2.9,4.5-6.8,4.5-10.9l0-12.3c0-4.1-1.6-8-4.5-10.9s-6.8-4.5-10.9-4.5L268.4,224.7z M283.3,255.5l-14.9,0
c-1.7,0-3.1-1.4-3.1-3.1l0-12.3c0-1.7,1.4-3.1,3.1-3.1l67.3,0c1.7,0,3.1,1.4,3.1,3.1v12.3c0,1.7-1.4,3.1-3.1,3.1l-15.4,0l42.2,98.3
c0.8,1.9,0.6,4.1-0.5,5.8c-0.3,0.4-0.6,0.8-0.9,1.1c-1.1,1.1-2.6,1.7-4.2,1.7L246.6,363c-2,0-3.9-1-5.1-2.7
c-1.1-1.7-1.4-3.8-0.6-5.7L283.3,255.5z" stroke-width="1" />
<g id="maskedLiquid" mask="url(#liquidMask)">
<path id="tubeLiquid" fill="#74ccf4" d="M246.6,358.9l110.2-0.6c0.6,0,1.1-0.2,1.5-0.6c0.1-0.1,0.2-0.3,0.3-0.4
c0.4-0.6,0.5-1.4,0.2-2c0,0-12.3-28.7-17.9-41.9c-28.6,6.6-55.4-3.9-78.1,0.1c-9,21-18.2,42.5-18.2,42.5c-0.2,0.7-0.2,1.4,0.2,2
C245.2,358.6,245.9,358.9,246.6,358.9z" />
</g>
</g>
<g id="waterLevel">
<text x="380" y="340" font-size="24" fill="#555">Low</text>
</g>
</svg>
I can read the value but no idea on how do i update the water level which uses complex path
Here's a simplified version of your SVG, with an adjustable water level.
// 100 - full
// 75 - average
// 50 - half
// 25 - Low
// 0 - Empty
document.getElementsByName('water-level')[0].addEventListener('change', updateWaterLevel);
function updateWaterLevel() {
//console.log('e', this.value);
// Top of bottle/liquid is at y=225. Bottom is at y=375.
// Liquid starts in the "full" position.
// So for water level 100, we move the liquid down 0.
// For water level 0, we move the liquid down 150 (375 - 225).
var fractionFull = this.value / 100;
var dy = (1 - fractionFull) * 150;
document.getElementById("tubeLiquid").setAttribute("transform", "translate(0," + dy +")");
}
svg {
width: 500px;
}
<input type="number" value="" name="water-level"/>
<svg viewBox="0 0 600 600" >
<defs>
<mask id="bottleMask">
<path fill="#FFFFFF" d="M 275,225 L 225,375 L 375,375 L 325,225 Z" />
</mask>
</defs>
<g id="maskedLiquid" mask="url(#bottleMask)">
<path id="tubeLiquid" fill="#74ccf4" d="M 225,225 Q 262,220, 300,225 Q 337,230, 375,225 L 375,375 L 225,375 Z" />
</g>
<path id="bottleShape" d="M 275,225 L 225,375 L 375,375 L 325,225 Z" fill="none" stroke="#444444" stroke-width="10"/>
<g id="waterLevel">
<text x="380" y="340" font-size="24" fill="#555">Low</text>
</g>
</svg>
Related
updating SVG animateMotion path using JavaScript
I try changing an SVG motion path according to a html select value using JS. The path updates as expected, but the element, which uses the path as a motion path continues to move along the original path. What am I missing? function changepath(selectObject) { let value = selectObject.value; let path = document.getElementById("planePath"); let plane = document.getElementById("animPath"); let rotation = "rotate(" + value + ")"; path.setAttribute("transform", rotation); plane.setAttribute("transform", rotation); } body { background: #eee; } .planePath { opacity: 0.8; stroke: darkslategrey; stroke-width: 2px; fill: none; } .plane { transform: scale(0.15); } select { margin-left: 2em;; } <svg viewBox="0 0 2000 200"> <!-- <path class="planePath" id="planePath" d="M 0 0 C 200 250 250 50 550 150 C 850 250 700 180 1000 200 " /> --> <path class="planePath" id="planePath" d="M 50 100 c 14 -3 736 -115 1900 0" /> <g id="plane" class="plane"> <rect x="0" y="0" width="100" height="100"/> </g> <animateMotion xlink:href="#plane" dur="6s" repeatCount="indefinite" rotate="auto"> <mpath id="animPath" xlink:href="#planePath" /> </animateMotion> </svg> <select name="route" id="route" onchange="changepath(this)"> <option value="0">0°</option> <option value="1">1°</option> <option value="2">2°</option> <option value="3">3°</option> <option value="4">4°</option> </select>
As Danny mentioned in his answer the mpath is using the untransformed path. If you need it to be transformed you can wrap both the path and the animated rect in a group and transform the group. <svg viewBox="0 0 2000 200"> <g transform="rotate(5)"> <path id="path" fill="none" stroke="red" stroke-width="5" d="M 50 100 c 14 -3 736 -115 1900 0" /> <rect id="block" x="0" y="0" width="20" height="20"/> <animateMotion href="#block" dur="2s" repeatCount="indefinite" rotate="auto" restart="always"> <mpath href="#path" /> </animateMotion> </g> </svg>
Looks like animateMotion mpath can't handle the transform <svg viewBox="0 0 2000 200"> <path id="NO_rotate" fill="none" stroke="green" stroke-width="5" d="M 50 100 c 14 -3 736 -115 1900 0"/> <path id="path" fill="none" stroke="red" stroke-width="5" d="M 50 100 c 14 -3 736 -115 1900 0" transform="rotate(5)"/> <rect id="block" x="0" y="0" width="20" height="20"/> <animateMotion href="#block" dur="2s" repeatCount="indefinite" rotate="auto" restart="always"> <mpath href="#path" /> </animateMotion> </svg>
Putting value at 100 doesn't fill up SVG circle. What's wrong with my calculation
I am trying to fill up a SVG circle that has a radius of 13.5. And I have found a calculation but when entering the value as 100 it's only half full. Which believes me there is something wrong with the math part. Putting the value as 225 fills it up fully. And that's not what's desired at all. SVG: //Background of progress circle <circle r="13.5" cx="16" cy="16" fill="transparent" stroke="#9E9E9E" stroke-width="3" stroke-dasharray="84.82300164692441" stroke-dashoffset="28.27433388230813" /> </svg> //Progress circle <svg style={{ height: '32px', width: '32px', transform: 'rotate(150deg)' }}> <circle r="13.5" cx="16" cy="16" fill="transparent" stroke="#000" stroke-width="3" stroke-dasharray={dashArrayValue} stroke-dashoffset={dashOffsetValue} /> </svg> Calculation code let value = 100 let radius = 13.5 let circumference = radius * 2 * Math.PI let percent = value * 100 / 220 let offset = circumference - ((-percent * 62) / 100) / 100 * circumference let convertedOffset = -offset setDashArrayValue(`${circumference}`) //${circumference} setDashOffsetValue(`${convertedOffset}`) Hopefully someone can spot the flaw because I certainly can't since my math is awful. Thanks.
If it is the dash array that you try to manipulate, here are some examples. YOu can see that I'm just changing two values; the rotation of the circle (where the stroke will start) and the first value in the dash array (the length of the stroke). I allso added the pathLength attribute that controls the total length of the stroke of the circle (in this case 360, but it could also be 100 his that fist better into your use case). <p>From 12 o'clock to 3 o'clock: <svg height="32px" width="32px"> <circle r="13.5" cx="16" cy="16" fill="transparent" stroke="#000" stroke-width="3" pathLength="360" stroke-dasharray="90 360" transform="rotate(-90 16 16)"/> </svg> </p> <p>From 12 o'clock to 6 o'clock: <svg height="32px" width="32px"> <circle r="13.5" cx="16" cy="16" fill="transparent" stroke="#000" stroke-width="3" pathLength="360" stroke-dasharray="180 360" transform="rotate(-90 16 16)"/> </svg> </p> <p>From 12 o'clock to 10 o'clock: <svg height="32px" width="32px"> <circle r="13.5" cx="16" cy="16" fill="transparent" stroke="#000" stroke-width="3" pathLength="360" stroke-dasharray="300 360" transform="rotate(-90 16 16)"/> </svg> </p> <p>From 6 o'clock to 10 o'clock: <svg height="32px" width="32px"> <circle r="13.5" cx="16" cy="16" fill="transparent" stroke="#000" stroke-width="3" pathLength="360" stroke-dasharray="120 360" transform="rotate(90 16 16)"/> </svg> </p> And the interactive version: document.forms.form01.number.addEventListener('change', e => { let number = e.target.value; document.getElementById('c1').attributes['stroke-dasharray'].value = `${number} 100`; }); <form name="form01"> <input name="number" type="range" value="50" min="0" max="100" /> </form> <p><svg height="32px" width="32px"> <circle id="c1" r="13.5" cx="16" cy="16" fill="transparent" stroke="#000" stroke-width="3" pathLength="100" stroke-dasharray="50 100" transform="rotate(-90 16 16)"/> </svg></p>
Fill Percentage area in a custom Oval SVG image
I would like to fill a custom SVG to a specific percentage. Here is my initial SVG <svg width="202" height="195" viewBox="0 0 202 195" fill="none" xmlns="http://www.w3.org/2000/svg"> <path opacity="0.1" d="M96.8166 4.06964C16.0794 8.40606 -20.4645 94.8546 20.2957 157.019C54.6867 204.16 143.361 202.123 184.273 150.807C226.464 97.5789 163.505 0.38025 96.8166 4.06964Z" stroke="#313848" stroke-width="6.87634" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> </svg> Suppose there is a progress of x% so I would like to fill this SVG like <svg width="207" height="203" viewBox="0 0 207 203" fill="none" xmlns="http://www.w3.org/2000/svg"> <path opacity="0.1" d="M99.8166 12.0696C19.0794 16.4061 -17.4645 102.855 23.2957 165.019C57.6867 212.16 146.361 210.123 187.273 158.807C229.464 105.579 166.505 8.38025 99.8166 12.0696Z" stroke="#313848" stroke-width="6.87634" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> <path d="M99.8142 12.0736C166.502 8.38527 229.463 105.585 187.273 158.812" stroke="#EA7052" stroke-width="6.87634" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> <path d="M96.1683 2.4287C88.1789 2.85671 84.5529 11.2658 88.579 17.3074C91.9765 21.8887 100.751 21.6836 104.805 16.6905C108.986 11.5113 102.768 2.06471 96.1683 2.4287Z" fill="#EDEDEE" stroke="#EA7052" stroke-width="4.76054" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> <path d="M171.545 162.236C169.583 169.548 177.007 175.33 184.329 173.522C189.985 171.84 192.408 163.889 188.57 158.747C184.582 153.434 173.156 156.193 171.545 162.236Z" fill="#EDEDEE" stroke="#EA7052" stroke-width="4.76054" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> </svg> I am not able to figure out how to achieve this. I want it to be dynamic so that I can make it for any percentage. Also, I need to animate it from the starting point to the endpoint in a circular motion. Any help would be highly appreciatable.
As I've commented: You can calculate the length of the path using the getTotalLength() method. This represents 100%. Next you can get the length representing the x% (xperc in the code). Now you can use stroke-dasharray to represent the partial path. You can calculate the position of the last point using the getPointAtLength() method. Please read the comments in my code. //the desired percentege let xperc = .35; //the total length of the path let tl = base.getTotalLength(); //the partial length at the given percentage xperc let partial = tl * xperc; //set the stroke-dasharray of the second use element perc.setAttribute("stroke-dasharray", `${partial} ${tl -partial}`) //calculate the position of the point marking the end position let theEnd = base.getPointAtLength(partial); // set the cx and the cy attributes for the end point end.setAttribute("cx", theEnd.x); end.setAttribute("cy", theEnd.y); circle { stroke: red; fill:white; stroke-width: 6.87634; } <svg width="207" height="203" viewBox="0 0 207 203" fill="none" xmlns="http://www.w3.org/2000/svg"> <defs> <path id="base" d="M99.8166,12.0696L99.8166,12.0696C166.505,8.38025 229.464,105.579 187.273,158.807C146.361,210.123 57.6867,212.16 23.2957,165.019C-17.4645,102.855 19.0794,16.4061 99.8166,12.0696Z" stroke-width="6.87634" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> </defs> <use xlink:href="#base" stroke="silver" /> <use xlink:href="#base" stroke="red" id="perc" /> <circle cx="99.8166" cy="12.0696" r="10" /> <circle id="end" r="10" /> </svg> OBSERVATION: since your path goes counter clockwise I had to reverse the path to get the desired result And this is an example where I'm using an input type range to change the percent value: let xperc = itr.value; onInput(); itr.addEventListener("input", onInput) function onInput() { xperc = itr.value; let tl = base.getTotalLength(); let partial = tl * xperc; perc.setAttribute("stroke-dasharray", `${partial} ${tl - partial}`); let theEnd = base.getPointAtLength(partial); end.setAttribute("cx", theEnd.x); end.setAttribute("cy", theEnd.y); } circle { stroke: red; fill:white; stroke-width: 6.87634; } <input id="itr" type="range" min="0" max="1" step=".001" value=".35" /><br> <svg width="207" viewBox="-5 -5 220 220" fill="none" xmlns="http://www.w3.org/2000/svg"> <defs> <path id="base" d="M99.8166,12.0696L99.8166,12.0696C166.505,8.38025 229.464,105.579 187.273,158.807C146.361,210.123 57.6867,212.16 23.2957,165.019C-17.4645,102.855 19.0794,16.4061 99.8166,12.0696Z" stroke-width="6.87634" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> </defs> <use xlink:href="#base" stroke="silver" /> <use xlink:href="#base" stroke="red" id="perc" /> <circle cx="99.8166" cy="12.0696" r="10" /> <circle id="end" r="10" /> </svg> And another demo where I'm using javascript to animate it from 0 to 1: //the animation begins at 0 let xperc = 0; //get the total length of the path let tl = base.getTotalLength(); //the request animation id let rid = null; function Animation() { rid = window.requestAnimationFrame(Animation); // while xperc < 1 increase it's value by 0.001. Else stop the animation if (xperc < 1) { xperc += 0.001; }else{window.cancelAnimationFrame(rid)} //the same as in the first example let partial = tl * xperc; perc.setAttribute("stroke-dasharray", `${partial} ${tl - partial}`); let theEnd = base.getPointAtLength(partial); end.setAttribute("cx", theEnd.x); end.setAttribute("cy", theEnd.y); } Animation(); circle { stroke: red; fill:white; stroke-width: 6.87634; } <svg width="207" viewBox="-5 -5 220 220" fill="none" xmlns="http://www.w3.org/2000/svg"> <defs> <path id="base" d="M99.8166,12.0696L99.8166,12.0696C166.505,8.38025 229.464,105.579 187.273,158.807C146.361,210.123 57.6867,212.16 23.2957,165.019C-17.4645,102.855 19.0794,16.4061 99.8166,12.0696Z" stroke-width="6.87634" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> </defs> <use xlink:href="#base" stroke="silver" /> <use xlink:href="#base" stroke="red" id="perc" /> <circle cx="99.8166" cy="12.0696" r="10" /> <circle id="end" r="10" /> </svg>
SVG paths and images
I'm trying to add images to SVG paths as the title is saying. I've made the following fiddle, JSFiddle I'd like to put images within the paths, like so, (Green dots representing images) so image How would this be done? I tried adding images to the path, but they just didn't show up, obviously. Code: <svg width="175" height="175"> <g transform="translate(87.5,87.5)"> <path fill="#1f77b4" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#aec7e8" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#ff7f0e" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#ffbb78" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#2ca02c" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#98df8a" d="M5.357829746269671e-15,-87.5A87.5,87.5,0,0,1,83.21744517582593,-27.038987007807897L61.3431453010374,-19.93159613718411A64.5,64.5,0,0,0,3.949485927250214e-15,-64.5Z"></path> <path fill="#d62728" d="M83.21744517582593,-27.038987007807897A87.5,87.5,0,0,1,51.4312095755914,70.7889870078079L37.91214877286452,52.18159613718411A64.5,64.5,0,0,0,61.3431453010374,-19.93159613718411Z"></path> <path fill="#ff9896" d="M51.4312095755914,70.7889870078079A87.5,87.5,0,0,1,-51.43120957559139,70.7889870078079L-37.91214877286451,52.18159613718411A64.5,64.5,0,0,0,37.91214877286452,52.18159613718411Z"></path> <path fill="#9467bd" d="M-51.43120957559139,70.7889870078079A87.5,87.5,0,0,1,-83.21744517582594,-27.038987007807886L-61.34314530103741,-19.9315961371841A64.5,64.5,0,0,0,-37.91214877286451,52.18159613718411Z"></path> <path fill="#c5b0d5" d="M-83.21744517582594,-27.038987007807886A87.5,87.5,0,0,1,-1.607348923880901e-14,-87.5L-1.1848457781750641e-14,-64.5A64.5,64.5,0,0,0,-61.34314530103741,-19.9315961371841Z"></path> </g> </svg>
Following the picture, you need to add 5 circles. Each circle is rotated relative to the other by the same angle - 360/5 = 72 Create the first circle: <defs> <circle id="greenCircle" cx="13" cy="98" r="10" fill="#B6FF00" /> </defs> Use the command <use> to clone the circle and rotate it transform =" rotate (deg x y) " to the desired angle relative to the first circle. <svg width="175" height="175" > <defs> <circle id="greenCircle" cx="13" cy="98" r="10" fill="#B6FF00" /> </defs> <g transform="translate(87.5,87.5)"> <path fill="#1f77b4" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#aec7e8" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#ff7f0e" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#ffbb78" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#2ca02c" d="M5.357829746269671e-15,-87.5L3.949485927250214e-15,-64.5Z"></path> <path fill="#98df8a" d="M5.357829746269671e-15,-87.5A87.5,87.5,0,0,1,83.21744517582593,-27.038987007807897L61.3431453010374,-19.93159613718411A64.5,64.5,0,0,0,3.949485927250214e-15,-64.5Z"></path> <path fill="#d62728" d="M83.21744517582593,-27.038987007807897A87.5,87.5,0,0,1,51.4312095755914,70.7889870078079L37.91214877286452,52.18159613718411A64.5,64.5,0,0,0,61.3431453010374,-19.93159613718411Z"></path> <path fill="#ff9896" d="M51.4312095755914,70.7889870078079A87.5,87.5,0,0,1,-51.43120957559139,70.7889870078079L-37.91214877286451,52.18159613718411A64.5,64.5,0,0,0,37.91214877286452,52.18159613718411Z"></path> <path fill="#9467bd" d="M-51.43120957559139,70.7889870078079A87.5,87.5,0,0,1,-83.21744517582594,-27.038987007807886L-61.34314530103741,-19.9315961371841A64.5,64.5,0,0,0,-37.91214877286451,52.18159613718411Z"></path> <path fill="#c5b0d5" d="M-83.21744517582594,-27.038987007807886A87.5,87.5,0,0,1,-1.607348923880901e-14,-87.5L-1.1848457781750641e-14,-64.5A64.5,64.5,0,0,0,-61.34314530103741,-19.9315961371841Z"></path> </g> <use xlink:href="#greenCircle" transform="rotate(-10 87.5 87.5)" /> <use xlink:href="#greenCircle" transform="rotate(62 87.5 87.5)" /> <use xlink:href="#greenCircle" transform="rotate(134 87.5 87.5)" /> <use xlink:href="#greenCircle" transform="rotate(206 87.5 87.5)" /> <use xlink:href="#greenCircle" transform="rotate(278 87.5 87.5)" /> </svg>
Here's a hint, add this to your fiddle: <circle cx="0" cy="0" r="10" fill="#12345"></circle>
snapsvg - Move path to cursor pointer
I have a complex SVG with multiple paths. I'm trying to the change the path data (d) of the paths to match the position of the cursor so when the user mouseover the svg, they move toward the pointer. What seem like a simple animation feels more like nightmare considering I'm not sure about my approach and choice of tools. Here is my SVG: <svg version="1.1" id="graph" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 222 246.6" style="enable-background:new 0 0 222 246.6;" xml:space="preserve"> <style type="text/css"> .st0{clip-path:url(#SVGID_2_);fill:#52B3F5;} .st1{clip-path:url(#SVGID_2_);fill:#8FDAFF;} .st2{clip-path:url(#SVGID_2_);fill:#0468FF;} .st3{clip-path:url(#SVGID_2_);fill:none;stroke:#0468FF;stroke-miterlimit:10;} .st4{clip-path:url(#SVGID_2_);fill:none;stroke:#8FDAFF;stroke-miterlimit:10;} .st5{clip-path:url(#SVGID_2_);fill:none;stroke:#52B3F5;stroke-miterlimit:10;} </style> <g> <defs> <rect id="SVGID_1_" width="222" height="246.6"/> </defs> <clipPath id="SVGID_2_"> <use xlink:href="#SVGID_1_" style="overflow:visible;"/> </clipPath> <path class="st0" d="M222,233.8c0,3.2-2.6,5.8-5.8,5.8c-3.2,0-5.8-2.6-5.8-5.8c0-3.2,2.6-5.8,5.8-5.8 C219.4,228,222,230.6,222,233.8"/> <path class="st0" d="M105.2,150c0,2.1-1.7,3.7-3.7,3.7c-2.1,0-3.7-1.7-3.7-3.7c0-2.1,1.7-3.7,3.7-3.7 C103.5,146.2,105.2,147.9,105.2,150"/> <path class="st0" d="M34.4,21.1c0,2.5-2,4.5-4.5,4.5s-4.4-2-4.4-4.5c0-2.5,2-4.4,4.4-4.4S34.4,18.6,34.4,21.1"/> <path class="st1" d="M110.5,207.1c0,3.3-2.7,5.9-5.9,5.9c-3.3,0-5.9-2.7-5.9-5.9c0-3.3,2.7-5.9,5.9-5.9 C107.8,201.2,110.5,203.9,110.5,207.1"/> <path class="st2" d="M128.4,207.1c0,3.9-3.2,7.1-7.1,7.1c-3.9,0-7.1-3.2-7.1-7.1c0-3.9,3.2-7.1,7.1-7.1 C125.3,200.1,128.4,203.2,128.4,207.1"/> <path class="st2" d="M22.7,240.8c0,3.2-2.6,5.8-5.8,5.8c-3.2,0-5.8-2.6-5.8-5.8c0-3.2,2.6-5.8,5.8-5.8 C20.1,235,22.7,237.6,22.7,240.8"/> <path class="st0" d="M9.2,232.7c0,2.6-2.1,4.6-4.6,4.6S0,235.3,0,232.7s2.1-4.6,4.6-4.6S9.2,230.1,9.2,232.7"/> <polygon class="st3" points="148.1,105.2 106.2,207.1 120.5,207.1 155.4,122.2 "/> <path class="st2" d="M202.5,23.5c0,3.1-2.5,5.7-5.7,5.7s-5.7-2.5-5.7-5.7c0-3.1,2.5-5.7,5.7-5.7S202.5,20.4,202.5,23.5"/> <path class="st2" d="M188.7,17.5c0,1.9-1.5,3.4-3.4,3.4c-1.9,0-3.4-1.5-3.4-3.4c0-1.9,1.5-3.4,3.4-3.4 C187.2,14.1,188.7,15.6,188.7,17.5"/> <polygon class="st3" points="184.4,17.1 106.2,207.1 120.5,207.1 196,23.4 194.2,22.4 "/> <polygon class="st4" points="39.4,17 29.5,22.4 27.7,23.3 103.3,207.1 106.3,207.1 117.6,207.1 "/> <polygon class="st3" points="118.7,5.6 105.9,5.6 103.2,5.6 5.8,234.2 6.4,234.6 16,241.4 "/> <polygon class="st5" points="17.3,242.7 121.4,149.5 111.7,140.8 6.3,234.6 9.2,236.7 "/> <polygon class="st5" points="217.3,234.1 111.7,140.8 101.9,149.5 205.8,242.5 206.4,242.1 "/> <polygon class="st4" points="217.3,234.1 120.3,5.6 105.8,5.6 206.4,242.1 "/> <polygon class="st5" points="181.8,15.6 102,87.3 111.7,96.1 194.2,22.4 "/> <polygon class="st5" points="41.7,15.7 29.5,22.4 111.7,96.1 121.6,87.3 "/> <path class="st0" d="M46.9,17.7c0,3-2.4,5.3-5.3,5.3c-3,0-5.3-2.4-5.3-5.3c0-3,2.4-5.3,5.3-5.3C44.5,12.3,46.9,14.7,46.9,17.7"/> <path class="st1" d="M44.2,20.7c0,1.7-1.4,3.1-3.1,3.1s-3.1-1.4-3.1-3.1c0-1.7,1.4-3.1,3.1-3.1S44.2,19,44.2,20.7"/> <path class="st1" d="M31.4,22.3c0,1.5-1.2,2.7-2.7,2.7S26,23.8,26,22.3c0-1.5,1.2-2.7,2.7-2.7S31.4,20.8,31.4,22.3"/> <path class="st2" d="M105,5.6c0,2.1-1.7,3.8-3.8,3.8c-2.1,0-3.8-1.7-3.8-3.8c0-2.1,1.7-3.8,3.8-3.8C103.3,1.9,105,3.5,105,5.6"/> <path class="st2" d="M124.3,5.6c0,3.1-2.5,5.6-5.6,5.6c-3.1,0-5.6-2.5-5.6-5.6c0-3.1,2.5-5.6,5.6-5.6C121.8,0,124.3,2.5,124.3,5.6" /> <path class="st1" d="M123.6,5.6c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1c0-1.7,1.4-3.1,3.1-3.1 C122.2,2.5,123.6,3.9,123.6,5.6"/> <path class="st0" d="M186.2,15.7c0,2.5-2.1,4.6-4.6,4.6s-4.6-2.1-4.6-4.6c0-2.5,2.1-4.6,4.6-4.6S186.2,13.2,186.2,15.7"/> <path class="st0" d="M197.8,22.4c0,2.1-1.7,3.8-3.8,3.8c-2.1,0-3.8-1.7-3.8-3.8c0-2.1,1.7-3.8,3.8-3.8 C196.1,18.7,197.8,20.3,197.8,22.4"/> <path class="st0" d="M199.4,22.4c0,2.9-2.4,5.3-5.3,5.3c-2.9,0-5.3-2.4-5.3-5.3c0-2.9,2.4-5.3,5.3-5.3 C197,17.1,199.4,19.5,199.4,22.4"/> <path class="st1" d="M111.4,5.6c0,3.1-2.5,5.6-5.6,5.6c-3.1,0-5.6-2.5-5.6-5.6c0-3.1,2.5-5.6,5.6-5.6C108.9,0,111.4,2.5,111.4,5.6" /> <path class="st0" d="M142.4,52.6c0,1.1-0.9,2.1-2.1,2.1c-1.1,0-2.1-0.9-2.1-2.1c0-1.1,0.9-2.1,2.1-2.1 C141.5,50.5,142.4,51.5,142.4,52.6"/> <path class="st1" d="M132.9,61.7c0,1.6-1.3,3-3,3c-1.6,0-3-1.3-3-3c0-1.6,1.3-3,3-3C131.5,58.8,132.9,60.1,132.9,61.7"/> <path class="st0" d="M149.1,65.5c0,2-1.7,3.7-3.7,3.7s-3.7-1.7-3.7-3.7c0-2,1.7-3.7,3.7-3.7S149.1,63.4,149.1,65.5"/> <path class="st1" d="M140.2,75.1c0,2.9-2.3,5.2-5.2,5.2c-2.9,0-5.2-2.3-5.2-5.2c0-2.9,2.3-5.2,5.2-5.2 C137.9,69.9,140.2,72.2,140.2,75.1"/> <path class="st1" d="M221,233.8c0,2.1-1.7,3.8-3.8,3.8c-2.1,0-3.8-1.7-3.8-3.8s1.7-3.8,3.8-3.8C219.4,230.1,221,231.7,221,233.8"/> <path class="st1" d="M209.5,240.7c0,2.1-1.7,3.8-3.8,3.8c-2.1,0-3.8-1.7-3.8-3.8s1.7-3.8,3.8-3.8 C207.8,237,209.5,238.7,209.5,240.7"/> <path class="st2" d="M85,52.6c0,1.1-0.9,1.9-1.9,1.9c-1.1,0-1.9-0.9-1.9-1.9c0-1.1,0.9-1.9,1.9-1.9C84.2,50.7,85,51.5,85,52.6"/> <path class="st2" d="M96.1,62c0,1.5-1.2,2.7-2.7,2.7c-1.5,0-2.7-1.2-2.7-2.7c0-1.5,1.2-2.7,2.7-2.7C94.9,59.3,96.1,60.5,96.1,62"/> <path class="st2" d="M9.2,233.7c0,1.6-1.3,2.9-2.9,2.9s-2.9-1.3-2.9-2.9c0-1.6,1.3-2.9,2.9-2.9S9.2,232.1,9.2,233.7"/> <path class="st0" d="M82.7,65.7c0,2.6-2.1,4.7-4.7,4.7c-2.6,0-4.7-2.1-4.7-4.7c0-2.6,2.1-4.7,4.7-4.7C80.5,61,82.7,63.1,82.7,65.7" /> <path class="st0" d="M90.1,75.1c0,1-0.8,1.9-1.9,1.9c-1,0-1.9-0.8-1.9-1.9c0-1,0.8-1.9,1.9-1.9C89.3,73.2,90.1,74.1,90.1,75.1"/> <path class="st2" d="M150.4,105.2c0,1.5-1.2,2.7-2.7,2.7c-1.5,0-2.7-1.2-2.7-2.7c0-1.5,1.2-2.7,2.7-2.7 C149.2,102.6,150.4,103.8,150.4,105.2"/> <path class="st2" d="M159.7,123c0,2.2-1.8,4-4,4c-2.2,0-4-1.8-4-4c0-2.2,1.8-4,4-4C157.9,119,159.7,120.7,159.7,123"/> <path class="st1" d="M159.2,88c0,2.2-1.8,4-4,4c-2.2,0-4-1.8-4-4c0-2.2,1.8-4,4-4C157.4,83.9,159.2,85.7,159.2,88"/> <path class="st1" d="M165.2,105.7c0,1.5-1.2,2.7-2.7,2.7c-1.5,0-2.7-1.2-2.7-2.7c0-1.5,1.2-2.7,2.7-2.7 C164,103.1,165.2,104.2,165.2,105.7"/> <path class="st2" d="M79.9,104.1c0,2.4-1.9,4.3-4.3,4.3c-2.4,0-4.3-1.9-4.3-4.3c0-2.4,1.9-4.3,4.3-4.3 C78,99.7,79.9,101.7,79.9,104.1"/> <path class="st2" d="M109.8,207.1c0,2-1.6,3.6-3.6,3.6c-2,0-3.6-1.6-3.6-3.6c0-2,1.6-3.6,3.6-3.6 C108.2,203.5,109.8,205.2,109.8,207.1"/> <path class="st2" d="M71,86.7c0,1.6-1.3,2.9-2.9,2.9s-2.9-1.3-2.9-2.9c0-1.6,1.3-2.9,2.9-2.9S71,85.1,71,86.7"/> <path class="st0" d="M22.7,240.8c0,2-1.7,3.7-3.7,3.7s-3.7-1.7-3.7-3.7c0-2.1,1.7-3.7,3.7-3.7S22.7,238.7,22.7,240.8"/> <path class="st1" d="M123.7,207.1c0,2.8-2.2,5-5,5c-2.8,0-5-2.2-5-5c0-2.8,2.2-5,5-5C121.4,202.1,123.7,204.4,123.7,207.1"/> <path class="st0" d="M114.3,140.8c0,1.7-1.4,3.1-3.1,3.1s-3.1-1.4-3.1-3.1c0-1.7,1.4-3.1,3.1-3.1S114.3,139.1,114.3,140.8"/> <path class="st0" d="M104.6,168c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1c0-1.7,1.4-3.1,3.1-3.1 C103.2,164.9,104.6,166.3,104.6,168"/> <path class="st1" d="M94.7,176.6c0,2.2-1.8,4-4,4c-2.2,0-4-1.8-4-4s1.8-4,4-4C92.9,172.7,94.7,174.4,94.7,176.6"/> <path class="st2" d="M121,168c0,0.9,0.7,1.6,1.6,1.6c0.9,0,1.6-0.7,1.6-1.6c0-0.9-0.7-1.6-1.6-1.6C121.7,166.4,121,167.1,121,168" /> <path class="st0" d="M136,164.1c0,1.3,1,2.3,2.3,2.3c1.3,0,2.3-1,2.3-2.3c0-1.3-1-2.3-2.3-2.3C137,161.8,136,162.8,136,164.1"/> <path class="st2" d="M127.5,176.6c0,3.3,2.6,5.9,5.9,5.9c3.3,0,5.9-2.6,5.9-5.9c0-3.3-2.6-5.9-5.9-5.9 C130.1,170.7,127.5,173.4,127.5,176.6"/> <path class="st0" d="M125.6,150.1c0,2.7-2.2,5-5,5c-2.7,0-5-2.2-5-5c0-2.7,2.2-5,5-5C123.4,145.2,125.6,147.4,125.6,150.1"/> <path class="st1" d="M103.9,154.9c0,3.8-3.1,6.9-6.9,6.9c-3.8,0-6.9-3.1-6.9-6.9c0-3.8,3.1-6.9,6.9-6.9 C100.8,148,103.9,151.1,103.9,154.9"/> <path class="st0" d="M207.3,239.1c0,1.8-1.5,3.3-3.3,3.3s-3.3-1.5-3.3-3.3s1.5-3.3,3.3-3.3S207.3,237.3,207.3,239.1"/> </g> </svg> And my full, completely failed attempt can be found here I guess the real question would be how to find the "d" endpoint of the mouse cursor so I can assign it to the paths.
cx and cy are for circles and ellipses. And you don't need to modify the d attribute for paths either. All you need to do to move any element is apply a translate transform. Ie: <path ... transform="translate(20, 20)"> In Snap you can use the Element.transform() function to apply a transform. Here's a demo where I move each path towards the pointer a little bit every time you move the pointer. function moveFunc( ev, x, y ) { //console.log(ev); paths.forEach(function(el) { // Convert screen mouse coords to the equivalent point in SVG coords var pt = cursorPoint(x, y); // Get the "center" of each path by way of its bounding box var b = el.getBBox(); var cx = b.x + b.width/2; var cy = b.y + b.height/2; // Get the direction vector from the path center to the pointer location var dx = pt.x - cx; var dy = pt.y - cy; // Get the current transform (if any) on the path var currentTransform = el.transform().localMatrix; // Add the tranlation that moves the paths a little toward the pointer currentTransform = currentTransform.translate(dx/20, dy/20); el.transform(currentTransform); }); } // Convert a screen space coordinate to an SVG coordinate function cursorPoint(x, y) { var svg = s.node; var pt = svg.createSVGPoint(); pt.x = x; pt.y = y; return pt.matrixTransform(svg.getScreenCTM().inverse()); } Hopefully this is enough to get you started. To move the <polygon> points, you'll need to get the array of points and then update each point in the array by adding dx,dy. You can get the points of a polygon using el.node.points. Good luck!