Javascript 创建模块化SVG动画的最佳方法

Javascript 创建模块化SVG动画的最佳方法,javascript,svg,Javascript,Svg,我想创建一个动画,它由几个“组件”的运动产生。目前,我手工编码SVG标签,但目标是生成它们;以下是我的一个组件的显示方式和我的代码: <g style="transform-origin:39%;transform: rotate(180deg);"> <circle id="pippo" cx="0" cy="0" r="5" fill="#333333"> <animateMotion dur="0.7s" repeatCount="once

我想创建一个动画,它由几个“组件”的运动产生。目前,我手工编码SVG标签,但目标是生成它们;以下是我的一个组件的显示方式和我的代码:

<g style="transform-origin:39%;transform: rotate(180deg);">
   <circle id="pippo" cx="0" cy="0" r="5" fill="#333333">
       <animateMotion dur="0.7s" repeatCount="once" fill="freeze"
calcMode="spline" keyTimes="0;1" keySplines="0.27 0 0 1">
           <mpath xlink:href="#shorterPath"/>
       </animateMotion>
   </circle>
</g>

通过javascript创建具有自定义属性的svg实例的好方法是什么?

在javascript中创建动态svg元素和动画。 名称空间 SVG元素必须使用
document.createElements
方法创建,并显式提供SVG命名空间URI“”

svg元素的属性值通常可以使用元素的
setAttribute
setAttributeNS
方法添加

如果使用
setAttribute
添加前缀为
xlink:
的属性名称,则无法正常工作-请使用带有xlink命名空间URI“”的
setattributes

请注意,对
href
属性使用
xlink:
前缀有利于不带前缀的名称“href”

另请参见:关于MDN

性质 如果试图通过将属性值设置为svg元素的属性名称来设置属性值,则当属性为只读时,可能会导致失败。与属性同名的SVG属性可能有一个getter(没有setter)并返回一个实现or接口的对象

比如说,

  • svgElement.className
    可以是只读的-最好使用
    setAttribute(“class”,value)
    元素.classList.add(name,value)
    。看

  • circleShape.r
    是只读的(其他元素的可设置动画的属性的其他属性名也是只读的)。看

例子 注意,
createSvgElement
helper函数使用一个
用于。。。在
循环中,并不是为了处理添加到
对象.prototype的随机可枚举属性而编写的。
xlink:
前缀属性名的代码已测试,但此处未使用

“严格使用”;
函数createSvgElement(标记名、属性){
var元素=document.createElements(
"http://www.w3.org/2000/svg“,标记名);
如果(属性){
for(属性中的var attr){
如果(/^xlink:/.test(attr)){
元素。setAttributeNS(“http://www.w3.org/1999/xlink",
属性[attr]);
}
否则{
setAttribute(attr,attributes[attr]);
}
}
}
返回元素;
}
让svg=createSvgElement(“svg”{
宽度:“200”,
高度:“200”,
查看框:“0 200 200”,
风格:“背景:海蓝宝石”,
});
设defs=createSvgElement(“defs”);
defs.appendChild(createSvgElement(“路径”){
id:“垂直运动路径”,
d:“m 1001000,50”
}));
defs.appendChild(createSvgElement(“路径”){
id:“短路径”,
d:“m 100,70 0,50”
}));
svg.appendChild(defs);
函数circleGroup(originTx、rotateDegrees、pathId、circleId){
设group=createSvgElement(“g”);
团体风格=
“变换原点:”+originTx
+“变换:旋转(“+rotatedgrees+”deg);”;
设circle=createSvgElement(“circle”,{r:5,fill:#333333“});
让am=createSvgElement(“animateMotion”{
dur:“0.7秒”,
重复计数:1,
填充:“冻结”,
calcMode:“样条线”,
关键时刻:“0;1”,
键样条:“0.27 0 0 1”
});
am.appendChild(createSvgElement(“mpath”){
“href”:“#”+pathId
}));
圆。附加子对象(am);
儿童组(圆形);
返回组;
}
//绘制动画并将svg附加到主体
[180,0,60,-60]。forEach(函数(角度){
appendChild(圆圈组(“50%”,角度,“垂直运动路径”);
});
[“61%,“39%”].forEach(函数(originTx){
appendChild(circleGroup(originTx,180,“短路径”);
});

document.body.appendChild(svg)是否要使用香草javascript?是。您是否建议执行其他操作?请确认并要求浏览器支持。Microsoft不支持它,而且运行fiddle HTML代码不会在Edge中显示动画。另一种方法是使用CSS动画进行重新设计,而不是动态创建SVG动画,而是动态创建CSS规则。你想追求哪一个-SMIL还是CSS?谢谢。我不清楚两者的局限性;我会坚持使用SMIL,因为它看起来更强大。我没有全部阅读,但“svg元素的许多属性值必须使用setAttribute或setAttributeNS添加”,不,大多数(如果不是全部)svg属性都有相应的IDL属性。例如,className存在。问题是,其中许多是可设置动画的,因此您需要设置它们的
baseVal
,例如
svgElement.className.baseVal=“foo”
,但是对于这个特别糟糕的示例,您甚至可以更好地使用
元素.prototype.classList
,在HtmleElements和SVGElements上的行为相同。@Kaido非常感谢您的反馈,如果将我看到的许多行为结合起来的话。作为回应,我认真修改了答案。如果你想让Microsoft浏览器执行SMIL,你可以使用它。