I have been searching for a good example on how to animate a svg path morph. I know how to do do pretty complex ones using SMIL, but snap.svg is new and shiny, and everyone seems to love it, so I'd like to take a look. I can't find a good example anywhere on how to do n animated path morph anywhere. Hopefully a snap.svg guru could point me in the right direction?
here's a link to the svg image and the code for it:
link to image
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="400">
<path id="thing" d="M94.2,265.7L82,203.4c43.3-15.6,83.8-29.2,137.1-20.2c61.5-27.6,126.1-56.9,202.6-46.1c18.7,18.9,21.5,39.8,12.2,62.3C322.7,231.9,208.2,247.6,94.2,265.7z">
<animate id="myAnimationElement" dur="2s" begin="0" repeatCount="indefinite" attributeName="d"
values="M94.2,265.7L82,203.4c43.3-15.6,83.8-29.2,137.1-20.2c61.5-27.6,126.1-56.9,202.6-46.1c18.7,18.9,21.5,39.8,12.2,62.3C322.7,231.9,208.2,247.6,94.2,265.7z;
M179.4,83.5l62.4-11.8c15.3,43.4-76,102.6-22.6,111.5c61.5-27.6,126.1-56.9,202.6-46.1c18.7,18.9,21.5,39.8,12.2,62.3C250.6,296.7,52.4,259.2,179.4,83.5z;"/>
</path>
</svg>
Not quite sure if you mean you just want the current animation in Snap or something different. Just to give an example of how one would typically do some animation...
s = Snap(400, 620);
var path = s.path("M94.2,265.7L82,203.4c43.3-15.6,83.8-29.2,137.1-20.2c61.5-27.6,126.1-56.9,202.6 46.1c18.7,18.9,21.5,39.8,12.2,62.3C322.7,231.9,208.2,247.6,94.2,265.7z");
path.animate({ d: "M179.4,83.5l62.4-11.8c15.3,43.4-76,102.6-22.6,111.5c61.5-27.6,126.1-56.9,202.6-46.1c18.7,18.9,21.5,39.8,12.2,62.3C250.6,296.7,52.4,259.2,179.4,83.5z" }, 1000, mina.bounce);
jsfiddle
Edit: There needs to be the same amount of points on the path to morph from/to.
If you're looking for something only for SVG Morph, you may not need the entire SnapSVG library, you can use KUTE.js. Really, take a look at this (Best viewed in Chrome and Firefox):
<div style="width: 220px">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle" fill="indigo" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531
c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"></path>
<path id="star" style="visibility:hidden" d="M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808
l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011"></path>
</svg>
</div>
<script id="core" src="https://cdn.jsdelivr.net/kute.js/1.5.5/kute.min.js"></script>
<script id="svg" src="https://cdn.jsdelivr.net/kute.js/1.5.5/kute-svg.min.js"></script>
<script>
var tween = KUTE.to('#rectangle', { path: '#star' }, {duration: 1500, yoyo: true, repeat: 1, morphIndex: 127}).start();
document.addEventListener('click', function(){
!tween.playing && tween.start();
}, false);
</script>
It's free and really easy to use.
Related
Essentially I needed to make the center "cut-out" keep a fixed shape and size regardless of vector scale. Is there a way to achieve this?
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="none" style="fill-rule:evenodd;" viewBox="0 0 2802 2657">
<path d="M290 4c-95,733 -191,1466 -286,2200 760,150 1520,300 2279,450 172,-223 343,-446 515,-669 -114,-572 -229,-1144 -343,-1716 -722,-88 -1444,-176 -2165,-264zm696 1027c-103,111 -205,222 -308,333 94,111 188,222 282,333 342,-205 684,-410 1026,-616 -333,-17 -667,-34 -1000,-51z"/>
</svg>
So I managed to do something after some editing to your SVG.
To achieve what you're asking you'll need to use / have :
- the SVG mask attribute
- A very large shape for the mask ( as much large as the max scale you want to use on the visible shape )
- The shape that you want to resize
- Resize the shape with transforms
Your SVG should looks like the following
<svg>
<defs>
<mask id="theMask">
<path fill="#ffffff" d=""/>
</mask>
</defs>
<g mask="url(#theMask)">
<path fill="#ffffff" id="shapetoresize" d=""/>
</g>
</svg>
I posted a pen as a "Proof of concept"
Feel free to fork it and use it to achieve what you're trying to do.
Codepen
note: as pointed out by #thioutp , The JS is only for demo purposes, you don't need GSAP to achieve this.
I'm playing around with SVG and I've hit a wall.
what im trying to do it when you hover over on svg element it will cause another to appear.
my idea was using javascript to add and remove a "hidden" class when you hover, but its not working, it works on none SVG elements but I can't see why it's not working here.
<svg xmlns:cc="http://web.resource.org/cc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
width="400px"
height="400px"
viewBox="0 150 960 900">
<path id="loc36" class="maploc" d="m 352.28954,738.20354 0,140.66609 85.8653,0 0,-140.41399 z"/>
<path id="info36" class="infopanel " d="m 306.42857,896.64787 0,157.85713 539.28572,0 0,-158.57141 z"/>
</svg>
Javascript
$("#loc36").hover(function(){
$('#info36').removeClass('hidden');
},function(){
$('#info36').addClass('hidden');
});
https://jsfiddle.net/atprsteq/
Its works on none SVG elements, like this example
http://jsfiddle.net/EzfwV/210/
Am I just missing something simple here?
Am I just missing something simple here?
Yes.
You forgot to include jQuery!
Select jQuery from the "Frameworks & Extensions" menu.
I'm working with the SVG that can be viewed here: http://n1t2.info/
I would just post the SVG, but because of the street maps layer the file is extremely large. However, you can see if you click the link that it's a map divided into 18 different svg paths, with a number of different colors shading them. My goal with this map is to make each of the 18 different sections clickable, or be able to give them an <a href="example.com">. Is this possible with SVGs at all?
edit: A comment suggested a show the way that I'm constructing the SVG file. You can see my method for that here.
IMO, the best solution is the SVG <a> element.
<svg width="200" height="200" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<a xlink:href="http://stackoverflow.com/questions/15532371/do-svg-docs-support-custom-data-attributes">
<path d="M 100 100 L 300 100 L 200 300 z" fill="orange" stroke="black" stroke-width="3"></path>
</a>
</svg>
You can handle it pretty easily by adding a data attribute to each <path> element and then handle it via jquery or just javascript.
First, add something like data-url="http://your-url.com" to the
<path> element. Example: <path data-url="http://your-url.com">.
Add jquery library just before the closing of your </body> tag, and the script in step #3 just like:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script>
//your script
</script>
</body>
</html>
instead of //your script you'll paste this one:
$(document).ready(function(){
$('path').on('click', function(e){
e.preventDefault();
var url = $(this).data('url');
console.log('Moving to:', url);
window.open(url, '_blank');
});
});
Test it: http://jsfiddle.net/jpvu852d/
A search on google turned up this jQuery plugin for decorating image maps that may help you achieve your goal:
http://www.outsharked.com/imagemapster/default.aspx?what.html
I need a little bit of help.
In the following code, I want to control the rotation of the star via onmouse-event.
If you move the mouse over the star, it is supposed to rotate.
I thought about changing the transform in attributeName to something different when the mouse is not over the star via roationon()/off() functions so that the rotation doesn't work but I have no idea how to do that.
I appreciate every help I can get.
Thanks
<!DOCTYPE html>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<html>
<body>
<script>
function rotationon() {}
function rotationoff() {}
</script>
<svg height="2000" width="2000">
<polygon id="stern1" points="100,10 40,180 190,60 10,60 160,180" fill="yellow" transform="translate(100, 100)" onmouseover="rotationon()" onmouseout="rotationoff()" >
<animateTransform
attributeName="transform"
begin="0s"
dur="5s"
type="rotate"
from="0 100 100"
to="360 100 100"
repeatCount="indefinite"
/>
</polygon>
</svg>
</body>
</html>
There's a few different ways to approach this, depending on what its going to integrate with, and how well it will play with other browsers.
My gut instinct would be to say ultimately, its worth using one of the SVG libs out there, like Raphael, snap.svg, Pablo.js etc. They will help with some of the issues likely to be faced.
You can also just use pure SVG like I mentioned http://jsfiddle.net/xaM6q/
However, to use the method you are trying, you may want to use something like beginElement() and endElement, so the code could look something like the following...fiddle at http://jsfiddle.net/xaM6q/2/
<script>
function rotationon(evt){
document.getElementById('myanim').beginElement();
}
function rotationoff(){
document.getElementById('myanim').endElement();
}
</script>
<svg height="2000" width="2000">
<g transform="translate(100,100)">
<polygon id="stern1" points="100,10 40,180 190,60 10,60 160,180" fill="yellow" onmouseover="rotationon()" onmouseout="rotationoff()" >
<animateTransform
id="myanim"
attributeName="transform"
begin="indefinite"
dur="5s"
type="rotate"
from="0 100 100"
to="360 100 100"
fill="freeze"
repeatCount="indefinite"
/>
</polygon>
</g>
Couple of things worth noting. I've added a g element to help keep the transformation in place, as you probably want that (without it, you may find it moves away). Also the animation may be a bit erratic depending how you want it to stop (I've added 'fill=freeze'), and what happens with events mid animation.
Its worth knowing all of this to get to know SVG animations, but as mentioned, I would probably still look at using a 3rd party lib and control the rotation manually, rather than using the animate tag, so you can halt/restart a rotation at any angle easily.
Looking for ideas on how to animate what looks like a laser drawing out a word in a cursive font using SVG. The animation can be done with SMIL or JavaScript I don't care - though I think it would be easier with SMIL.
I am pretty sure if I could just get the letters represented as a path I could figure out how to animate a line from a fixed point to the word path - even if the path is non-continuous.
Any ideas?
EDIT
My demo was very basic, essentially I wrote animate functions for each letter and arranged their timing. Here is the letter X for example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
<rect x="0" y="0" width="100%" height="100%" fill="black"/>
<path id="word" stroke="red" d="M10 10 L40 40 M40 10 L10 40" />
<line x1="10" y1="10" x2="25" y2="50" stroke="blue" stroke-width="0.5">
<animate attributeName="x1" begin="0s" dur="1s" values="10; 40;" />
<animate attributeName="y1" begin="0s" dur="1s" values="10; 40;" />
<animate attributeName="x1" begin="1s" dur="1s" values="40; 10;" />
<animate attributeName="y1" begin="1s" dur="1s" values="10; 40;" />
<set attributeName="visibility" to="hidden" begin="2s" />
</line>
</svg>
I am sure we can all agree that this is not an ideal long term solution... I thought it would be relatively easy to animate one end of a LINE along a path but I am having problems just getting the path...
Extract the paths from the glyphs in question, then apply a dash-array animation as seen in this example on each of the paths.
From a high level perspective, I would think you would want to do something like render the font to a canvas, then use the pixel information to generate the animation sequence. A simple algorithm could just trace from left to right, it would be a good deal harder to figure out a single stroke path, but that is doable as well.
You don't mention any idea of what platform or any time constraints, so its hard to get much closer than that.
One possibility... SVG Fonts are, I understand, stored as a sequence of SVG commands used to draw individual characters. The vector-based nature of drawing in SVG would seem like it would be amenable to 'tracing out' characters in realtime; you might be able to make a conversion utility to pre-convert SVG fonts to simple paths.