Похоже, у вас может быть четыре вопроса:
- Как встроить скрипт в файл SVG?
- Как запустить скрипт внутри файла SVG?
- Как мне получить доступ к данным для элемента
<path>
из скрипта? - Как я могу манипулировать данными для элемента
<path>
из скрипта?
Давайте разберемся с ними однимза один раз:
Как встроить скрипт в файл SVG?
Как описано в спецификации SVG , вы можете поместить элемент <script>
вВаш документ должен содержать код JavaScript.Согласно последним спецификациям SVG, вам не нужно указывать атрибут type
для вашего скрипта.По умолчанию используется значение type="application/ecmascript"
.
- Другие распространенные типы пантомимы включают
"text/javascript"
, "text/ecmascript"
(указано в SVG 1.1), "application/javascript"
и "application/x-javascript"
.У меня нет подробной информации о поддержке всех этих браузеров или об отсутствии атрибута type
.У меня всегда был хороший успех с text/javascript
.
Как и в случае с HTML, вы можете либо поместить код скрипта непосредственно в документ, либо ссылаться на внешний файл.При выполнении последнего вы должны использовать атрибут href
(не src
) для URI с атрибутом в пространстве имен xlink
.
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<script xlink:href="/js/mycode.js" />
<script><![CDATA[
// Wrap the script in CDATA since SVG is XML and you want to be able to write
// for (var i=0; i<10; ++i )
// instead of having to write
// for (var i=0; i<10; ++i )
]]></script>
</svg>
Как запустить скриптвнутри файла SVG?
Как и в случае с HTML, код, включенный в ваш документ SVG, будет запущен, как только он встретится.Если вы поместите свой элемент <script>
над остальной частью документа (как вы могли бы поместить <script>
в <head>
документа HTML), то ни один из ваших элементов документа не будет доступен, когда ваш код выполняется.
Самый простой способ избежать этого - поместить элементы <script>
внизу документа:
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- all SVG content here, above the script -->
<script><![CDATA[
// Now I can access the full DOM of my document
]]></script>
</svg>
В качестве альтернативы, вы можете создать функцию обратного вызова в верхней части документа, котораявызывается только тогда, когда остальная часть документа готова:
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<title>SVG Coordinates for Embedded XHTML Elements</title>
<script>document.documentElement.addEventListener('load',function(){
// This code runs once the 'onload' event fires on the root SVG element
console.log( document.getElementById('foo') );
},false)</script>
<path id="foo" d="M0 0" />
</svg>
Как получить доступ к данным для элемента <path>
из скрипта?
Существует два способа получить доступ к большинствуинформация об элементах в SVG: вы можете получить доступ к атрибуту в виде строки через стандартный метод DOM Level 1 Core getAttribute()
, или вы можете использовать объекты и методы SVG DOM .Давайте рассмотрим оба варианта:
Доступ к данным пути через getAttribute()
Использование getAttribute()
возвращает ту же строку, что и при просмотре источника:
<path id="foo" d="M150 0 L75 200 L225 200 Z" />
<script><![CDATA[
var path = document.getElementById('foo');
var data = path.getAttribute('d');
console.log(data);
//-> "M150 0 L75 200 L225 200 Z"
]]></script>
- Плюсы: очень просто звонить;вам не нужно ничего знать о SVG DOM
- Con: поскольку вы получаете строку, вы должны проанализировать атрибут самостоятельно;для данных SVG
<path>
это может быть мучительно.
Доступ к данным пути с помощью методов SVG DOM
<path id="foo" d="M150 0 L75 200 L225 200 Z" />
<script><![CDATA[
var path = document.getElementById('foo');
// http://www.w3.org/TR/SVG/paths.html#__svg__SVGAnimatedPathData__normalizedPathSegList
// See also path.pathSegList and path.animatedPathSegList and path.animatedNormalizedPathSegList
var segments = path.normalizedPathSegList ;
for (var i=0,len=segments.numberOfItems;i<len;++i){
var pathSeg = segments.getItem(i);
// http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSeg
switch(pathSeg.pathSegType){
case SVGPathSeg.PATHSEG_MOVETO_ABS:
// http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegMovetoAbs
console.log("Move to",pathSeg.x,pathSeg.y);
break;
case SVGPathSeg.PATHSEG_LINETO_ABS:
// http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegLinetoAbs
console.log("Line to",pathSeg.x,pathSeg.y);
break;
case SVGPathSeg.PATHSEG_CLOSEPATH:
// http://www.w3.org/TR/SVG/paths.html#InterfaceSVGPathSegClosePath
console.log("Close Path");
break;
}
}
]]></script>
Приведенный выше скрипт выдает следующий вывод:
Move to 150 0
Line to 75 200
Line to 225 200
Close Path
Плюсы: данные пути анализируются для вас;вы получаете точные цифры от самого API;использование normalizedPathSegList
принимает относительные команды и делает их абсолютными для вас;если SMIL-анимация изменяет данные пути, использование неанимированного pathSegList может дать вам доступ к базовой неанимированной информации, недоступной через getAttribute()
.
Минусы: сладкие шимпанзеПламя, посмотри на этот код!И это даже не обрабатывает все возможные сегменты пути.
Поскольку читать спецификации W3C для SVG DOM может быть сложно, много лет назад я создал онлайн-инструмент для просмотракакие свойства и объекты существуют.Вы можете использовать его здесь: http://objjob.phrogz.net/svg/hierarchy
Как я могу манипулировать данными для элемента <path>
из скрипта
Как и выше, вы можете создать новую строку ииспользуйте setAttribute()
, чтобы вставить его в объект, или вы можете манипулировать SVG DOM.
Управление данными пути с помощью setAttribute()
<path id="foo" d="M150 0 L75 200 L225 200 Z" />
<script><![CDATA[
var path = document.getElementById('foo');
path.setAttribute('d','M150,0 L150,100 200,300 Z');
]]></script>
Управление данными пути с использованием SVG DOM
<path id="foo" d="M150,0 L75,200 l150,0 Z" />
<script><![CDATA[
var path = document.getElementById('foo');
var segments = path.pathSegList;
segments.getItem(2).y = -10;
]]></script>
В общем, вам просто нужно изменить свойства различных экземпляров подкласса SVGPathSeg
;изменения вносятся сразу в DOM.(В приведенном выше примере исходный треугольник перекошен, поскольку последняя точка слегка смещена вверх.)
Когда вам нужно создать новые сегменты пути, вам нужно использовать такие методы, как var newSegment = myPath.createSVGPathSegArcAbs(100,200,10,10,Math.PI/2,true,false)
и затем используйте один из методов, чтобы вставить этот сегмент в список, например, segments.appendItem(newSegment)
.