javascript html5 如何将一个 SVG 变形或动画化为另一个?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14870014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
html5 How to morph or animate one SVG to another?
提问by Fabiano Soriani
I did some searching but I have to admit, I have 0 experience with SVG, I've seen a bunch of modern libraries, such as Raphael, PaperJS, KineticJS, EaselJS but I have no idea of what would fit the goal here, maybe even CSS keyframes would do the trick.
我做了一些搜索,但我不得不承认,我对 SVG 的经验为 0,我见过一堆现代库,例如 Raphael、PaperJS、KineticJS、EaselJS,但我不知道什么适合这里的目标,也许甚至 CSS 关键帧也能解决问题。
Pointers to this problem would be greatly appreciated.
将不胜感激指向此问题的指针。
Goal
On the browser, I want to animate svg1 into svg2, using transition type ease-out
目标
在浏览器上,我想使用过渡类型将 svg1 动画化为 svg2ease-out
Constraints
约束
- Any javascript library, if required at all
- Should be able to every element to the other element of same ID
- morph shapes, paths, fill*, stroke*, cx, cy, rc, ry
- Should work on current Firefox and Chrome, IE 10 would be nice to have
- Should work in new mobiles such as iphone 5, nexus 4 and 7
- Decent performance, even on mobiles
- Indifferent if it renders as
<svg>
or<canvas>
- 任何 javascript 库,如果需要的话
- 应该能够将每个元素指向相同 ID 的另一个元素
- 变形形状、路径、填充*、笔触*、cx、cy、rc、ry
- 应该在当前的 Firefox 和 Chrome 上工作,IE 10 会很好
- 应该适用于新手机,例如 iphone 5、nexus 4 和 7
- 性能不错,即使在手机上
- 如果它呈现为
<svg>
或<canvas>
svg1:
SVG1:
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<defs>
<linearGradient id="svg_6">
<stop stop-color="#828236" offset="0"/>
<stop stop-color="#7d7dc9" offset="0.99219"/>
</linearGradient>
<linearGradient id="svg_7" x1="0" y1="0" x2="1" y2="1">
<stop stop-color="#828236" offset="0"/>
<stop stop-color="#7d7dc9" offset="0.99219"/>
</linearGradient>
<linearGradient y2="1" x2="1" y1="0" x1="0" id="svg_1">
<stop offset="0" stop-color="#828236"/>
<stop offset="0.99219" stop-color="#7d7dc9"/>
</linearGradient>
</defs>
<g>
<title>Layer 1</title>
<ellipse ry="145" rx="116" id="svg_2" cy="201" cx="317" fill-opacity="0.36" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="5" stroke="#000000" fill="url(#svg_7)"/>
<ellipse ry="21" rx="10" id="svg_5" cy="137" cx="274" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="5" stroke="#000000" fill="#0cd60c"/>
<ellipse ry="31" rx="17" id="svg_9" cy="114" cx="346" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="5" stroke="#000000" fill="#0cd60c"/>
<path id="svg_14" d="m235,239c55.66666,-1.33333 133.33334,-71.66667 167,-4l-167,4z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="5" stroke="#000000" fill="none"/>
</g>
</svg>
svg2:
SVG2:
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<defs>
<linearGradient id="svg_6">
<stop offset="0" stop-color="#828236"/>
<stop offset="0.99219" stop-color="#7d7dc9"/>
</linearGradient>
<linearGradient y2="1" x2="1" y1="0" x1="0" id="svg_7">
<stop offset="0" stop-color="#828236"/>
<stop offset="0.99219" stop-color="#7d7dc9"/>
</linearGradient>
<linearGradient id="svg_1" x1="0" y1="0" x2="1" y2="1">
<stop stop-color="#828236" offset="0"/>
<stop stop-color="#7d7dc9" offset="0.99219"/>
</linearGradient>
</defs>
<g>
<title>Layer 1</title>
<ellipse id="svg_2" fill="url(#svg_7)" stroke="#000000" stroke-width="5" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" fill-opacity="0.36" cx="317" cy="201" rx="116" ry="145"/>
<ellipse id="svg_5" stroke="#000000" fill="#0cd60c" stroke-width="5" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" cx="277.5" cy="132.5" rx="13.5" ry="25.5"/>
<ellipse id="svg_9" stroke="#000000" fill="#0cd60c" stroke-width="5" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" cx="349.5" cy="110" rx="20.5" ry="35"/>
<path id="svg_14" fill="none" stroke="#000000" stroke-width="5" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" d="m235,240c21.66666,81.66669 114.33334,96.33331 167,-4l-167,4z" />
</g>
</svg>
psyou can visualize here, by simply pasting the codes in the area.
ps您可以在此处可视化,只需在该区域粘贴代码即可。
I have no code to show, I didn't want to start off wrong. My intuition tells me there is a 50% chance that the best solution don't involve navigating those nodes one by one diffing then!
我没有代码可显示,我不想开始错误。我的直觉告诉我,最好的解决方案有 50% 的机会不涉及逐个导航这些节点,然后!
回答by Mike
As far as I can see you only want to morph paths
据我所知,你只想改变路径
This is a nice tutorial: http://commons.oreilly.com/wiki/index.php/SVG_Essentials/Animating_and_Scripting_SVG
这是一个不错的教程:http: //commons.oreilly.com/wiki/index.php/SVG_Essentials/Animating_and_Scripting_SVG
W3C spec for SVG Paths: http://www.w3.org/TR/SVG/paths.html
SVG 路径的 W3C 规范:http: //www.w3.org/TR/SVG/paths.html
W3C spec for animation: http://www.w3.org/TR/SVG/animate.html
W3C 动画规范:http: //www.w3.org/TR/SVG/animate.html
Here's an example: http://www.carto.net/svg/samples/path_morphing.shtml
这是一个例子:http: //www.carto.net/svg/samples/path_morphing.shtml
回答by Darwin
Have to mention that 2015 have brought us several pretty nice libraries for svg morph:
不得不提的是,2015 年为我们带来了几个非常不错的 svg morph 库:
- https://alexk111.github.io/SVG-Morpheus/
- http://greensock.com/morphSVG(probably the best of the best, but you have to buy their license)
- https://github.com/gorangajic/react-svg-morph(for react)
回答by Simon d
Indeed, there are quite a few libraries that allow svg morphing, as Darwin mentioned.
事实上,正如达尔文所提到的,有很多库允许 svg 变形。
Some extras I've found were: snap.svg, KUTE.js, GSAP. Svg.js has a plugin for svg morph and I don't believe velocity.js has support for this yet.
我发现的一些附加功能是:snap.svg、KUTE.js、GSAP。Svg.js 有一个用于 svg morph 的插件,我认为velocity.js 还不支持这个。
回答by jared
paraphrasing:
释义:
Currently you have to use the same number of vertices in both path-elements, and they have to be of the same type and appear in the same orderin the other path-description. You should also orient both polygons in the same direction (left-right and right-left would produce unwanted results).
目前,您必须在两个 path-elements 中使用相同数量的顶点,并且它们必须具有相同的类型并且在另一个 path-description中以相同的顺序出现。您还应该将两个多边形定向在同一方向上(左右和左右会产生不需要的结果)。
So you can do it (see the link below for an example) but you need to plan it out so that you create shape A's path and shape B's path in the exact same way with identical curve types, points, etc.
因此,您可以这样做(请参阅下面的链接以获取示例),但您需要对其进行规划,以便使用相同的曲线类型、点等以完全相同的方式创建形状 A 的路径和形状 B 的路径。
Here's an example i made: animated svg path
I have the path on the right set as a mask of an image; it also animates.
这是我制作的一个示例:动画 svg 路径
我将右侧的路径设置为图像的蒙版;它也有动画效果。
- I created one shape in illustrator
- i duplicated that shape.
- I modified the duplicate into a new shape, careful not to add vertices or change from bezier to linear curve type etc
- fyi to confirm point count you can select the path, then go path>simplify and it will show you current points on that path...
- I save that svg file, then copy/paste those paths into another svg with the animation information.
- NOTE:the paths are placed within an element in the svg file that corresponds to the layer name that it's on in illustrator. If you keep both shapes on different layers in illustrator and name them clearly it will help keep your svg files organized.
- NOTE #2:If you create your shape and it's very simple, ie only straight lines, it will likely get saved as a _polygon instead of a _path which I personally found difficult to animate, so I recommend adding a bezier handle to at least a single point(and the identical corresponding point in the second shape).
- 我在 Illustrator 中创建了一个形状
- 我复制了那个形状。
- 我将副本修改为新形状,注意不要添加顶点或从贝塞尔曲线更改为线性曲线类型等
- 仅供参考以确认点数,您可以选择路径,然后转到路径>简化,它将显示该路径上的当前点...
- 我保存该 svg 文件,然后将这些路径复制/粘贴到另一个带有动画信息的 svg 中。
- 注意:路径位于 svg 文件中的一个元素中,该元素对应于它在 illustrator 中所在的图层名称。如果您在 illustrator 中将两个形状保留在不同图层上并清楚地命名它们,这将有助于保持您的 svg 文件井井有条。
- 注意#2:如果您创建的形状非常简单,即只有直线,则它可能会被保存为 _polygon 而不是我个人认为难以制作动画的 _path,因此我建议至少添加一个贝塞尔曲线手柄单个点(和第二个形状中相同的对应点)。
回答by naugtur
If you can define the morphing as a list of changes instead of second SVG, you could use d3 http://d3js.org/framework
如果您可以将变形定义为更改列表而不是第二个 SVG,则可以使用 d3 http://d3js.org/框架
It has a bit steep learning curve, but it gives you a lot of power. If you want something easier I suggest Raphael http://raphaeljs.com/- capabilities are similiar, but it's easier to start.
它的学习曲线有点陡峭,但它给了你很大的力量。如果你想要更简单的东西,我建议 Raphael http://raphaeljs.com/- 功能相似,但更容易开始。