Can't get hamburger menu to animate on click - javascript
I targeted the SVG rect using :nth-chid(1), 2 and 3 and made a -> that I'm trying to trigger on click. Don't know what I'm doing wrong here. Any Help would be great thank you!
(function() {
var burger;
buger = document.getElementById('burger');
burger.addEventListener('click', function() {
console.log('you cliked the burger');
return burger.classList.toggle('st0-active');
});
}).call(this);
body {
max-width: 900px;
margin: 0 auto;
}
.st0-active:nth-child(1) {
-webkit-transform: rotate(27deg) translate(23px, -51px);
transform: rotate(27deg) translate(23px, -51px);
fill: #000;
}
.st0-active:nth-child(2) {
fill: #000;
}
.st0-active:nth-child(3) {
-webkit-transform: rotate(-21deg) translate(-48px, 15px);
transform: rotate(-21deg) translate(-48px, 15px);
fill: #000;
}
<body>
<svg class="mo-icon__svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve" id="burger">
<g id="icon_x5F_hamburger">
<rect x="0.11206" y="46.3329" class="st0" width="200" height="8"/>
<rect x="0.11206" y="96.22083" class="st0" width="200" height="8"/>
<rect x="0.11206" y="146.10876" class="st0" width="200" height="8"/>
</g>
</svg>
</body>
Here is a picture of my designed end goal
Which is the reason I'm using CSS Transforms and targeting the rect using nth-child Here is a link to the codepen that I'm currently working on
enter link description here
(function() {
var burger;
burger = document.getElementById('burger');
burger.addEventListener('click', function() {
console.log('you cliked the burger');
return burger.classList.toggle('st0-active');
});
}).call(this);
body {
max-width: 900px;
margin: 0 auto;
}
#burger > g > rect{
transition: transform 1s;
}
.st0-active > g > rect:nth-child(1) {
-webkit-transform: rotate(27deg) translate(23px, -51px);
transform: rotate(27deg) translate(23px, -51px);
fill: #000;
}
.st0-active > g > rect:nth-child(2) {
fill: #000;
}
.st0-active > g > rect:nth-child(3) {
-webkit-transform: rotate(-21deg) translate(-48px, 15px);
transform: rotate(-21deg) translate(-48px, 15px);
fill: #000;
}
<body>
<svg class="mo-icon__svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" style="enable-background:new 0 0 200 200;" xml:space="preserve" id="burger">
<g id="icon_x5F_hamburger">
<rect x="0.11206" y="46.3329" class="st0" width="200" height="8"/>
<rect x="0.11206" y="96.22083" class="st0" width="200" height="8"/>
<rect x="0.11206" y="146.10876" class="st0" width="200" height="8"/>
</g>
</svg>
</body>
Try to add this code.
#burger{
transition: transform 1s;
}
Additionally
CSS3 transitions allows you to change property values smoothly (from one value to another), over a given duration.
Related
SVG+JavaScript, how to find out if <use> reference exists
I have an SVG file like this <svg class="icon" viewBox="0 0 16 16"> <use href="assets/icons.svg#my-fancy-icon"></use> </svg> Using JavaScript, how do I find out if the href attribute of use element points to an element that actually exists?
Get the <use> element's boundaries: width & height: 0 = not existent Whenever a svg element is referenced by an <use> element via a href attribute (or the still widely used legacy syntax: xlink:href) and it can be successfully appended to the svg's shadow DOM, it will return a width and height value > 0. If not – getBBox() will return a width and height value of 0. The use reference is not valid/existent. Example 1: check width and height let useEls = document.querySelectorAll('use'); useEls.forEach(function(use) { let bb = use.getBBox(); let [width, height] = [bb.width, bb.height]; if (width == 0 && height == 0) { use.closest('svg').classList.add('notavailable') } }) svg { height: 10em; border: 1px solid #ccc; display: inline-block; } .notavailable { border: 1px solid red; } <svg id="svgIcons" class="svgIcons" viewBox="0 0 100 100" style="position:absolute; height:0; width:0;" xmlns="http://www.w3.org/2000/svg"> <symbol id="home" viewBox="0 0 34 48"> <path d="M33.16,28.12h-5.2v13h-3.44v-16.72l-7.72-8.72l-7.72,8.72v16.72h-3.44v-13h-5.24l16.4-17.4Z" /> </symbol> </svg> <svg viewBox="0 0 34 48"> <use href="#home" /> </svg> <svg viewBox="0 0 34 48"> <use href="#notExistent" /> </svg> Example 2: clone all use elements in temporary svg This way we can also check invisible <use> elements hidden by display: none that would be overlooked by the previous checking method. checkUseEls(); function checkUseEls() { // collect missing references let missingRefs = []; //add temporary hidden svg let svgTmp = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svgTmp.setAttribute('style', 'position:absolute; width:0; height:0;visibility:hidden'); document.body.appendChild(svgTmp); //add cloned use els let useEls = document.querySelectorAll('use'); useEls.forEach(function(use) { let cloned = use.cloneNode(); cloned.setAttribute('style', 'display:block!important') svgTmp.appendChild(cloned) let bb = cloned.getBBox(); let [width, height] = [bb.width, bb.height]; if (width == 0 && height == 0) { missingRefs.push(cloned.getAttribute('href')) } }) svgTmp.remove(); console.log(missingRefs) } svg { height: 10em; border: 1px solid #ccc; display: inline-block; } .notavailable { border: 1px solid red; } <svg id="svgIcons" class="svgIcons" viewBox="0 0 100 100" style="display:none" xmlns="http://www.w3.org/2000/svg"> <symbol id="home" viewBox="0 0 34 48"> <path d="M33.16,28.12h-5.2v13h-3.44v-16.72l-7.72-8.72l-7.72,8.72v16.72h-3.44v-13h-5.24l16.4-17.4Z" /> </symbol> <symbol id="homeHidden" viewBox="0 0 34 48"> <path d="M33.16,28.12h-5.2v13h-3.44v-16.72l-7.72-8.72l-7.72,8.72v16.72h-3.44v-13h-5.24l16.4-17.4Z" /> </symbol> </svg> <svg viewBox="0 0 34 48"> <use href="#home" /> </svg> <svg viewBox="0 0 34 48" style="display:none"> <use href="#notExistent" /> </svg> <svg viewBox="0 0 34 48"> <use href="#homeHidden" style="display:none"/> </svg> Symbol #homeHidden is existent but hidden. By applying display:block to it's cloned instance, we can check it's with/height.
Try this way: const icon = document.querySelector(".use"); if (icon.firstElementChild === "USE") //...do something
How do I get a style property value from an SVG element that is animated using transform?
If I have an SVG element that is animated using transform, either using SMIL or CSS, how do I get the computed style of the property that is animated? Here I have a <rect> that rotates, but as you can see the rotate property just returns none: var rect1 = document.getElementById('rect1'); setTimeout(function(){ let rectStyle = getComputedStyle(rect1); console.log(rectStyle.rotate); }, 200); <svg id="svg" width="200" viewBox="0 0 4 4" xmlns="http://www.w3.org/2000/svg"> <rect id="rect1" x="1" y="1" width="2" height="2" fill="red"> <animateTransform attributeName="transform" attributeType="XML" type="rotate" values="0 2 2; 360 2 2" dur="10s" repeatCount="indefinite"/> </rect> </svg> var rect1 = document.getElementById('rect1'); setTimeout(function(){ let rectStyle = getComputedStyle(rect1); console.log(rectStyle.rotate); }, 200); #rect1 { transform-origin: center; animation-name: rotate; animation-duration: 10s; animation-timing-function: linear; animation-iteration-count: infinite; } #keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } <svg id="svg" width="200" viewBox="0 0 4 4" xmlns="http://www.w3.org/2000/svg"> <rect id="rect1" x="1" y="1" width="2" height="2" fill="red" /> </svg>
In the case of a SMIL animation just read off the SMIL values if you want to. var rect1 = document.getElementById('rect1'); setTimeout(function(){ let a = rect1.transform.animVal[0].matrix.a; let b = rect1.transform.animVal[0].matrix.b; let angle = Math.atan2(b, a) * (180/Math.PI); console.log(angle); }, 200); <svg id="svg" width="200" viewBox="0 0 4 4" xmlns="http://www.w3.org/2000/svg"> <rect id="rect1" x="1" y="1" width="2" height="2" fill="red"> <animateTransform attributeName="transform" attributeType="XML" type="rotate" values="0 2 2; 360 2 2" dur="10s" repeatCount="indefinite"/> </rect> </svg>
In the case of a CSS animation you can use transform instead of rotate but you get something like matrix(....). to get the exact value you need similar to this article . var rect1 = document.getElementById('rect1'); setTimeout(function(){ let rectStyle = getComputedStyle(rect1); let values = rectStyle.transform.split('(')[1]; values = values.split(')')[0]; values = values.split(','); let a = values[0]; let b = values[1]; let c = values[2]; let d = values[3]; var angle = Math.atan2(b, a) * (180/Math.PI); console.log(angle); }, 200); #rect1 { transform-origin: center; animation-name: rotate; animation-duration: 10s; animation-timing-function: linear; animation-iteration-count: infinite; } #keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } <svg id="svg" width="200" viewBox="0 0 4 4" xmlns="http://www.w3.org/2000/svg"> <rect id="rect1" x="1" y="1" width="2" height="2" fill="red" /> </svg>
how to make svg curve at one end
im using svg for circular progress bar , i want to make one end curve not the both end . how is this possible ? how can i implement one end curve in svg? svg { height: 80vh; margin: 10vh auto; border: 1px solid red; display: block; transform: rotate(-90deg); } svg circle { stroke-width: 10; fill: transparent; } #outer { stroke: lightgrey; } #inner { stroke: blue; animation: value 2.5s linear forwards; stroke-linecap: round; } #keyframes value { 0% { stroke-dasharray: 0 100; } 100% { stroke-dasharray: 90 100; } } <svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <circle id="outer" cx="50" cy="50" r="40" /> <circle id="inner" pathLength="100" cx="50" cy="50" r="40" /> </svg>
The easiest way would be to mask the starting point of the blue circle. For this you will need a <mask> like so: <mask id="m"> <rect width="100" height="100" fill="white"/> <rect x="85" y="40" width="10" height="10" /> </mask> Please observe that the first rectangle is white and it covers the whole chart. (Everything under a white pixel will be visible). The smaller rectangle is black and covers the starting point of the blue circle. Everything under a black pixel will be invisible. svg { height: 80vh; margin: 10vh auto; border: 1px solid red; display: block; transform: rotate(-90deg); } svg circle { stroke-width: 10; fill: transparent; } #outer { stroke: lightgrey; } #inner { stroke: blue; animation: value 2.5s linear forwards; stroke-linecap: round; } #keyframes value { 0% { stroke-dasharray: 0 100; } 100% { stroke-dasharray: 90 100; } } <svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <mask id="m"> <rect width="100" height="100" fill="white"/> <rect x="85" y="40" width="10" height="10" /> </mask> <circle id="outer" cx="50" cy="50" r="40" /> <circle id="inner" pathLength="100" cx="50" cy="50" r="40" mask="url(#m)" /> </svg>
Try this code: svg { height: 80vh; margin: 10vh auto; border: 1px solid red; display: block; transform: rotate(-90deg); border-top-right-radius: 20px; } svg circle { stroke-width: 10; fill: transparent; } #outer { stroke: lightgrey; } #inner { stroke: blue; animation: value 2.5s linear forwards; stroke-linecap: round; } #keyframes value { 0% { stroke-dasharray: 0 100; } 100% { stroke-dasharray: 90 100; } } <svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <circle id="outer" cx="50" cy="50" r="40" /> <circle id="inner" pathLength="100" cx="50" cy="50" r="40" /> </svg>
I came up with an alternative solution than enxaneta suggested. The problem with using a mask is that when your value goes over 96% or so, the circle isn't completely filled and the mask is revealed. Instead, you can set a rounded progress line on top of another progress line that has flat endcaps. By rotating the rounded progress line by roughly 5 degrees, the flat end is revealed. Here's how to do that in React Native with react-native-svg: const radius = 60; let myPercentage = 40; const circleCircumference = 2 * Math.PI * radius; const valueOffset = circleCircumference - (circleCircumference * myPercentage * 0.98) / 100; <Svg height={radius * 2 + 30} width={radius * 2 + 30}> <G rotation={-90} originX={radius + 15} originY={radius + 15}> // Background gray circle <Circle cx="50%" cy="50%" r={radius} stroke="rgb(60, 60, 60)" fill="transparent" strokeWidth="10" strokeDasharray={circleCircumference} strokeLinecap="butt" /> // Background progress circle with flat ends <Circle cx="50%" cy="50%" r={radius} stroke={"rgb(0, 51, 204)"} fill="transparent" strokeWidth="10" strokeDasharray={circleCircumference} strokeDashoffset={valueOffset} strokeLinecap="butt" /> // Progress circle with round ends rotated by 5 degrees <Circle cx="50%" cy="50%" r={radius} stroke={rgb(0, 51, 204)} fill="transparent" rotation={5} originX={radius + 15} originY={radius + 15} strokeWidth="10" strokeDasharray={circleCircumference} strokeDashoffset={valueOffset} strokeLinecap="round" /> </G> </Svg>
Isolate section of SVG when mouse is hovered
I am attempting to build an interactive map from scratch. I have an SVG of the map of Canada that has separate layers for each province. I'd like to highlight a specific province/territory when the mouse is hovered over it. I have tried using a function that gets the live update of the mouse coordinates, but I am unsure as to how to figure out which section of the image it is on. I am unsure as to if this is the best method of doing it. Through some of my research, I have found a method of gathering the pointer coordinates: let x = 0; let y = 0; function showCoords() { x = event.clientX; y = event.clientY; } And I call it around the SVG using: <div onmousemove="showCoords()"> ...SVG HERE </div> I can select the different layers inside of the SVG, but the question is if I can find a way of checking which layer my mouse is currently over. Thank you! Edit: I have reached a solution that accomplishes my goal, but I am unsure as to if it is efficient. Using CSS, I fill each group upon hover: #canada { fill: hsl(0, 0%, 29%); } #canada g { transition: .3s; } #canada g:hover { fill: hsl(189, 88%, 59%); } I am also using the onClick option on each group to pull up their dialogue.
Maybe something like this? Just keep "data-name" attribute on each <g> inside svg code. let x = 0; let y = 0; let svgCountry = document.querySelector("#states svg"); let svgStates = svgCountry.querySelectorAll("[data-name]"); let resContainer = document.getElementById("state-hovered-is"); // init tooltip function showCoords(event) { let x = event.clientX; let y = event.clientY; resContainer.setAttribute("style", "left:" + (x + 15) + "px;" + "top:" + (y - 50) + "px;"); } // close tooltip function clearCoor() { resContainer.innerHTML = ""; } // clear everything function clearAllOn() { svgStates.forEach(function(el) { el.classList.remove("hover"); resContainer.innerHTML = ""; console.clear(); }); } // display current state in div function displayState(el) { var res = el.getAttribute("data-name"); el.classList.add("hover"); resContainer.innerHTML = "<p>You're at" + " " + res + "</p>"; console.log(res); } svgStates.forEach(function(el) { // mouse events el.addEventListener("mouseenter", function() { displayState(el); }); el.addEventListener("mouseleave", function() { clearAllOn(); }); // touch events el.addEventListener("touchstart", function() { clearAllOn(); displayState(el); }); }); body { background-color: #fff; font-family: Arial, Helvetica, sans-serif; color: #333; } g.hover { opacity: 0.5; } #states { margin: 0 auto; width: 600px; max-width: 100%; position: relative; } #state-hovered-is { text-align: center; min-height: 50px; position: fixed; pointer-events: none; background-color: rgba(0, 0, 0, 0.76); border-radius: 6px; } #state-hovered-is p { color: #fff; margin: 0; padding: 15px; width: 180px; } <div id="states" onmousemove="showCoords(event)" onmouseout="clearCoor()"> <!-- State name here --> <div id="state-hovered-is"></div> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 961.38 830.7"> <defs> <style> .cls-1 { fill: #fff;} .cls-2 {fill: #b8c4e6;} .cls-3 {fill: #ce8080;} .cls-4 {fill: #e99bd2;} .cls-5 {fill: #acac90;} .cls-6 {fill: #e6c0c0;} .cls-7 {fill: #4d6ac1;} .cls-8 {fill: #c9e6b8;} .cls-9 {fill: #f3f3db;} .cls-10 {fill: #cece71;} .cls-11 {fill: #7188ce;} .cls-12 {fill: #daa0a0;} .cls-13 {fill: #91916b;} .cls-14 {fill: #dada94;} .cls-15 {fill: #916b86;} </style> </defs> <title>Canada</title> <g id="Layer_1"> <ellipse class="cls-1" cx="480.69" cy="415.35" rx="679.8" ry="587.39" /> <path class="cls-1" d="M539.84,220.75c-2.45,5-6.57,8.18-10.72,11.7l2-9.56C534.53,224.17,537,221.84,539.84,220.75Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M53,543.56c-1.09,2.13-2.18,4.23-3.52,6.84l-.51-10.68.56-.25Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M771.19,558.14c-.32-2.18-.77-4.36-.89-6.56a3.15,3.15,0,0,1,1.31-2.05,1.76,1.76,0,0,1,1.64.49,4.19,4.19,0,0,1,.17,2.5c-.48,1.84-1.18,3.62-1.79,5.43Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M40.77,527.77l-7-8.41.35-.18A76,76,0,0,1,40.4,524c.77.71.87,2.14,1.27,3.25Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M493.56,95.47l3.41,6L485.7,105a30.91,30.91,0,0,1,2.81-2.42C491.7,100.51,493.64,100.2,493.56,95.47Z" transform="translate(-0.06 -0.26)" /> </g> <g id="Yukon" data-name="Yukon"> <path class="cls-3" d="M174.12,185.61c.91,1.61.88,2.8-.63,4.31-4.21,4.21-8.16,8.68-12.2,13.07-.34.38-.78,1-.72,1.39.58,3.9-2,6.08-4.31,8.53a6.48,6.48,0,0,0-1.84,3.83,5.33,5.33,0,0,0,1.79,3.5c1.85,1.68,4.07,2.94,6,4.53,3.45,2.83,3.47,5.7.33,9.15-2.19,2.39-4.41,4.77-6.37,7.34-1.76,2.3-1.12,4.05,1.42,5.49,1.4.81,2.66,1.88,4.19,3-2.18,1.51-3.35,2.81-2.33,5.22.45,1.05,0,2.31-1.73,2.4a17.09,17.09,0,0,0-3.62.83c-4.36,1.21-5.4,4.72-5.53,8.56a57.14,57.14,0,0,0,.5,10c.23,1.57,1.5,3,2.39,4.63-2.26,2.84-2.38,6.32-1.6,10.12a46.41,46.41,0,0,1,.52,7.56,1.6,1.6,0,0,1-.82,1.17c-2.55,1.24-3,3.61-3.48,6a9.38,9.38,0,0,1-1.27,3.48,10.68,10.68,0,0,0-1.7,8.87,2.39,2.39,0,0,1-.44,1.48c-.6,1-1.32,2-2,2.93-1.42,2.18-1.43,4,.77,5.24,3.32,1.83,3.1,4.7,2.57,7.41-.72,3.66-.45,6.87,2,9.78,1.47,1.77,1.39,3.3-.37,4.95a7.72,7.72,0,0,0-1.45,3.08c-.28.81-.27,1.71-.5,2.53-1.52,5.43,1,6.26,4.74,7.61,1.41.5,2.57,1.66,3.93,2.34a26.86,26.86,0,0,0,4.63,1.87c1.72.5,3.51.73,5.24,1.06.05.25.15.5.1.53-3,2.14-3,5.28-2.81,8.48.09,2,0,4,0,6.25A575.11,575.11,0,0,1,48.14,298a7.87,7.87,0,0,1,.58-.75c3.2-3.33,3.13-5.09-.71-7.55a38.29,38.29,0,0,0-6.52-3.12c-2.14-.86-3.05-5-1.32-6.73q13.23-13,26.49-26c6.81-6.67,13.65-13.31,20.46-20q13.26-13,26.5-26,10.56-10.35,21.15-20.68,11.07-10.83,22.16-21.66c1.92-1.87,3.87-3.74,6-5.43a2.44,2.44,0,0,1,2.34-.08,12.63,12.63,0,0,1,4.51,7.68c.95,5.52,2.44,10.95,3.73,16.42A5.64,5.64,0,0,0,174.12,185.61Z" transform="translate(-0.06 -0.26)" /> </g> <g id="British_Columiba" data-name="British Columiba"> <g> <path class="cls-4" d="M190.26,405.28c.27.14.53.31,1.06.62-1,1.88-2,3.69-2.9,5.53-5.64,11.14-11.24,22.3-16.9,33.43-4.43,8.73-8.92,17.42-13.38,26.13l-19.37,37.93c-.21.42-.68.84-.65,1.24.17,2.7,0,5.24-2.52,6.95.78,2,1.25,4.14,2.45,5.8.82,1.15,1.83,1.89,1.89,3.54s.46,3.46,2.33,4.55c2.39,1.41,1.92,4.19,2.3,6.41.31,1.81-.17,3.77-.35,5.66s.8,3.35,2.22,4.62a2.72,2.72,0,0,1,.81,2.17,5.54,5.54,0,0,0,1.49,5.42c.88,1,1.18,2.44,1.69,3.71.82,2,1.6,4,2.38,6,1,2.51,2,5,2.9,7.55.32.88.14,2.18.72,2.67,3.23,2.74,2.75,6.63,3,10.1a15.41,15.41,0,0,0,3.74,8.9c3.16,3.57,2.61,7,1.68,10.73-.83,3.31-1.92,6.57-3,9.84s-.35,6.2,1.21,9.74c-5.31-2.27-10.13-4.28-14.9-6.38-10.53-4.64-21.08-9.23-31.54-14-8.14-3.72-16.25-7.52-24.19-11.65-8.81-4.6-17.41-9.61-26.09-14.47a2,2,0,0,1-1-1.12,65.21,65.21,0,0,1-1-7.47c-.16-3.6-1.05-5-4.37-5.94,0-1.19,0-2.34,0-3.5a3.82,3.82,0,0,0-2.71-3.76c-1.17-.5-3.27-.93-3.32-1.53a9.88,9.88,0,0,1,.91-5.44c3.08-5.49,3.08-7.06-1-11.44-2.29-2.47-4.78-4.79-6.82-7.46a9.16,9.16,0,0,1-1.44-4.76c-.2-2.61-1.08-4.69-3.49-5.72-3.27-1.39-4.67-4.2-5.48-7.23a5.27,5.27,0,0,1,1-4.36,5.48,5.48,0,0,0,1.59-5.2c-.48-3.26,1.93-4.89,4.78-5.55a19.58,19.58,0,0,0,3.83-1c2.43-1.12,2.65-3.06.7-4.87a7.78,7.78,0,0,1-2-9.22c1.46-3.4,1.33-5.05-1-6.15-1.19-.56-2.78-.29-4.19-.39-.47,0-.93-.05-1.65-.09,1.67-3,3-5.78,6.86-6.28a4.12,4.12,0,0,0,3.2-2.73c.72-1.68,2.44-2.95,3.74-4.38,1.14-1.23,1.82-2.81.52-4a5.8,5.8,0,0,0-4-1A30.06,30.06,0,0,0,44.62,459c-1.84-6.08-.47-11.9,1.17-17.65A3.74,3.74,0,0,1,48,439.05c7.2-1.55,10.53-7,13.68-12.85a30.35,30.35,0,0,1,3.83-4.91c1.69-2,2.72-4.14,1.8-6.84s-1.71-5.51-2.66-8.23A52.51,52.51,0,0,0,62,399.51c-1.34-2.62-.9-5.19-.39-7.83q2.15-11.08,4.26-22.15c1.08-5.61,2.21-11.21,3.21-16.84a9.48,9.48,0,0,0-.36-2.74c-.16-1.32-.33-2.65-.44-4-.14-1.58-.18-3.17-.36-4.74a11.92,11.92,0,0,1,1.16-7.34c1.92-3.53,1.66-7.9-.48-9.87l1.06-1.21c7.65,6.68,15.29,13.38,23.2,19.74,8.69,7,17.59,13.76,26.79,20,13.27,9,26.71,17.88,40.42,26.24C169.85,394.8,180.18,399.83,190.26,405.28Z" transform="translate(-0.06 -0.26)" /> <path class="cls-4" d="M67.71,323.4c-4.2-2.13-8.84-4.21-13.43-1.55-2.84,1.64-5.18.87-8.06.13,2.21-2.52,1.9-5.53,1.88-8.49s0-6.08,0-9.44a8.14,8.14,0,0,1,1.68.85c5.42,4.9,10.73,9.92,16.24,14.72l3.65,3.2L68.61,324A4,4,0,0,0,67.71,323.4Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M52.34,580.17c.15,1.23-.68,2.57-1.25,4.47-2.23-1.77-4.17-2.89-5.53-4.5a75.63,75.63,0,0,1-5.85-8.23,3.32,3.32,0,0,1-.2-2.75c2.52-5.09,2.08-6.95-3.06-9.61-1.82-.94-2.5-1.94-2.32-4,.32-3.52.35-4.15-4.79-9.94,2-2.92,1.55-3.82-.24-7-1.32-2.35-1.69-5.31-2.07-8.06-.29-2.13-.63-4-2.58-5.25a2.26,2.26,0,0,1-.79-1.75c.24-3.45.6-6.89.93-10.33,2-.08,2.8,1.11,3.33,2.71A29.72,29.72,0,0,0,36,529,45.65,45.65,0,0,1,43,536.54c1.16,1.66,1.53,4.06,1.7,6.17a84.4,84.4,0,0,1,0,10.06c-.17,4.12,1.42,7.63,3.38,11.07a18,18,0,0,1,2.24,4.56A109.17,109.17,0,0,1,52.34,580.17Z" transform="translate(-0.06 -0.26)" /> <path class="cls-1" d="M17.57,426.81l6.17,8.48C16.39,441.78,11.81,449.73,11,459.7,10.41,448.18,12.87,437.39,17.57,426.81Z" transform="translate(-0.06 -0.26)" /> </g> </g> <g id="Alberta" data-name="Alberta"> <path class="cls-5" d="M194.56,407.63c27.17,14.46,55.83,25.35,85,35.57L214.1,643.67c-10.88-4-21.29-7.82-31.68-11.68-3.52-1.3-6.91-3-10.51-4s-5.08-3.41-6.18-6.74c-1.26-3.84-.43-7.18,1.12-10.59A26.88,26.88,0,0,0,169.13,597a4.52,4.52,0,0,0-1-2.58c-4.16-4.42-5.32-9.88-5.71-15.66-.07-1-.13-2.32-.75-2.88-2.84-2.56-2.45-6.26-3.65-9.38-.64-1.69-1.62-3.26-2.29-4.95-.84-2.14-1.52-4.35-2.27-6.53-.05-.15-.06-.35-.17-.44a6.25,6.25,0,0,1-2-7.07c.17-.6-1.07-1.75-1.85-2.43a2.33,2.33,0,0,1-1.08-2.43,28.92,28.92,0,0,0-.52-7.52c-.36-2.17,0-4.65-2.15-6.28-1.47-1.09-1.92-2.71-2.35-4.49-.35-1.45-1.6-2.69-2.47-4-.51-.77-1.07-1.51-1.72-2.42,2.55-1.41,2.87-3.59,2.69-6a5,5,0,0,1,.5-2.5q5-9.88,10-19.7c6.78-13.11,13.63-26.19,20.37-39.32,3.84-7.45,7.51-15,11.31-22.47C187.5,421.2,191,414.48,194.56,407.63Z" transform="translate(-0.06 -0.26)" /> </g> </svg> </div> Here's how the full map looks: https://jsfiddle.net/darkosss/7umphzwn/
Translate (gradually - with animate) an svg element after a delay using jQuery
I have this cubes which I want to translate to a different X and Y point after a delay of say 3000. I am not able to understand how to do this with the help of jQuery. Here is a JS Fiddle. Below is the code. JS // code for fade in one by one console.log("game begins"); allSVGs = $("g"); fadeIn(0); setTimeout(function () { $("#cubeTop").animate({ svgTransform: "translate(0, -160)" }); }, 3000); function fadeIn(svgIndex) { console.log(svgIndex); allSVGs.eq(svgIndex).css({ "display": "block", "opacity": "0" }); allSVGs.eq(svgIndex).animate({ "opacity": "1" }, { complete: function () { svgIndex++; if (svgIndex < allSVGs.length) //Making sure we don't exceed the maximum available SVG elements fadeIn(svgIndex); //Recursively calling the next elements animation (hide) from the completed one. }, duration: 400 }); } Thanks in advance. PS: Sorry for not being clear. I just made an edit to the question.
Well it is possible. I just made some changes to your setTimeOut. Check if this is what you want: setTimeout(function () { $("#cubeTop") .animate( {"min-height": -140}, {duration: 1000, step: function( top ){ this.setAttribute("transform", "translate(0,"+top+")"); } }); }, 3000); Here is the DEMO
You can try something like this $("#cubeTop").attr({ transform:'translate(0,-140)' }) // code for fade in one by one console.log("game begins"); allSVGs = $("g"); fadeIn(0); setTimeout(function () { $("#cubeTop").attr({ transform:'translate(0,-140)' }) }, 3000); function fadeIn(svgIndex) { console.log(svgIndex); allSVGs.eq(svgIndex).css({ "display": "block", "opacity": "0" }); allSVGs.eq(svgIndex).animate({ "opacity": "1" }, { complete: function () { svgIndex++; if (svgIndex < allSVGs.length) //Making sure we don't exceed the maximum available SVG elements fadeIn(svgIndex); //Recursively calling the next elements animation (hide) from the completed one. }, duration: 400 }); } svg { position: absolute; left: 0; top: 0; } #cube { fill: none; stroke: black; cursor: pointer; display: none; } #cubeTop { fill: none; stroke: black; cursor: pointer; display: none; } #cubeTopRight { fill: none; stroke: red; cursor: pointer; display: none; } #cubeTopRightDown { fill: none; stroke: black; cursor: pointer; display: none; } #cubeDown { fill: none; stroke: red; cursor: pointer; display: none; } #cubeLeftDown { fill: none; stroke: black; cursor: pointer; display: none; } #cubeLeft { fill: none; stroke: red; cursor: pointer; display: none; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> <svg height="100%" version="1.1" width="100%" xmlns="http://www.w3.org/2000/svg"> <g id="cube"> <path id="f1" d="M190,200L260,160L330,200L260,240L190,200"></path> <path id="f2" d="M260,240L330,200L330,280L260,320L260,240"></path> <path id="f3" d="M260,240L260,320L190,280L190,200L260,240"></path> </g> <g id="cubeTop" transform="translate(0, -80)"> <path id="t1" d="M190,200L260,160L330,200L260,240L190,200"></path> <path id="t2" d="M260,240L330,200L330,280L260,320L260,240"></path> <path id="t3" d="M260,240L260,320L190,280L190,200L260,240"></path> </g> <g id="cubeTopRight" transform="translate(70, -40)"> <path id="r1" d="M190,200L260,160L330,200L260,240L190,200"></path> <path id="r2" d="M260,240L330,200L330,280L260,320L260,240"></path> <path id="r3" d="M260,240L260,320L190,280L190,200L260,240"></path> </g> <g id="cubeTopRightDown" transform="translate(70, 40)"> <path id="rd1" d="M190,200L260,160L330,200L260,240L190,200"></path> <path id="rd2" d="M260,240L330,200L330,280L260,320L260,240"></path> <path id="rd3" d="M260,240L260,320L190,280L190,200L260,240"></path> </g> <g id="cubeDown" transform="translate(0, 80)"> <path id="cd1" d="M190,200L260,160L330,200L260,240L190,200"></path> <path id="cd2" d="M260,240L330,200L330,280L260,320L260,240"></path> <path id="cd3" d="M260,240L260,320L190,280L190,200L260,240"></path> </g> <g id="cubeLeftDown" transform="translate(-70, 40)"> <path id="ld1" d="M190,200L260,160L330,200L260,240L190,200"></path> <path id="ld2" d="M260,240L330,200L330,280L260,320L260,240"></path> <path id="ld3" d="M260,240L260,320L190,280L190,200L260,240"></path> </g> <g id="cubeLeft" transform="translate(-70, -40)"> <path id="l1" d="M190,200L260,160L330,200L260,240L190,200"></path> <path id="l2" d="M260,240L330,200L330,280L260,320L260,240"></path> <path id="l3" d="M260,240L260,320L190,280L190,200L260,240"></path> </g> </svg>
Add all the stuff in setTimeout function and try. // code for fade in one by one setTimeout(function() { console.log("game begins"); allSVGs = $("g"); fadeIn(0); $("#cubeTop").animate({ svgTransform: "translate(0, -160)" }); function fadeIn(svgIndex) { console.log(svgIndex); allSVGs.eq(svgIndex).css({ "display": "block", "opacity": "0" }); allSVGs.eq(svgIndex).animate({ "opacity": "1" }, { complete: function() { svgIndex++; if (svgIndex < allSVGs.length) //Making sure we don't exceed the maximum available SVG elements fadeIn(svgIndex); //Recursively calling the next elements animation (hide) from the completed one. }, duration: 400 }); } }, 3000);