I am working with svg animation right now. I want to setup morph animation on this svg. For example the vibe icon will be morph with Wibe on hover of the image. I try few examples from the stackoverflow. But that is not working. Right now the current animation on this image is rotating E of wibe and floating vibe icon.
Please help me regarding this issue. How can I use morph animation in this.
Thanks
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1491.3333 803.33069"
height="500"
width="700"
xml:space="preserve"
id="svg2"
version="1.1" style="
background-color: #000;
"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath18"
clipPathUnits="userSpaceOnUse"><path
id="path16"
d="M 0,602.498 H 1118.496 V 0 H 0 Z" /></clipPath></defs><g
transform="matrix(1.3333333,0,0,-1.3333333,0,803.33067)"
id="g10"><g
id="g12"><g
clip-path="url(#clipPath18)"
id="g14"><g
transform="translate(665.3598,379.7295)"
id="g20"><path
id="path22"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="m 0,0 h 26.962 c 13.938,0 23.293,3.023 28.064,9.077 4.763,6.046 7.149,12.378 7.149,18.979 0,6.235 -2.475,12.003 -7.427,17.33 C 49.789,50.705 40.72,53.36 27.517,53.36 23.481,53.36 18.8,53.262 13.481,53.083 8.17,52.902 3.676,52.625 0,52.265 Z m 0,-57.764 v -56.668 c 1.111,0 4.044,-0.18 8.807,-0.548 4.772,-0.367 11.193,-0.547 19.257,-0.547 15.409,0 26.407,2.566 33.001,7.696 6.609,5.139 9.91,12.296 9.91,21.456 0,3.675 -0.638,7.246 -1.921,10.727 -1.29,3.481 -3.578,6.512 -6.879,9.085 -3.301,2.565 -7.891,4.673 -13.758,6.316 -5.859,1.658 -13.563,2.483 -23.098,2.483 z m -91.859,165.587 c 7.337,1.095 15.769,2.108 25.303,3.023 9.535,0.923 19.25,1.74 29.152,2.483 9.911,0.728 19.535,1.276 28.882,1.643 9.355,0.368 17.509,0.548 24.486,0.548 45.843,0 80.134,-6.504 102.872,-19.527 22.738,-13.016 34.103,-33.278 34.103,-60.787 0,-13.931 -3.203,-25.761 -9.625,-35.483 -6.414,-9.715 -15.131,-18.057 -26.129,-25.034 15.402,-5.506 28.057,-13.383 37.959,-23.645 9.91,-10.278 14.854,-24.756 14.854,-43.473 0,-33.728 -12.468,-57.104 -37.411,-70.134 -24.937,-13.016 -61.793,-19.528 -110.569,-19.528 -12.836,0 -29.617,0.458 -50.337,1.373 -20.727,0.923 -41.898,2.851 -63.54,5.784 z m -25.049,-282.757 c -9.535,-1.47 -18.154,-2.573 -25.859,-3.3 -7.697,-0.743 -14.666,-1.111 -20.9,-1.111 -6.233,0 -13.21,0.368 -20.907,1.111 -7.704,0.727 -16.129,1.83 -25.296,3.3 v 283.852 c 8.057,1.838 16.031,3.121 23.923,3.848 7.892,0.743 15.491,1.111 22.828,1.111 6.969,0 14.494,-0.368 22.55,-1.111 8.072,-0.727 15.957,-2.01 23.661,-3.848 z m -237.89,119.924 34.102,163.928 c 2.941,0.735 8.62,1.463 17.06,2.206 8.439,0.727 17.426,1.095 26.961,1.095 12.1,0 22.828,-0.368 32.182,-1.095 9.348,-0.743 16.039,-1.471 20.076,-2.206 l -89.129,-283.304 c -6.234,-1.838 -13.016,-3.031 -20.345,-3.578 -7.344,-0.548 -14.674,-0.818 -22.003,-0.818 -7.344,0 -14.771,0.27 -22.287,0.818 -7.51,0.547 -15.304,1.74 -23.376,3.578 l -40.157,154.034 c -6.969,-24.576 -14.028,-50.427 -21.184,-77.569 -7.15,-27.141 -14.029,-52.625 -20.631,-76.465 -7.697,-1.838 -15.311,-3.031 -22.827,-3.578 -7.518,-0.548 -14.944,-0.818 -22.273,-0.818 -7.344,0 -14.674,0.27 -22.011,0.818 -7.336,0.547 -14.118,1.74 -20.352,3.578 l -86.368,283.304 c 4.029,0.735 11.095,1.463 21.178,2.206 10.083,0.727 21.177,1.095 33.278,1.095 9.535,0 18.799,-0.368 27.786,-1.095 8.987,-0.743 14.936,-1.471 17.877,-2.206 l 35.761,-168.332 39.609,168.332 c 6.234,1.838 13.113,3.031 20.63,3.586 7.509,0.54 14.936,0.825 22.273,0.825 7.336,0 14.763,-0.285 22.287,-0.825 7.517,-0.555 15.124,-1.748 22.821,-3.586 z" /></g><g
transform="translate(220.8446,208.5321)"
id="g24"><path
id="path26"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="M 0,0 C 62.399,-4.247 111.294,-96.425 205.706,-86.576 172.84,-130.659 92.497,-208.532 24.911,-208.532 -117.925,-208.532 -130.651,8.887 0,0" /> <animateMotion
path="M10,50 q60,50 100,0 q60,-50 100,0"
begin="g10.mouseover" dur="10s" repeatCount="indefinite" end="g10.mouseout"
/></g><g
transform="translate(580.4182,121.9514)"
id="g28"><path
id="path30"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="M 0,0 C -85.441,36.938 -117.17,22.297 -153.931,0 -105.978,83.683 -54.72,98.899 0,0" /> <animateMotion
path="M10,50 q60,50 100,0 q60,-50 100,0"
begin="g10.mouseover" dur="10s" repeatCount="indefinite" end="g10.mouseout"
/></g><g
transform="translate(653.5858,147.7134)"
id="g32"><path
id="path34"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="M 0,0 C -13.413,-15.054 -31.372,-29.682 -73.072,-25.757 -16.196,-124.558 53.294,-118.125 91.542,-83.726 164.849,-17.787 68.09,76.417 0,0" /> <animateMotion
path="M10,50 q60,50 100,0 q60,-50 100,0"
begin="g10.mouseover" dur="10s" repeatCount="indefinite" end="g10.mouseout"
/></g><g
transform="translate(925.3088,392.7031)"
id="g36"><path
id="path38"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="m 0,0 c 0,0 0,41.564 40.817,43.368 40.271,1.78 44.37,-43.33 44.37,-43.33 z M 81.95,103.607 C -68.673,133.163 -111.656,-7.91 -72.935,-117.879 c 0,0 48.014,-94.48 168.825,-63.503 l -1.549,75.894 c 0,0 -80.541,-21.684 -86.736,37.172 l 159.346,2.403 c 0,0 34.441,146.082 -85.001,169.52" /><animateTransform attributeType="xml" attributeName="transform" type="rotate" from="360 8.4 9.5" to="0 8.4 9.5" dur="0.5s" additive="sum" begin="g10.mouseover" repeatCount="1" end="g10.mouseout" /></g></g></g></g>
</svg>
Years back, Dan Miller had the same problem, as I have now, as they wanted a function (JavaScript) to get SVG elements by class. Dan proposed a function, but users were unable to run it:
function getSvgElemByClass(svgRoot,classSearchStr) {
// modification of Dustin Diaz's find by class script - http://www.dustindiaz.com/getelementsbyclass/
return(
function getSvgElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
node = document;
if ( tag == null )
tag = '*';
// SVG = XML, so we need the XML method:
// using 'magic' namespace variable provided by websvg (svgns)
var els = node.getElementsByTagNameNS(svgns,tag);
var elsLen = els.length;
var pattern = new RegExp('(^|\\\\s)'+searchClass+'(\\\\s|$)');
for (i = 0, j = 0; i < elsLen; i++) {
// SVG specific helper
if(els[i].hasAttribute('class') &&
pattern.test(els[i].getAttribute('class')) ) {
classElements[j] = els[i];
j++;
} else if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
)(classSearchStr,svgRoot)
}
An .svg file could look like this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg1024" viewBox="0 0 20 20" width="20" height="20">
<style id="style_css_sheet" type="text/css">
.land
{
fill: #00ff00;
stroke-width: 0.2;
stroke: #e0e0e0;
}
.aa, .ab
{
fill: #ff0000;
}
</style>
<g class="land bg"
id="A">
<path d="M 0,5 H 5 V 0 H 0 Z"
id="aa" class="land er bg"/>
<path d="m 10,5 h 5 V 0 h -5 z"
id="ab" class="land er bg"/>
<path d="m 5,5 h 5 V 0 H 5 Z"
id="ac" class="land tt bg"/>
</g>
<path d="M 0,10 H 5 v -5 H 0 Z"
id="ba" class="land er au"/>
<path d="m 10,10 h 5 v -5 h -5 z"
id="bb" class="land tt au"/>
<path d="m 5,10 h 5 v -5 H 5 Z"
id="bc" class="land er au"/>
<path d="M 0,15 H 5 V 10 H 0 Z"
id="ca" class="land tt bg"/>
<path d="m 10,15 h 5 V 10 h -5 z"
id="cb" class="land tt au"/>
<path d="m 5,15 h 5 V 10 H 5 Z"
id="cc" class="land er bg"/>
</svg>
From html I would like to select by class, like select all class "tt", or select all class "au". Tried with the script of Dan Miller, tried to fix it, but could not do it.
I would like to override the values set in the svg. (change .land {fill: #00ff00;})
I use this script
https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.5/svg.js
So that I can draw by id. That works, if I remove the .land{...}:
var element = SVG.get('fi');
element.fill('#f06')
How could I select by class? What to do, so that I can leave default colouring (.land{...})?
Simply use jQuery to change the fill by class:
$('.land').css('fill', '#0000ff')
Working Codepen.
You mention jQuery in your title, but later just Javascript.
jQuery is not required. Modern browsers have the document.getElementsByClassName() method.
var tt = document.getElementsByClassName("tt");
Array.from(tt).forEach(function(item) {
item.style.fill = "#0000ff";
});
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg1024" viewBox="0 0 20 20" width="20" height="20">
<style id="style_css_sheet" type="text/css">
.land
{
fill: #00ff00;
stroke-width: 0.2;
stroke: #e0e0e0;
}
.aa, .ab
{
fill: #ff0000;
}
</style>
<g class="land bg"
id="A">
<path d="M 0,5 H 5 V 0 H 0 Z"
id="aa" class="land er bg"/>
<path d="m 10,5 h 5 V 0 h -5 z"
id="ab" class="land er bg"/>
<path d="m 5,5 h 5 V 0 H 5 Z"
id="ac" class="land tt bg"/>
</g>
<path d="M 0,10 H 5 v -5 H 0 Z"
id="ba" class="land er au"/>
<path d="m 10,10 h 5 v -5 h -5 z"
id="bb" class="land tt au"/>
<path d="m 5,10 h 5 v -5 H 5 Z"
id="bc" class="land er au"/>
<path d="M 0,15 H 5 V 10 H 0 Z"
id="ca" class="land tt bg"/>
<path d="m 10,15 h 5 V 10 h -5 z"
id="cb" class="land tt au"/>
<path d="m 5,15 h 5 V 10 H 5 Z"
id="cc" class="land er bg"/>
</svg>
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)"