如何使用 javascript 生成 SMIL
How to generate SMIL with javascript
我正在尝试用 SMIL
生成一个 svg
并且很难弄清楚为什么它不起作用。
代码如下
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//assigning svg element attribute
svg.setAttribute('class', 'layer1');
svg.setAttribute('xmlns', svgns);
svg.setAttribute('viewBox', '0 0 1280 720');
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute('class', 'bg');
bg.setAttribute('id', 'bg');
bg.setAttribute("width", '1280');
bg.setAttribute("height", '720');
bg.setAttribute("fill", "#F1C40F");
svg.appendChild(bg);
let pth = document.createElementNS(svgns, 'path');
pth.setAttribute('class', 'pth');
pth.setAttribute('id', 'pth');
pth.setAttribute('d',
'M10,20, L110,20, L110,140, L10,140 ,Z'
);
pth.style.setProperty("stroke-width", ".5");
pth.style.setProperty("stroke", "red");
pth.setAttribute('fill', 'red');
svg.appendChild(pth);
let anim = document.createElementNS(svgns, 'animate');
anim.setAttribute('attributeName', 'd');
anim.setAttribute('attributeType', 'XML');
anim.setAttribute('values', "M10,20, L110,20, L110,140, L10,140 ,Z; M10,20, L210,20, L210,140, L10,140 ,Z; M10,20, L110,20, L110,140, L10,140 ,Z");
anim.setAttribute('keyTimes', '0;0.5;1');
anim.setAttribute('begin', '0s');
anim.setAttribute('end', '1s');
anim.setAttribute('repeatCount', 'indefinite');
svg.appendChild(anim);
pth.appendChild(anim);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<link rel="stylesheet" href="style.css">
</link>
<svg>
<script href="index.js"></script>
<!--
<rect class="bg" id="bg" width="1280" height="720" fill="#F1C40F"></rect>
<path class="pth" id="pth" d="M10,20, L110,20, L110,140, L10,140 ,Z" fill="red"
style="stroke-width: 0.5; stroke: red;">
<animate attributeName="d"
attributeType="XML"
values=
"M10,20, L110,20, L110,140, L10,140 ,Z
;M10,20, L210,20, L210,140, L10,140 ,Z
;M10,20, L110,20, L110,140, L10,140 ,Z"
keyTimes="0;.5;1"
begin="0s"
dur="1s"
repeatCount="indefinite"
/>
</path>-->
</svg>
</html>
但是,未注释的 SVG 可以与 SMIL 一起正常工作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<link rel="stylesheet" href="style.css">
</link>
<svg>
<script href="index.js"></script>
<rect class="bg" id="bg" width="1280" height="720" fill="#F1C40F"></rect>
<path class="pth" id="pth" d="M10,20, L110,20, L110,140, L10,140 ,Z" fill="red"
style="stroke-width: 0.5; stroke: red;">
<animate attributeName="d"
attributeType="XML"
values=
"M10,20, L110,20, L110,140, L10,140 ,Z
;M10,20, L210,20, L210,140, L10,140 ,Z
;M10,20, L110,20, L110,140, L10,140 ,Z"
keyTimes="0;.5;1"
begin="0s"
dur="1s"
repeatCount="indefinite"
/>
</path>
</svg>
</html>
更新
动画效果很好,具有完全相同的 d
值以及 begin
和 dur
。
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//assigning svg element attribute
/*
svg.setAttribute('class', 'layer1');
svg.setAttribute('xmlns', svgns);
svg.setAttribute('viewBox', '0 0 1280 720');
*/
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute('class', 'bg');
bg.setAttribute('id', 'bg');
bg.setAttribute("width", '1280');
bg.setAttribute("height", '720');
bg.setAttribute("fill", "#F1C40F");
svg.appendChild(bg);
let pth = document.createElementNS(svgns, 'path');
pth.setAttribute('class', 'pth');
pth.setAttribute('id', 'pth');
pth.setAttribute('d',
'M10,20, L110,20, L110,140, L10,140 ,Z'
);
pth.style.setProperty("stroke-width", ".5");
pth.style.setProperty("stroke", "red");
pth.setAttribute('fill', 'red');
svg.appendChild(pth);
let anim = document.createElementNS(svgns, 'animate');
anim.setAttribute('attributeName', 'd');
anim.setAttribute('attributeType', 'XML');
anim.setAttribute('values', "M10,20, L110,20, L110,140, L10,140 ,Z; M10,20, L210,20, L210,140, L10,140 ,Z; M10,20, L110,20, L110,140, L10,140 ,Z");
anim.setAttribute('keyTimes', '0;0.5;1');
anim.setAttribute('begin', '2s');
anim.setAttribute('dur', '1s');
anim.setAttribute('repeatCount', 'indefinite');
svg.appendChild(anim);
pth.appendChild(anim);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<svg>
<script href="index.js"></script>-
<!--
<rect class="bg" id="bg" width="1280" height="720" fill="#F1C40F"></rect>
<path class="pth" id="pth" d="M10,20, L110,20, L110,140, L10,140 ,Z" fill="red"
style="stroke-width: 0.5; stroke: red;">
<animate attributeName="d"
attributeType="XML"
values="M10,20, L110,20, L110,140, L10,140 ,Z; M10,20, L210,20, L210,140, L10,140 ,Z; M10,20, L110,20, L110,140, L10,140 ,Z"
keyTimes="0;.5;1"
begin="2s"
dur="1s"
repeatCount="indefinite"
/>
</path>-->
</svg>
</html>
我通过删除逗号(字母前不允许,谢谢,@ccprog)清理了 d
值,删除了 begin
和 end
属性并添加了 dur
属性。就是这样。
更新
如果您将 begin
属性设置为“不确定”,动画将开始,然后您在 <animate>
上调用函数 beginElement()
。这里我加了一个setTimeout()
来说明。
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//assigning svg element attribute
svg.setAttribute('class', 'layer1');
svg.setAttribute('xmlns', svgns);
svg.setAttribute('viewBox', '0 0 1280 720');
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute('class', 'bg');
bg.setAttribute('id', 'bg');
bg.setAttribute("width", '1280');
bg.setAttribute("height", '720');
bg.setAttribute("fill", "#F1C40F");
svg.appendChild(bg);
let pth = document.createElementNS(svgns, 'path');
pth.setAttribute('class', 'pth');
pth.setAttribute('id', 'pth');
pth.setAttribute('d', 'M 10 20 L 110 20 L 110 140 L 10 140 Z');
pth.style.setProperty("stroke-width", ".5");
pth.style.setProperty("stroke", "red");
pth.setAttribute('fill', 'red');
svg.appendChild(pth);
let anim = document.createElementNS(svgns, 'animate');
anim.setAttribute('attributeName', 'd');
anim.setAttribute('attributeType', 'XML');
anim.setAttribute('values', "M 10 20 L 110 20 L 110 140 L 10 140 Z;M 10 20 L 210 20 L 210 140 L 10 140 Z;M 10 20 L 110 20 L 110 140 L 10 140 Z");
anim.setAttribute('keyTimes', '0;.5;1');
anim.setAttribute('begin', 'indefinite');
anim.setAttribute('dur', '2s');
anim.setAttribute('repeatCount', 'indefinite');
svg.appendChild(anim);
pth.appendChild(anim);
setTimeout(function(){anim.beginElement();}, 2000);
<svg></svg>
我正在尝试用 SMIL
生成一个 svg
并且很难弄清楚为什么它不起作用。
代码如下
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//assigning svg element attribute
svg.setAttribute('class', 'layer1');
svg.setAttribute('xmlns', svgns);
svg.setAttribute('viewBox', '0 0 1280 720');
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute('class', 'bg');
bg.setAttribute('id', 'bg');
bg.setAttribute("width", '1280');
bg.setAttribute("height", '720');
bg.setAttribute("fill", "#F1C40F");
svg.appendChild(bg);
let pth = document.createElementNS(svgns, 'path');
pth.setAttribute('class', 'pth');
pth.setAttribute('id', 'pth');
pth.setAttribute('d',
'M10,20, L110,20, L110,140, L10,140 ,Z'
);
pth.style.setProperty("stroke-width", ".5");
pth.style.setProperty("stroke", "red");
pth.setAttribute('fill', 'red');
svg.appendChild(pth);
let anim = document.createElementNS(svgns, 'animate');
anim.setAttribute('attributeName', 'd');
anim.setAttribute('attributeType', 'XML');
anim.setAttribute('values', "M10,20, L110,20, L110,140, L10,140 ,Z; M10,20, L210,20, L210,140, L10,140 ,Z; M10,20, L110,20, L110,140, L10,140 ,Z");
anim.setAttribute('keyTimes', '0;0.5;1');
anim.setAttribute('begin', '0s');
anim.setAttribute('end', '1s');
anim.setAttribute('repeatCount', 'indefinite');
svg.appendChild(anim);
pth.appendChild(anim);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<link rel="stylesheet" href="style.css">
</link>
<svg>
<script href="index.js"></script>
<!--
<rect class="bg" id="bg" width="1280" height="720" fill="#F1C40F"></rect>
<path class="pth" id="pth" d="M10,20, L110,20, L110,140, L10,140 ,Z" fill="red"
style="stroke-width: 0.5; stroke: red;">
<animate attributeName="d"
attributeType="XML"
values=
"M10,20, L110,20, L110,140, L10,140 ,Z
;M10,20, L210,20, L210,140, L10,140 ,Z
;M10,20, L110,20, L110,140, L10,140 ,Z"
keyTimes="0;.5;1"
begin="0s"
dur="1s"
repeatCount="indefinite"
/>
</path>-->
</svg>
</html>
但是,未注释的 SVG 可以与 SMIL 一起正常工作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<link rel="stylesheet" href="style.css">
</link>
<svg>
<script href="index.js"></script>
<rect class="bg" id="bg" width="1280" height="720" fill="#F1C40F"></rect>
<path class="pth" id="pth" d="M10,20, L110,20, L110,140, L10,140 ,Z" fill="red"
style="stroke-width: 0.5; stroke: red;">
<animate attributeName="d"
attributeType="XML"
values=
"M10,20, L110,20, L110,140, L10,140 ,Z
;M10,20, L210,20, L210,140, L10,140 ,Z
;M10,20, L110,20, L110,140, L10,140 ,Z"
keyTimes="0;.5;1"
begin="0s"
dur="1s"
repeatCount="indefinite"
/>
</path>
</svg>
</html>
更新
动画效果很好,具有完全相同的 d
值以及 begin
和 dur
。
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//assigning svg element attribute
/*
svg.setAttribute('class', 'layer1');
svg.setAttribute('xmlns', svgns);
svg.setAttribute('viewBox', '0 0 1280 720');
*/
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute('class', 'bg');
bg.setAttribute('id', 'bg');
bg.setAttribute("width", '1280');
bg.setAttribute("height", '720');
bg.setAttribute("fill", "#F1C40F");
svg.appendChild(bg);
let pth = document.createElementNS(svgns, 'path');
pth.setAttribute('class', 'pth');
pth.setAttribute('id', 'pth');
pth.setAttribute('d',
'M10,20, L110,20, L110,140, L10,140 ,Z'
);
pth.style.setProperty("stroke-width", ".5");
pth.style.setProperty("stroke", "red");
pth.setAttribute('fill', 'red');
svg.appendChild(pth);
let anim = document.createElementNS(svgns, 'animate');
anim.setAttribute('attributeName', 'd');
anim.setAttribute('attributeType', 'XML');
anim.setAttribute('values', "M10,20, L110,20, L110,140, L10,140 ,Z; M10,20, L210,20, L210,140, L10,140 ,Z; M10,20, L110,20, L110,140, L10,140 ,Z");
anim.setAttribute('keyTimes', '0;0.5;1');
anim.setAttribute('begin', '2s');
anim.setAttribute('dur', '1s');
anim.setAttribute('repeatCount', 'indefinite');
svg.appendChild(anim);
pth.appendChild(anim);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<svg>
<script href="index.js"></script>-
<!--
<rect class="bg" id="bg" width="1280" height="720" fill="#F1C40F"></rect>
<path class="pth" id="pth" d="M10,20, L110,20, L110,140, L10,140 ,Z" fill="red"
style="stroke-width: 0.5; stroke: red;">
<animate attributeName="d"
attributeType="XML"
values="M10,20, L110,20, L110,140, L10,140 ,Z; M10,20, L210,20, L210,140, L10,140 ,Z; M10,20, L110,20, L110,140, L10,140 ,Z"
keyTimes="0;.5;1"
begin="2s"
dur="1s"
repeatCount="indefinite"
/>
</path>-->
</svg>
</html>
我通过删除逗号(字母前不允许,谢谢,@ccprog)清理了 d
值,删除了 begin
和 end
属性并添加了 dur
属性。就是这样。
更新
如果您将 begin
属性设置为“不确定”,动画将开始,然后您在 <animate>
上调用函数 beginElement()
。这里我加了一个setTimeout()
来说明。
// targeting the svg itself
const svg = document.querySelector("svg");
// variable for the namespace
const svgns = "http://www.w3.org/2000/svg"
//assigning svg element attribute
svg.setAttribute('class', 'layer1');
svg.setAttribute('xmlns', svgns);
svg.setAttribute('viewBox', '0 0 1280 720');
let bg = document.createElementNS(svgns, 'rect');
bg.setAttribute('class', 'bg');
bg.setAttribute('id', 'bg');
bg.setAttribute("width", '1280');
bg.setAttribute("height", '720');
bg.setAttribute("fill", "#F1C40F");
svg.appendChild(bg);
let pth = document.createElementNS(svgns, 'path');
pth.setAttribute('class', 'pth');
pth.setAttribute('id', 'pth');
pth.setAttribute('d', 'M 10 20 L 110 20 L 110 140 L 10 140 Z');
pth.style.setProperty("stroke-width", ".5");
pth.style.setProperty("stroke", "red");
pth.setAttribute('fill', 'red');
svg.appendChild(pth);
let anim = document.createElementNS(svgns, 'animate');
anim.setAttribute('attributeName', 'd');
anim.setAttribute('attributeType', 'XML');
anim.setAttribute('values', "M 10 20 L 110 20 L 110 140 L 10 140 Z;M 10 20 L 210 20 L 210 140 L 10 140 Z;M 10 20 L 110 20 L 110 140 L 10 140 Z");
anim.setAttribute('keyTimes', '0;.5;1');
anim.setAttribute('begin', 'indefinite');
anim.setAttribute('dur', '2s');
anim.setAttribute('repeatCount', 'indefinite');
svg.appendChild(anim);
pth.appendChild(anim);
setTimeout(function(){anim.beginElement();}, 2000);
<svg></svg>