How do I use javascript to clone an SVG element? - javascript

I am trying to follow the example here under the cloneNode section (fourth occurrence of 'cloneNode' in the document). The document says it's a DRAFT so i'm wondering if these features don't exist with SVG yet??
Here is my HTML:
<html>
<head>
<script>
var Root=document.documentElement
function clone(){
var G=document.getElementById("groupid")
alert('hi')
var NewG=G.cloneNode(true)
alert('bye')
var move="translate("+0+","+30+")"
NewG.setAttributeNS(null,"transform",move)
Root.appendChild(NewG)
}
clone()
</script>
</head>
<body>
<div style="" width="100px" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200px" viewBox="0 0 1 1" style="fill:purple;stroke:red" id="bigsvg"><?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="100%" height="100%">
<svg width="100%" ID="piece" y="0" x="0" class="black" height="100%">
<g transform="translate(0.005) scale(0.022)" id="groupid">
<path class="onepointsix" d="M 22 9 C 19.792 9 18 10.792 18 13 C 18 13.885103 18.29397 14.712226 18.78125 15.375 C 16.829274 16.496917 15.5 18.588492 15.5 21 C 15.5 23.033947 16.442042 24.839082 17.90625 26.03125 C 14.907101 27.08912 10.5 31.578049 10.5 39.5 L 33.5 39.5 C 33.5 31.578049 29.092899 27.08912 26.09375 26.03125 C 27.557958 24.839082 28.5 23.033948 28.5 21 C 28.5 18.588492 27.170726 16.496917 25.21875 15.375 C 25.70603 14.712226 26 13.885103 26 13 C 26 10.792 24.208 9 22 9 z " />
</g>
</svg>
</svg>
</div>
</body>
</html>
As you can see, the alert 'bye' doesn't work. Thanks in advance for the help.

When you call getElementById, the element doesn't yet exist. Put the script at the end of the body :
<head>
</head>
<body>
<div style="" width="100px" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200px" viewBox="0 0 1 1" style="fill:purple;stroke:red" id="bigsvg"><?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="100%" height="100%">
<svg width="100%" ID="piece" y="0" x="0" class="black" height="100%">
<g transform="translate(0.005) scale(0.022)" id="groupid">
<path class="onepointsix" d="M 22 9 C 19.792 9 18 10.792 18 13 C 18 13.885103 18.29397 14.712226 18.78125 15.375 C 16.829274 16.496917 15.5 18.588492 15.5 21 C 15.5 23.033947 16.442042 24.839082 17.90625 26.03125 C 14.907101 27.08912 10.5 31.578049 10.5 39.5 L 33.5 39.5 C 33.5 31.578049 29.092899 27.08912 26.09375 26.03125 C 27.557958 24.839082 28.5 23.033948 28.5 21 C 28.5 18.588492 27.170726 16.496917 25.21875 15.375 C 25.70603 14.712226 26 13.885103 26 13 C 26 10.792 24.208 9 22 9 z " />
</g>
</svg>
</svg>
</div>
<script>
var Root=document.documentElement
function clone(){
var G=document.getElementById("groupid")
alert('hi')
var NewG=G.cloneNode(true)
alert('bye')
var move="translate("+0+","+30+")"
NewG.setAttributeNS(null,"transform",move)
Root.appendChild(NewG)
}
clone()
</script>
</body>
</html>

This seems to be more complicated than need be. Start with just your pawn path in your root svg. Then clone, and append to root. One of the important things to address that once you clone, you should change the id of the cloned element. Otherwise you will get a conflict when addressing the original cloned element.
Try This:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Title</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body style='font-family:arial'>
<center>
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400" xmlns="http://www.w3.org/2000/svg" >
<path id="pawn" d="M 22 9 C 19.792 9 18 10.792 18 13 C 18 13.885103 18.29397 14.712226 18.78125 15.375 C 16.829274 16.496917 15.5 18.588492 15.5 21 C 15.5 23.033947 16.442042 24.839082 17.90625 26.03125 C 14.907101 27.08912 10.5 31.578049 10.5 39.5 L 33.5 39.5 C 33.5 31.578049 29.092899 27.08912 26.09375 26.03125 C 27.557958 24.839082 28.5 23.033948 28.5 21 C 28.5 18.588492 27.170726 16.496917 25.21875 15.375 C 25.70603 14.712226 26 13.885103 26 13 C 26 10.792 24.208 9 22 9 z " />
</svg>
</div>
<br />SVG Source:<br />
<textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:200px'></textarea>
<br />Javascript:<br />
<textarea id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea>
</center>
<script id=myScript>
var Root=mySVG
function clone(){
var newPawn=pawn.cloneNode(true)
newPawn.id="newPawn1"
var move="translate("+0+","+30+")"
newPawn.setAttribute("transform",move)
Root.appendChild(newPawn)
}
</script>
<script>
document.addEventListener("onload",init(),false)
function init()
{
clone()
svgSourceValue.value=svgDiv.innerHTML
jsValue.value=myScript.text
}
</script>
</body>
</html>

To make it clear what was causing errors:
var Root=document.documentElement was wrong because we need to make sure the new clone gets added to its parent SVG, not at the end of the page. Instead we must add an id="mySVG" to the parent and then use var Root=mySVG.
var G=document.getElementById("groupid") didn't grab the 'groupid' element because the code ran before the element existed. The solution is to trigger the code to run AFTER the page loads (use onload event, or move the script to the bottom of the body).
var move="translate("+0+","+30+")" was replacing the transform property in the SVG group, overwriting the old translate AND the scale(0.022). Therefore, while the clone existed after fixing the above two errors, it was so far down that it was out of the viewBox. Instead I should use var move="translate(0,1) scale(0.022)"

Related

Dynamically create svg group clones which is store in a variable using java script or jquery

i have a lot shapes created using svg tags and which in turn stored in js variables . I want to clone and append the groups to svg element with unique ids using js.
var ped_pb = '<g transform="scale(1.5)" stroke-width=".0005"><path i:knockout="Off" fill-rule="evenodd" clip-rule="evenodd" d="M10.411,0.506V13.17h12.697V0.506H10.411z"/><g> <defs><path id="XMLID_1_" d="M0,0.253h23.87v23.809H0V0.253z"/> </defs> <clipPath id="XMLID_2_"><use xlink:href="#XMLID_1_" /></clipPath><path i:knockout="Off" clip-path="url(#XMLID_2_)" fill="none" stroke="#000000" stroke-width="1.0131" stroke-miterlimit="8" d="M10.411,0.506h12.697V13.17H10.411V0.506z"/></g><g stroke-width=".000000000000000000005"><path i:knockout="Off" clip-path="url(#XMLID_4_)" stroke="#000000" stroke-width="0.0317" stroke-linejoin="round" stroke-miterlimit="10" d="M1.523,23.777l7.555-8.422l-1.523-1.361l-7.523,8.422L1.523,23.777zM7.904,21.782l1.777-8.611l-8.38,2.723c-0.54,0.158-0.825,0.729-0.667,1.267c0.19,0.538,0.762,0.823,1.301,0.665l6.698-2.185l-1.301-1.172l-1.429,6.902c-0.095,0.538,0.254,1.076,0.794,1.203C7.269,22.668,7.777,22.321,7.904,21.782z"/></g></g>';
i need a js function to populate the above shapes stored in variable to an svg element in different x or y coordinates as when required.
i have achieved the goal in the following way
var ped_pb = '<g transform="scale(1.5)" stroke-width=".0005" style="border: 1px dashed black;"><path i:knockout="Off" fill-rule="evenodd" clip-rule="evenodd" d="M10.411,0.506V13.17h12.697V0.506H10.411z"/><g> <defs><path id="XMLID_1_" d="M0,0.253h23.87v23.809H0V0.253z"/> </defs> <clipPath id="XMLID_2_"><use xlink:href="#XMLID_1_" /></clipPath><path i:knockout="Off" clip-path="url(#XMLID_2_)" fill="none" stroke-width="1.0131" stroke-miterlimit="8" d="M10.411,0.506h12.697V13.17H10.411V0.506z"/></g><g stroke-width=".000000000000000000005"><path i:knockout="Off" clip-path="url(#XMLID_4_)" stroke-width="0.0317" stroke-linejoin="round" stroke-miterlimit="10" d="M1.523,23.777l7.555-8.422l-1.523-1.361l-7.523,8.422L1.523,23.777zM7.904,21.782l1.777-8.611l-8.38,2.723c-0.54,0.158-0.825,0.729-0.667,1.267c0.19,0.538,0.762,0.823,1.301,0.665l6.698-2.185l-1.301-1.172l-1.429,6.902c-0.095,0.538,0.254,1.076,0.794,1.203C7.269,22.668,7.777,22.321,7.904,21.782z"/></g></g>';
function clone(){
var element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
element.setAttributeNS(null, 'id', 'lk');
element.innerHTML= ped_pb;
gg.appendChild(element)
element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
element.setAttributeNS(null, 'id', 'lk1');
element.setAttributeNS(null, 'transform', 'translate(40,80)');
element.setAttributeNS(null, 'fill', '#0FF');
element.innerHTML= ped_pb;
gg.appendChild(element)
element = document.createElementNS('http://www.w3.org/2000/svg', 'g');
element.setAttributeNS(null, 'id', 'lk2');
element.setAttributeNS(null, 'transform', 'translate(80,120)');
element.setAttributeNS(null, 'fill', '#f00');
element.innerHTML= ped_pb;
gg.appendChild(element)
}
document.addEventListener("onload",init(),false)
function init()
{
//clone()
clone()
}
<svg id="mySVG" width="400" height="400" xmlns="http://www.w3.org/2000/svg" >
<g id="gg">
<path id="pawn" d="M 22 9 C 19.792 9 18 10.792 18 13 C 18 13.885103 18.29397 14.712226 18.78125 15.375 C 16.829274 16.496917 15.5 18.588492 15.5 21 C 15.5 23.033947 16.442042 24.839082 17.90625 26.03125 C 14.907101 27.08912 10.5 31.578049 10.5 39.5 L 33.5 39.5 C 33.5 31.578049 29.092899 27.08912 26.09375 26.03125 C 27.557958 24.839082 28.5 23.033948 28.5 21 C 28.5 18.588492 27.170726 16.496917 25.21875 15.375 C 25.70603 14.712226 26 13.885103 26 13 C 26 10.792 24.208 9 22 9 z " />
</g>
</svg>

Multiples transformations matrix on SVG, get cursor point

This question is probably more related to math than svg itself.
Inside a main svg, got multiples transformed svg, (from different events), by a viewBox attribute.
Inside those svg, others elements are grouped in a g, modified using matrix transformations.
How to obtain the points on the elements transformed from the mouse pointer.
The goal could be to draw a point or obtain the related point, as a graph chart.
let point = document.getElementById("main").createSVGPoint();
// The mouse cursor points
point.x = 180
point.y = 63
mouse = point.matrixTransform(sub.getCTM())
// console.log(mouse)
// Output
// "x": 611.75439453125,
// "y": 68.71578979492188
// Testing:
circle.setAttribute("cx", 611.75439453125)
circle.setAttribute("cy", 68.71578979492188)
// Not working
<!-- Parent svg -->
<!-- Not preserving aspect ratios -->
<svg id="main" viewBox="0 0 300 400">
<!-- Includes others svg, transformed with a viewBox -->
<!-- Not preserving aspect ratios -->
<svg id="group1" viewBox="7 54 10 570">
<!-- Group element modified with a matrix -->
<!-- Using css to define the matrix behave identicaly -->
<!-- All elements in this group are transformed by this matrix -->
<g id="sub" transform="matrix(4.5,0,0,0.84,-140,99)">
<!-- Exemple element in group -->
<polyline points="4 65.94338623003772 5 78 6 50.10565885410098 7 40.95007190251531 8 53.698867220021675 9 49.43265131064406 10 44.36112722960851 11 56.329540580770356 12 49.785452985846554 13 44.10803037565898 14 40.537830814642945 15 41.84933269419995 16 38.33857254585345 17 43.590332265307744 18 49.16421525342487 19 49.49017332290519 20 42.51658803643061 21 46.943865580139814 22 36.27544970608283 23 38.070136488634255 24 43.46186643792423 25 42.20788657062835 26 48.37424628503659 27 25.58210762671243 28 23.927391073996347 29 22.349370537628886 30 30.592274894669004 31 21.97356005752208 32 24.960869894290738 33 23.221787723591348 34 17.41781668642936 35 2 36 19.335217095138404 37 39.60405681560149 38 38.49579937936788 39 32.47132729520408 40 25.016474506143126 41 27.037414536922626 42 27.541690844412955 43 20.37253071624997 44 9.872846078159213 45 17.79362716653617 46 13.107500567651172 47 24.955117693064494 48 24.247596942250766 49 19.728284178923616 50 11.341574791230315 51 8.248807931982782 52 10.697328253903962 " ></polyline>
<!-- This circle should be at the cursor -->
<circle id="circle" cx="50" cy="50" r="50"fill="blue">
</g>
</svg>
<!-- Rectangles symbolizing the mouse cursor -->
<rect width="1000" height="1" x="0" y="63" ></rect>
<rect width="1" height="500" x="180" y="0"></rect>
</svg>
Svg has numerous bindings related to transformations, we can retrieve the transformation matrix of each elements with getCTM() and getBBox(), and use matrixTransform.
This works for one level of transformation?
How to chain multiples matrix transformations?
If you want the point relative to the transformed area, then it should get reflected as the offsetX and offsetY properties of their corresponding MouseEvents.
However, there seems to be a bug in Webkit / Blink browsers with this regard, so this actually only works in Firefox (and maybe IE?)...
const poly = document.querySelector('polyline');
poly.addEventListener('mousemove', evt => {
circle.setAttribute("cx", evt.offsetX + 2.5);
circle.setAttribute("cy", evt.offsetY + 2.5);
});
<!-- Parent svg -->
<!-- Not preserving aspect ratios -->
<svg id="main" viewBox="0 0 300 400">
<!-- Includes others svg, transformed with a viewBox -->
<!-- Not preserving aspect ratios -->
<svg id="group1" viewBox="7 54 10 570">
<!-- Group element modified with a matrix -->
<!-- Using css to define the matrix behave identicaly -->
<!-- All elements in this group are transformed by this matrix -->
<g id="sub" transform="matrix(4.5,0,0,0.84,-140,99)">
<!-- Exemple element in group -->
<polyline points="4 65.94338623003772 5 78 6 50.10565885410098 7 40.95007190251531 8 53.698867220021675 9 49.43265131064406 10 44.36112722960851 11 56.329540580770356 12 49.785452985846554 13 44.10803037565898 14 40.537830814642945 15 41.84933269419995 16 38.33857254585345 17 43.590332265307744 18 49.16421525342487 19 49.49017332290519 20 42.51658803643061 21 46.943865580139814 22 36.27544970608283 23 38.070136488634255 24 43.46186643792423 25 42.20788657062835 26 48.37424628503659 27 25.58210762671243 28 23.927391073996347 29 22.349370537628886 30 30.592274894669004 31 21.97356005752208 32 24.960869894290738 33 23.221787723591348 34 17.41781668642936 35 2 36 19.335217095138404 37 39.60405681560149 38 38.49579937936788 39 32.47132729520408 40 25.016474506143126 41 27.037414536922626 42 27.541690844412955 43 20.37253071624997 44 9.872846078159213 45 17.79362716653617 46 13.107500567651172 47 24.955117693064494 48 24.247596942250766 49 19.728284178923616 50 11.341574791230315 51 8.248807931982782 52 10.697328253903962 " ></polyline>
<!-- This circle should be at the cursor -->
<circle id="circle" cx="5" cy="5" r="5" fill="blue" pointer-events="none">
</g>
</svg>
<!-- Rectangles symbolizing the mouse cursor -->
<rect width="1000" height="1" x="0" y="63" ></rect>
<rect width="1" height="500" x="180" y="0"></rect>
</svg>
If you wish to transform arbitrary values, then you use the technique described in this Answer which consists in dispatching such a MouseEvent on your element:
const point = {x:180, y:63};
const poly = document.querySelector('polyline');
poly.addEventListener('mousemove', evt => {
point.x = evt.offsetX;
point.y = evt.offsetY;
}, {once: true});
const evt = new MouseEvent('mousemove', {
clientX: point.x,
clientY: point.y
});
poly.dispatchEvent(evt);
console.log(point);
circle.setAttribute("cx", point.x);
circle.setAttribute("cy", point.y);
<!-- Parent svg -->
<!-- Not preserving aspect ratios -->
<svg id="main" viewBox="0 0 300 400">
<!-- Includes others svg, transformed with a viewBox -->
<!-- Not preserving aspect ratios -->
<svg id="group1" viewBox="7 54 10 570">
<!-- Group element modified with a matrix -->
<!-- Using css to define the matrix behave identicaly -->
<!-- All elements in this group are transformed by this matrix -->
<g id="sub" transform="matrix(4.5,0,0,0.84,-140,99)">
<!-- Exemple element in group -->
<polyline points="4 65.94338623003772 5 78 6 50.10565885410098 7 40.95007190251531 8 53.698867220021675 9 49.43265131064406 10 44.36112722960851 11 56.329540580770356 12 49.785452985846554 13 44.10803037565898 14 40.537830814642945 15 41.84933269419995 16 38.33857254585345 17 43.590332265307744 18 49.16421525342487 19 49.49017332290519 20 42.51658803643061 21 46.943865580139814 22 36.27544970608283 23 38.070136488634255 24 43.46186643792423 25 42.20788657062835 26 48.37424628503659 27 25.58210762671243 28 23.927391073996347 29 22.349370537628886 30 30.592274894669004 31 21.97356005752208 32 24.960869894290738 33 23.221787723591348 34 17.41781668642936 35 2 36 19.335217095138404 37 39.60405681560149 38 38.49579937936788 39 32.47132729520408 40 25.016474506143126 41 27.037414536922626 42 27.541690844412955 43 20.37253071624997 44 9.872846078159213 45 17.79362716653617 46 13.107500567651172 47 24.955117693064494 48 24.247596942250766 49 19.728284178923616 50 11.341574791230315 51 8.248807931982782 52 10.697328253903962 " ></polyline>
<!-- This circle should be at the cursor -->
<circle id="circle" cx="5" cy="5" r="5" fill="blue" pointer-events="none">
</g>
</svg>
<!-- Rectangles symbolizing the mouse cursor -->
<rect width="1000" height="1" x="0" y="63" ></rect>
<rect width="1" height="500" x="180" y="0"></rect>
</svg>
Note that WebKit / Blink do set it correctly on HTML elements as demonstrated in this Q/A...
The problem is that getCTM() only returns the transformation up to the nearest enclosing <svg> element. Instead you can use getScreenCTM() to calculate the transformation relative to the window. Except we actually need to take the inverse of this transformation so it will be subtracted it from the mouse point. Then we make sure everything is relative to the top-level svg container.
This will be accurate no matter how many layers of transformations the target element is nested under.
<svg id="main" viewBox="0 0 300 400">
<svg id="group1" viewBox="7 54 10 570">
<g id="sub" transform="matrix(4.5,0,0,0.84,-140,99)">
<polyline points="4 65.94338623003772 5 78 6 50.10565885410098 7 40.95007190251531 8 53.698867220021675 9 49.43265131064406 10 44.36112722960851 11 56.329540580770356 12 49.785452985846554 13 44.10803037565898 14 40.537830814642945 15 41.84933269419995 16 38.33857254585345 17 43.590332265307744 18 49.16421525342487 19 49.49017332290519 20 42.51658803643061 21 46.943865580139814 22 36.27544970608283 23 38.070136488634255 24 43.46186643792423 25 42.20788657062835 26 48.37424628503659 27 25.58210762671243 28 23.927391073996347 29 22.349370537628886 30 30.592274894669004 31 21.97356005752208 32 24.960869894290738 33 23.221787723591348 34 17.41781668642936 35 2 36 19.335217095138404 37 39.60405681560149 38 38.49579937936788 39 32.47132729520408 40 25.016474506143126 41 27.037414536922626 42 27.541690844412955 43 20.37253071624997 44 9.872846078159213 45 17.79362716653617 46 13.107500567651172 47 24.955117693064494 48 24.247596942250766 49 19.728284178923616 50 11.341574791230315 51 8.248807931982782 52 10.697328253903962 " />
<circle id="circle" cx="50" cy="50" r="50" fill="blue" />
</g>
</svg>
<rect width="1000" height="1" x="0" y="63" />
<rect width="1" height="500" x="180" y="0" />
<script>
let sub = document.getElementById('sub');
let circle = document.getElementById('circle');
let main = document.getElementById("main");
let mouse = main.createSVGPoint();
mouse.x = 180; mouse.y = 63;
function getMatrix(el) {
let matrix = el.getScreenCTM().inverse();
matrix = matrix.multiply(main.getScreenCTM());
return matrix;
}
let result = mouse.matrixTransform(getMatrix(sub));
circle.setAttribute("cx", result.x);
circle.setAttribute("cy", result.y);
</script>
</svg>

SVG: dynamically created <use> won't show [duplicate]

One of the use elements is created dynamically, one is created statically. I have written a jsfiddle.
https://jsfiddle.net/rhedin/r0dbf6uy/6/
<!doctype html>
<body>
<svg
id="svg_box"
width="200px"
height="100px"
viewBox="0 0 200 100"
style="background-color:pink"
>
<defs>
<g id="b">
<path d="m 4.23,7.7400001 0,-7.14000002 C 4.23,0.18000008 3.96,7.6293944e-8 3.39,7.6293944e-8 l -2.22,0 C 0.39000002,7.6293944e-8 1.9073486e-8,0.36000008 1.9073486e-8,1.0500001 c 0,0.75 0.420000000926514,1.02 1.349999980926514,1.02 0.21,0 0.45,0.03 0.66,0.03 L 2.01,17.1 c -0.12,0 -0.21,0 -0.3,0 C 0.51000002,17.1 1.9073486e-8,17.28 1.9073486e-8,18.12 1.9073486e-8,18.81 0.39000002,19.17 1.17,19.17 l 2.67,0 c 0.45,0 0.6,-0.24 0.6,-0.75 l 0,-1.17 c 0.99,1.47 2.52,2.19 4.56,2.19 3.93,0 6.93,-3.09 6.93,-6.9 0,-3.8699999 -2.94,-6.8999999 -6.87,-6.8999999 -2.07,0 -3.72,0.72 -4.83,2.1 z M 8.79,17.13 c -2.73,0 -4.62,-1.98 -4.62,-4.68 0,-2.7299999 1.92,-4.6799999 4.62,-4.6799999 2.73,0 4.62,2.01 4.62,4.6799999 0,2.79 -1.89,4.68 -4.62,4.68 z" />
</g>
</defs>
<use x="130px" y="10px" xlink:href="#b" />
</svg>
<script>
var svgElt = document.getElementById('svg_box');
var newUse = document.createElementNS("http://www.w3.org/2000/svg", 'use');
newUse.setAttribute('x', '150px');
newUse.setAttribute('y', '10px');
newUse.setAttribute('xlink:href', '#b');
svgElt.appendChild(newUse);
</script>
</body>
Two both appear the same in Chrome's debugger. Why does only one show up?
Thanks, Rick
You can't set an xlink:href attribute using setAttribute, you need to use setAttributeNS
var svgElt = document.getElementById('svg_box');
var newUse = document.createElementNS("http://www.w3.org/2000/svg", 'use');
newUse.setAttribute('x', '150px');
newUse.setAttribute('y', '10px');
newUse.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#b');
svgElt.appendChild(newUse);
<!doctype html>
<body>
<svg
id="svg_box"
width="200px"
height="100px"
viewBox="0 0 200 100"
style="background-color:pink"
>
<defs>
<g id="b">
<path d="m 4.23,7.7400001 0,-7.14000002 C 4.23,0.18000008 3.96,7.6293944e-8 3.39,7.6293944e-8 l -2.22,0 C 0.39000002,7.6293944e-8 1.9073486e-8,0.36000008 1.9073486e-8,1.0500001 c 0,0.75 0.420000000926514,1.02 1.349999980926514,1.02 0.21,0 0.45,0.03 0.66,0.03 L 2.01,17.1 c -0.12,0 -0.21,0 -0.3,0 C 0.51000002,17.1 1.9073486e-8,17.28 1.9073486e-8,18.12 1.9073486e-8,18.81 0.39000002,19.17 1.17,19.17 l 2.67,0 c 0.45,0 0.6,-0.24 0.6,-0.75 l 0,-1.17 c 0.99,1.47 2.52,2.19 4.56,2.19 3.93,0 6.93,-3.09 6.93,-6.9 0,-3.8699999 -2.94,-6.8999999 -6.87,-6.8999999 -2.07,0 -3.72,0.72 -4.83,2.1 z M 8.79,17.13 c -2.73,0 -4.62,-1.98 -4.62,-4.68 0,-2.7299999 1.92,-4.6799999 4.62,-4.6799999 2.73,0 4.62,2.01 4.62,4.6799999 0,2.79 -1.89,4.68 -4.62,4.68 z" />
</g>
</defs>
<use x="130px" y="10px" xlink:href="#b" />
</svg>
</body>

How to animate SVG?

I'd like to use the jQuery "animate"-call to animate a SVG.
The SVG should get for example rotated or or scaled.
What I've tried so far was this simple code but obviously this is not working so far:
$("#svg").animate({
transform: "scale(0.4)"
}, 400)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200px" viewBox="0 0 1 1" style="fill:purple;stroke:red" id="svg">
<svg width="100%" height="100%">
<svg width="100%" ID="piece" y="0" x="0" class="black" height="100%">
<g transform="translate(0.005) scale(0.022)">
<path d="M 22 9 C 19.792 9 18 10.792 18 13 C 18 13.885103 18.29397 14.712226 18.78125 15.375 C 16.829274 16.496917 15.5 18.588492 15.5 21 C 15.5 23.033947 16.442042 24.839082 17.90625 26.03125 C 14.907101 27.08912 10.5 31.578049 10.5 39.5 L 33.5 39.5 C 33.5 31.578049 29.092899 27.08912 26.09375 26.03125 C 27.557958 24.839082 28.5 23.033948 28.5 21 C 28.5 18.588492 27.170726 16.496917 25.21875 15.375 C 25.70603 14.712226 26 13.885103 26 13 C 26 10.792 24.208 9 22 9 z " />
</g>
</svg>
I also added this line $("#svg").css({transform: "scale(0.4)"}) to try if the scale style will be applied on the element, and however - this is working.
How can I fix this issue why I'm not be able to animate the SVG element? Any help would be very appreciated, thanks.
You want it to animate and reduce the svg that's right ?
Here's a snipper where it works
$("#svg").animate({
width: "10%", height: "10%"
}, 400)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200px" viewBox="0 0 1 1" style="fill:purple;stroke:red" id="svg">
<svg width="100%" height="100%">
<svg width="100%" ID="piece" y="0" x="0" class="black" height="100%">
<g transform="translate(0.005) scale(0.022)">
<path d="M 22 9 C 19.792 9 18 10.792 18 13 C 18 13.885103 18.29397 14.712226 18.78125 15.375 C 16.829274 16.496917 15.5 18.588492 15.5 21 C 15.5 23.033947 16.442042 24.839082 17.90625 26.03125 C 14.907101 27.08912 10.5 31.578049 10.5 39.5 L 33.5 39.5 C 33.5 31.578049 29.092899 27.08912 26.09375 26.03125 C 27.557958 24.839082 28.5 23.033948 28.5 21 C 28.5 18.588492 27.170726 16.496917 25.21875 15.375 C 25.70603 14.712226 26 13.885103 26 13 C 26 10.792 24.208 9 22 9 z " />
</g>
</svg>
Here's the documentation to use the animate function : here
or do it with CSS
#svg {
animation: reduce 2s 2; /* To make the animation twice */
}
#keyframes reduce {
from {transform : scale(1);}
to {transform : scale(0.4);}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200px" viewBox="0 0 1 1" style="fill:purple;stroke:red" id="svg">
<svg width="100%" height="100%">
<svg width="100%" ID="piece" y="0" x="0" class="black" height="100%">
<g transform="translate(0.005) scale(0.022)">
<path d="M 22 9 C 19.792 9 18 10.792 18 13 C 18 13.885103 18.29397 14.712226 18.78125 15.375 C 16.829274 16.496917 15.5 18.588492 15.5 21 C 15.5 23.033947 16.442042 24.839082 17.90625 26.03125 C 14.907101 27.08912 10.5 31.578049 10.5 39.5 L 33.5 39.5 C 33.5 31.578049 29.092899 27.08912 26.09375 26.03125 C 27.557958 24.839082 28.5 23.033948 28.5 21 C 28.5 18.588492 27.170726 16.496917 25.21875 15.375 C 25.70603 14.712226 26 13.885103 26 13 C 26 10.792 24.208 9 22 9 z " />
</g>
</svg>
I make the animation twice but do as you want with the animation-iteration-count property : documentation here
Wish it helped you !
Also one good web tool what SVG Gator made you can try here:
https://app.svgator.com/
There is a few assets of animations.
Best regards.

How can this path stroke set the opacity of the group behind it?

I have this code which shows my current output when the snippet is run.
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 300 300" viewBox="0 0 300 300" x="0px" y="0px" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:space="preserve" version="1.1">
<g fill-opacity=".2">
<path fill="#f79820" d="M 150 0 c 82.8 0 150 67.2 150 150 s -67.2 150 -150 150 S 0 232.8 0 150 S 67.2 0 150 0" />
<circle fill="#f5f4b7" cx="150" cy="150" r="141.9" />
<path fill="#f79820" d="M 135.7 103.3 c 3.5 18.3 4 19 7.8 19.2 c 3.8 0.2 10.4 -4.1 13.6 -12.1 c 3.1 -8 5 -20.2 7.8 -27.9 s 15.4 -29.6 18.7 -39.2 s 0.2 -19.2 -3.1 -23.6 c -3.3 -4.4 -10.7 -4.4 -23.5 -3.4 c -12.7 1 -33.4 -0.1 -40.8 3.4 c -8.4 3.9 -12.1 4.8 -8.9 15.5 C 110.2 45.9 132.2 84.9 135.7 103.3 Z" />
<path fill="#f79820" d="M 153.9 124.2 c -1.7 2.9 3.3 5.6 5.3 5.6 c 2 0 10.1 -2.9 23 -10.4 c 12.9 -7.5 49.9 -25.1 60.2 -35.2 c 10.2 -10 4.3 -22.8 0 -28.9 c -4.3 -6.1 -21 -22.8 -34.4 -29.7 c -13.4 -7 -16.7 1.2 -19.2 12.4 c -2.5 11.2 -12.1 31.1 -15.4 38.2 C 170 83.4 155.5 121.3 153.9 124.2 Z" />
<path fill="#f79820" d="M 213.5 108.7 c -23.7 12.8 -50.5 24.7 -50.4 27.2 c 0.1 3.1 11.1 6.5 27.4 9.9 c 16.4 3.4 29.1 2.5 44.6 9 c 15.5 6.5 36.7 9.9 45 -5.4 s 0.5 -47.6 -8.3 -58.1 c -8.8 -10.5 -10.9 -15.1 -25.6 -3.6 C 240.8 92 227.6 101.1 213.5 108.7 Z" />
<path fill="#f79820" d="M 283.6 167.2 c -2.2 -8.7 -11.1 1.4 -55.9 -8.5 c -44.8 -9.9 -60.7 -13.6 -63 -10.2 c -1.3 1.9 13.4 14.1 36 25.1 c 22.5 11 34.6 21.6 43.7 27.9 c 9.1 6.3 20.2 6.3 26.9 0 C 278.1 195.2 285.8 175.8 283.6 167.2 Z" />
<path fill="#f79820" d="M 226.6 194.7 c -16 -3.6 -35.4 -19 -42.1 -23.8 c -6.8 -4.8 -21.2 -17.1 -25.4 -13.3 c -2.6 2.4 -0.7 15.6 8.4 38.7 s 18.7 56.7 21.6 73.6 c 3 16.8 10.9 9.5 19 2.5 c 8.1 -7 26.4 -21.4 40 -30.7 c 13.6 -9.3 11.6 -19 10.1 -21.7 S 242.6 198.2 226.6 194.7 Z" />
<path fill="#f79820" d="M 157.9 178.9 c -4.1 -13.1 -5.2 -20.5 -9 -20.4 c -4.5 0.2 -9.1 18.7 -12.4 27.4 c -3.3 8.7 -12.7 52.3 -16.7 72.4 c -4 20 -1.8 25.8 15.2 26.7 s 36.7 4.9 42.8 -1 c 6.1 -5.9 5.3 -23.1 0 -44.5 C 172.5 217.9 161.9 192 157.9 178.9 Z" />
<path fill="#f79820" d="M 135.5 171.9 c 2.5 -9.2 3.2 -13.5 -2 -14.3 c -7.1 -1 -17.5 10.5 -25.3 22.1 S 77.5 213.4 63 228.7 c -14.5 15.3 -4 23.8 16 36.2 c 20 12.4 27.9 13.8 31.6 10.9 c 3.6 -2.9 6.6 -26.3 11.1 -43.8 C 126.1 214.4 133 181.1 135.5 171.9 Z" />
<path fill="#f79820" d="M 61.1 227.1 c 5.1 -6.8 32.2 -34.3 40 -44.8 c 7.8 -10.5 26.3 -28.2 27.9 -29.2 c 1.7 -1 -1.1 -4 -3.8 -6.8 c -2.1 -2.1 -2.8 -1.2 -11.1 0 c -8.3 1.2 -39 13.4 -53.4 17.7 c -14.4 4.2 -22.5 3.9 -31.1 7.5 c -8.6 3.6 -11.7 12.4 -1.7 26.8 c 10.1 14.4 6.3 18.9 13.6 28.9 C 48.9 237.1 56 233.9 61.1 227.1 Z" />
<path fill="#f79820" d="M 25.8 169.4 c 9.1 -1 41.5 -11.6 59.2 -18.9 c 17.7 -7.3 40.9 -11.4 40.7 -13.9 c -0.5 -5.6 -29.9 -17 -40.5 -22.6 c -10.6 -5.6 -25 -19.9 -35.4 -25.1 c -10.4 -5.3 -23.3 -4.8 -25.4 8.2 c -2.1 12.9 -8.8 27.9 -11.4 48 C 10.2 165.1 16.7 170.4 25.8 169.4 Z" />
<path fill="#f79820" d="M 54.5 88.3 c 16 5.4 37.5 19.7 43.1 24 c 5.6 4.2 31.2 20.9 35.2 17.5 c 3.4 -2.9 0.3 -21.1 -6.3 -31.8 c -6.6 -10.7 -9.1 -29.4 -14.5 -45.2 c -5.5 -15.8 -17.7 -28.4 -34 -18 s -33.4 24.8 -37.8 36 C 35.7 82 38.5 82.9 54.5 88.3 Z" />
</g>
<svg style="display: block; width: 100%;" viewBox="0 0 100 100">
<path stroke="#f79820" stroke-opacity=".4" fill-opacity="0" style="stroke-dasharray: 157.698, 157.698; stroke-dashoffset: 55;" stroke-width="49.81" d="M 50,50 m 0,-25.095 a 25.095,25.095 0 1 1 0,50.19 a 25.095,25.095 0 1 1 0,-50.19" />
</svg>
</svg>
My goal is to get everything covered by the stroke to be shown "darker" than the remaining portion of the circle. However the effect that is happening is the opacity of the stroke is compounding with the groups opacity so it doesn't have the contrast it needs to have.
Ideally it would look something like this...
Would inverting the pieces be an option? Instead of darkening the section, lighten the inverse? I removed the fill-opacity on the outer svg, changed the stroke of the inner path to white and increased the opacity to .6. I did not change the path, though, this was just to demonstrate the concept.
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 300 300" viewBox="0 0 300 300" x="0px" y="0px" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:space="preserve" version="1.1">
<g>
<path fill="#f79820" d="M 150 0 c 82.8 0 150 67.2 150 150 s -67.2 150 -150 150 S 0 232.8 0 150 S 67.2 0 150 0" />
<circle fill="#f5f4b7" cx="150" cy="150" r="141.9" />
<path fill="#f79820" d="M 135.7 103.3 c 3.5 18.3 4 19 7.8 19.2 c 3.8 0.2 10.4 -4.1 13.6 -12.1 c 3.1 -8 5 -20.2 7.8 -27.9 s 15.4 -29.6 18.7 -39.2 s 0.2 -19.2 -3.1 -23.6 c -3.3 -4.4 -10.7 -4.4 -23.5 -3.4 c -12.7 1 -33.4 -0.1 -40.8 3.4 c -8.4 3.9 -12.1 4.8 -8.9 15.5 C 110.2 45.9 132.2 84.9 135.7 103.3 Z" />
<path fill="#f79820" d="M 153.9 124.2 c -1.7 2.9 3.3 5.6 5.3 5.6 c 2 0 10.1 -2.9 23 -10.4 c 12.9 -7.5 49.9 -25.1 60.2 -35.2 c 10.2 -10 4.3 -22.8 0 -28.9 c -4.3 -6.1 -21 -22.8 -34.4 -29.7 c -13.4 -7 -16.7 1.2 -19.2 12.4 c -2.5 11.2 -12.1 31.1 -15.4 38.2 C 170 83.4 155.5 121.3 153.9 124.2 Z" />
<path fill="#f79820" d="M 213.5 108.7 c -23.7 12.8 -50.5 24.7 -50.4 27.2 c 0.1 3.1 11.1 6.5 27.4 9.9 c 16.4 3.4 29.1 2.5 44.6 9 c 15.5 6.5 36.7 9.9 45 -5.4 s 0.5 -47.6 -8.3 -58.1 c -8.8 -10.5 -10.9 -15.1 -25.6 -3.6 C 240.8 92 227.6 101.1 213.5 108.7 Z" />
<path fill="#f79820" d="M 283.6 167.2 c -2.2 -8.7 -11.1 1.4 -55.9 -8.5 c -44.8 -9.9 -60.7 -13.6 -63 -10.2 c -1.3 1.9 13.4 14.1 36 25.1 c 22.5 11 34.6 21.6 43.7 27.9 c 9.1 6.3 20.2 6.3 26.9 0 C 278.1 195.2 285.8 175.8 283.6 167.2 Z" />
<path fill="#f79820" d="M 226.6 194.7 c -16 -3.6 -35.4 -19 -42.1 -23.8 c -6.8 -4.8 -21.2 -17.1 -25.4 -13.3 c -2.6 2.4 -0.7 15.6 8.4 38.7 s 18.7 56.7 21.6 73.6 c 3 16.8 10.9 9.5 19 2.5 c 8.1 -7 26.4 -21.4 40 -30.7 c 13.6 -9.3 11.6 -19 10.1 -21.7 S 242.6 198.2 226.6 194.7 Z" />
<path fill="#f79820" d="M 157.9 178.9 c -4.1 -13.1 -5.2 -20.5 -9 -20.4 c -4.5 0.2 -9.1 18.7 -12.4 27.4 c -3.3 8.7 -12.7 52.3 -16.7 72.4 c -4 20 -1.8 25.8 15.2 26.7 s 36.7 4.9 42.8 -1 c 6.1 -5.9 5.3 -23.1 0 -44.5 C 172.5 217.9 161.9 192 157.9 178.9 Z" />
<path fill="#f79820" d="M 135.5 171.9 c 2.5 -9.2 3.2 -13.5 -2 -14.3 c -7.1 -1 -17.5 10.5 -25.3 22.1 S 77.5 213.4 63 228.7 c -14.5 15.3 -4 23.8 16 36.2 c 20 12.4 27.9 13.8 31.6 10.9 c 3.6 -2.9 6.6 -26.3 11.1 -43.8 C 126.1 214.4 133 181.1 135.5 171.9 Z" />
<path fill="#f79820" d="M 61.1 227.1 c 5.1 -6.8 32.2 -34.3 40 -44.8 c 7.8 -10.5 26.3 -28.2 27.9 -29.2 c 1.7 -1 -1.1 -4 -3.8 -6.8 c -2.1 -2.1 -2.8 -1.2 -11.1 0 c -8.3 1.2 -39 13.4 -53.4 17.7 c -14.4 4.2 -22.5 3.9 -31.1 7.5 c -8.6 3.6 -11.7 12.4 -1.7 26.8 c 10.1 14.4 6.3 18.9 13.6 28.9 C 48.9 237.1 56 233.9 61.1 227.1 Z" />
<path fill="#f79820" d="M 25.8 169.4 c 9.1 -1 41.5 -11.6 59.2 -18.9 c 17.7 -7.3 40.9 -11.4 40.7 -13.9 c -0.5 -5.6 -29.9 -17 -40.5 -22.6 c -10.6 -5.6 -25 -19.9 -35.4 -25.1 c -10.4 -5.3 -23.3 -4.8 -25.4 8.2 c -2.1 12.9 -8.8 27.9 -11.4 48 C 10.2 165.1 16.7 170.4 25.8 169.4 Z" />
<path fill="#f79820" d="M 54.5 88.3 c 16 5.4 37.5 19.7 43.1 24 c 5.6 4.2 31.2 20.9 35.2 17.5 c 3.4 -2.9 0.3 -21.1 -6.3 -31.8 c -6.6 -10.7 -9.1 -29.4 -14.5 -45.2 c -5.5 -15.8 -17.7 -28.4 -34 -18 s -33.4 24.8 -37.8 36 C 35.7 82 38.5 82.9 54.5 88.3 Z" />
</g>
<svg style="display: block; width: 100%;" viewBox="0 0 100 100">
<path stroke="#ffffff" stroke-opacity=".6" fill-opacity="0" style="stroke-dasharray: 157.698, 157.698; stroke-dashoffset: 55;" stroke-width="49.81" d="M 50,50 m 0,-25.095 a 25.095,25.095 0 1 1 0,50.19 a 25.095,25.095 0 1 1 0,-50.19" />
</svg>
</svg>

Categories

Resources