How to animate entire "path" element of svg? - javascript

I have read this documentation http://www.w3.org/TR/SVG/animate.html about svg animation and i know how to animate rectangle,circle etc,but this document doesn't contains any info on how to animate entire svg "path" element.
I am creating bow and arrow game and i want to animate the "path" element to the right when user clicks on a button. i just want to know how to animate entire "path" element??
In the below code i want to animate second "path" element to the right...
<svg width="500" height="500">
<path d="M150,150 l0,150 q80,-50 0,-150 M220,230 l-120,0 m120,0 l-20,10 m20,-10 l-20,-10" style="stroke:black;stroke-width:5;fill:red;"/>
<path d="M220,230 l-120,0 m120,0 l-20,10 m20,-10 l-20,-10" style="stroke:orange;width:5" />
</svg>

After some trail and error i finally resolve my issue.Below is the code for the same.
<svg width="500" height="500">
<path d="M150,150 l0,150 q80,-50 0,-150 M220,230 l-120,0 m120,0 l-20,10 m20,-10 l-20,-10" style="stroke:black;stroke-width:5;fill:red;"/>
<path d="M220,230 l-120,0 m120,0 l-20,10 m20,-10 l-20,-10" style="stroke:orange;width:5">
<animateMotion
path="M0,0 l300,0"
begin="0s" dur="5s" repeatCount="1"
/>
</path>
</svg>

Related

SVG graph and Javascript: Which is the best way to add animation to and SVG file?

I'm new at coding.
I'm studying the way to make an animated portfolio like Sean Halpin or Stephanie Walter one. I want to put a face, in which, blinking eyes and a moving the mouth would be the animated elements. Basically, I want to play with the visibility of the closed eyes and open mouth. As an example, I drew a face as follows:
<svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 429 429">
<defs>
<style>
.cls-1 {
fill: #fff;
}
.cls-2 {
fill: none;
stroke: #000;
stroke-miterlimit: 10;
}
</style>
</defs>
<g id="face">
<path class="cls-1" d="M611,608.5a214,214,0,1,1,151.32-62.68A212.6,212.6,0,0,1,611,608.5Z" transform="translate(-396.46 -180)" />
<path d="M611,181a212.9,212.9,0,1,1-83.1,16.78A212.11,212.11,0,0,1,611,181m0-1c-118.46,0-214.5,96-214.5,214.5S492.5,609,611,609s214.5-96,214.5-214.5S729.43,180,611,180Z" transform="translate(-396.46 -180)" />
</g>
<g id="eyes">
<g id="eye_r">
<circle class="cls-1" cx="319.15" cy="128.63" r="48.5" />
<path d="M715.61,260.62a48,48,0,1,1-48,48,48.06,48.06,0,0,1,48-48m0-1a49,49,0,1,0,49,49,49,49,0,0,0-49-49Z" transform="translate(-396.46 -180)" />
</g>
<g id="iris_r">
<circle cx="319.15" cy="128.63" r="19" />
</g>
<g id="eye_l">
<circle class="cls-1" cx="109.85" cy="128.63" r="48.5" />
<path d="M506.32,260.62a48,48,0,1,1-48,48,48.06,48.06,0,0,1,48-48m0-1a49,49,0,1,0,49,49,49,49,0,0,0-49-49Z" transform="translate(-396.46 -180)" />
</g>
<g id="iris_l">
<circle cx="109.85" cy="128.63" r="19" />
</g>
<line id="closed_eye_l" class="cls-2" x1="62.04" y1="128.5" x2="158.04" y2="128.5" />
<line id="closed_eye_r" class="cls-2" x1="270.69" y1="128.23" x2="366.69" y2="128.23" />
</g>
<g id="closed_mouth">
<ellipse cx="214.5" cy="309" rx="108.5" ry="11.5" />
<path d="M611,478c29.08,0,56.41,1.25,77,3.51,30.68,3.38,31,7.32,31,7.49s-.35,4.11-31,7.49C667.37,498.75,640,500,611,500s-56.41-1.25-77-3.51c-30.69-3.38-31-7.32-31-7.49s.35-4.11,31-7.49c20.55-2.26,47.88-3.51,77-3.51m0-1c-60.2,0-109,5.37-109,12s48.8,12,109,12,109-5.37,109-12-48.8-12-109-12Z" transform="translate(-396.46 -180)" />
</g>
</svg>
So, I thought three ways to do this:
Place the svg inside an tag, calling then a function that takes into consideration the loading of the file. An example of what I'm saying is found in the following resource: https://www.petercollingridge.co.uk/tutorials/svg/interactive/javascript/, in the "External SVG + External JavaScript" part. It didn't work. The contentDocument ALWAYS returns "null".
In my example, it would be:
HTML:
<object id="face" data="path/to/face.svg" type="image/svg+xml"></object>
JS:
<script type="text/javascript">
window.addEventListener("load", function() {
var svgObject = document.getElementById('face').contentDocument;
var svg = svgObject.getElementById('closed_eye_r');
svg.style.visibility="hidden";
});
</script>
Inline SVG - call a "transform" property. Sean Halpin does it but I'm not sure what he does.
HTML: https://www.seanhalpin.design/
JS: https://www.seanhalpin.design/js/scripts.js
Inline SVG, use getElementById and apply functions to animate the internal parts of the SVG file.
Questions:
a. Is Inline SVG a good practice?
b. Which is the best way to animate an SVG?
I hope to have been clear. Let me know if something is not well presented, I want to learn to edit questions in order to make them as clear as possible.
Thanks!

Trying to change the color of an svg using an onclick event. Its saying it cant assign the color because its underfined

heres my svg file, its just a face as I am practicing
<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 720 720" style="enable-background:new 0 0 720 720;" xml:space="preserve">
<g id="skin">
<circle class="skin" cx="364.42" cy="383" r="278"/>
</g>
<g id="mouth">
<path class="mouth" d="M172.92,383c127.67,0,255.33,0,383,0c0,105.05-86.45,191.5-191.5,191.5S172.92,488.05,172.92,383z"/>
</g>
<g id="hair">
<path id = "hair" class = "hair" d="M107.4,276.86c-2.76-50.59,10.76-81.24,24.2-100.13C189.57,95.31,331.92,112,341.92,57.91
c2.04-11.03-2.07-21.46-6.93-29.61c18.47-6.31,81.92-25.39,151.28,3.28c94.59,39.09,121.88,137.21,127.56,160.84
c7.93,32.98,7.18,61.32,5.46,79.42c-38.79-64.73-78.17-85.57-107.42-92.42c-43.32-10.15-60.72,11.26-139.64,11.71
c-67.77,0.39-78.13-15.27-119.49-10.14C216.75,185.45,165.19,204.69,107.4,276.86z"/>
</g>
<g id="eyes">
<g>
<circle class = "eyes" cx="251.17" cy="271.25" r="52.4"/>
<circle class = "eyes" cx="477.67" cy="271.25" r="52.4"/>
</g>
</g>
</svg>
I'm trying to change the hair to blue using a button and an onclick event here:
<button class="blueButton" onclick="hair.style.fill='blue';"></button>
it does not change the color so I was wondering if anyone knew where I was going wrong with this...
Thank you!
You can't just reference the hair element. Instead, call document.getElementById('hair') to get it.
<button class="blueButton" onclick="document.getElementById('hair').style.fill='blue';">Button</button>
Here is a fiddle you can see it work in https://jsfiddle.net/679nLv3p/
You have two SVG objects with the same id hair. Remove the group one.
<g>
<path id = "hair" class = "hair" d="M107.4,276.86c-2.76-50.59,10.76-81.24,24.2-100.13C189.57,95.31,331.92,112,341.92,57.91
c2.04-11.03-2.07-21.46-6.93-29.61c18.47-6.31,81.92-25.39,151.28,3.28c94.59,39.09,121.88,137.21,127.56,160.84
c7.93,32.98,7.18,61.32,5.46,79.42c-38.79-64.73-78.17-85.57-107.42-92.42c-43.32-10.15-60.72,11.26-139.64,11.71
c-67.77,0.39-78.13-15.27-119.49-10.14C216.75,185.45,165.19,204.69,107.4,276.86z"/>
</g>
Working jsbin example

How can I add image on the tool-tip within SVG?

Trying to reference image on a tooltip within an SVG map. The reference is as the following:
<path
inkscape:connector-curvature="0"
id="BD"
data-info="<div>Bangladesh</div><div><img src="http://www.digi4health.org/wp-content/uploads/2018/09/bd.png" alt="Bangladesh mHealth" width="600" height="171"></div><div>Some Description</div>"
data-name="Bangladesh"
data-id="BD"
d="m 1486.5,431.9 -4.5,-10.1 -1.5,0.1 -0.2,4 -3.5,-3.3 1.1,-3.6 2.4,-0.4 1.6,-5.3 -3.4,-1.1 -5,0.1 -5.4,-0.9 -1.2,-4.4 -2.7,-0.4 -4.8,-2.7 -1.2,4.3 4.6,3.4 -3.1,2.4 -0.8,2.3 3.7,1.7 -0.4,3.8 2.6,4.8 1.6,5.2 2.2,0.6 1.7,0.7 0.6,-1.2 2.5,1.3 1.3,-3.5 -0.9,-2.6 5.1,0.2 2.8,3.7 1.5,3.1 0.8,3.2 2,3.3 -1.1,-5.1 2.1,1 -0.5,-4.6 z"
style="fill:#c1f4ff;fill-rule:evenodd" />
I have SVG world map, where I have added some descriptions in a popup info box related to my project. Currently, on the infobox I just have text. I am trying to include some pictures within the pop infobox.
Here I am sharing the full code for better understanding. Appreciate your support.
Your code is all wrong and I'm not very sure what are you asking. Take a look at the following example and tell me if this is what you need:
<svg viewbox = "1450 400 50 50">
<clipPath id="Bangladesh">
<path d="m 1486.5,431.9 l-4.5,-10.1 -1.5,0.1 -0.2,4 -3.5,-3.3 1.1,-3.6 2.4,-0.4 1.6,-5.3 -3.4,-1.1 -5,0.1 -5.4,-0.9 -1.2,-4.4 -2.7,-0.4 -4.8,-2.7 -1.2,4.3 4.6,3.4 -3.1,2.4 -0.8,2.3 3.7,1.7 -0.4,3.8 2.6,4.8 1.6,5.2 2.2,0.6 1.7,0.7 0.6,-1.2 2.5,1.3 1.3,-3.5 -0.9,-2.6 5.1,0.2 2.8,3.7 1.5,3.1 0.8,3.2 2,3.3 -1.1,-5.1 2.1,1 -0.5,-4.6 z"
/>
</clipPath>
<image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/darwin300.jpg" x="1450" y="400" height="50" width="50" clip-path="url(#Bangladesh)"/>
</svg>
I wasn't able to use your image since it comes from an http (not secure).

Set X and Y value for g element of SVG

I am relatively new in SVG drawing with HTML5.
What I want to do is to make a group of elements in SVG with g element so that all elements inside of that g element can work like a group and all the element's base x and y value can be received from the upper g element.
So, what I have done is something like this-
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
<g x="1000" y="1000">
<title>SVG Title Demo example</title>
<rect width="200" height="50"
style="fill:wheat; stroke:blue; stroke-width:1px"/>
<text style="text-anchor: middle;" class="small">My Text</text>
</g>
</svg>
What I expected is all the elements inside the g element will get x="1000" and y="1000" so my expected output is like this-
But I am getting this-
Re-
I don't like to set x and y element in text element. I just want to set relative x and y into the text element if needed, but that should be relative to g element.
Can anyone help me what I need to do to achieve my target with a group in SVG?
<g> elements don't support x or y attributes. You can use a transform instead though.
I've decreased the values from 1000 to 100 as otherwise the output is outside the 500 x 300 canvas of the outer <svg> element.
I've provided additional x and y attributes on the text element so it appears positioned as in your example. If wanted you could put the text itself in a <g> element or an <svg> element.
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(100, 100)">
<title>SVG Title Demo example</title>
<rect width="200" height="50"
style="fill:wheat; stroke:blue; stroke-width:1px"/>
<text x="100" y="30" style="text-anchor: middle;" class="small">My Text</text>
</g>
</svg>
or using an additional <g> element to avoid x and y on the text itself.
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(100, 100)">
<title>SVG Title Demo example</title>
<rect width="200" height="50"
style="fill:wheat; stroke:blue; stroke-width:1px"/>
<g transform="translate(100, 30)">
<text style="text-anchor: middle;" class="small">My Text</text>
</g>
</g>
</svg>
Alternatively you could use an inner <svg> element instead of a <g> element as that does support x and y attributes
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
<svg x="100" y="100">
<title>SVG Title Demo example</title>
<rect width="200" height="50"
style="fill:wheat; stroke:blue; stroke-width:1px"/>
<text x="100" y="30" style="text-anchor: middle;" class="small">My Text</text>
</svg>
</svg>

SVG Textpath - animate startOffset (text to slide down SVG path) - in JS

How can I animate the SVG textpath startOffset parameter in WebAnimation/JS (NOT CSS!):
I want to let the text slide down the path...
I tried numbers,%, px with no success.
<svg id="text-on-path-svg" width="400" height="400" style="border:1px solid #00f">
<path id="myPathforText" fill="none" stroke="#000" d="M90,90C90,160 250,160 300,300"/>
<text >
<textpath id="slideText" xlink:href="#myPathforText" startOffset="50%" >Text laid out along a path.</textpath>
</text>
<script type="text/ecmascript">
<![CDATA[
var slideText=document.getElementById("slideText");
var slideTextPlayer=slideText.animate(
[{startOffset:'0%'},
{startOffset:'100%'}],
{duration:3000,delay:0,iterations:Infinity});
]]>
</script>
</svg>
JSFiddle: https://jsfiddle.net/509c8pmj/
Help would be much appreciated.
One way is by placing an animate element inside your textpath element, like this:
<textpath id="slideText" xlink:href="#myPathforText" startOffset="50%" >
Text laid out along a path.
<animate attributeName="startOffset" from="0%" to ="100%" begin="0s" dur="3s" repeatCount="indefinite"/>
</textpath>
You can use repeatCount="indefinite" if you want it to keep looping.
I've been learning some of the SVG + SMIL syntax from articles on https://css-tricks.com (but their site was down for me as I'm writing this.)

Categories

Resources