javascript - code - Scripting<path> data en SVG(lectura y modificación)
svg html (2)
Parece que puede tener cuatro preguntas:
- ¿Cómo incribo script dentro de un archivo SVG?
- ¿Cómo ejecuto el script dentro de un archivo SVG?
- ¿Cómo accedo a los datos de un elemento
<path>
desde el script? - ¿Cómo puedo manipular los datos para un elemento
<path>
del script?
Vamos a abordarlos uno a la vez:
¿Cómo incribo script dentro de un archivo SVG?
Como se describe en la especificación SVG , puede colocar un elemento <script>
en su documento para contener el código JavaScript. De acuerdo con las últimas especificaciones de SVG, no necesita especificar un atributo de type
para su secuencia de comandos. Por defecto se type="application/ecmascript"
.
- Otros tipos de mime comunes incluyen
"text/javascript"
,"text/ecmascript"
(especificado en SVG 1.1),"application/javascript"
y"application/x-javascript"
. No tengo información detallada sobre el soporte del navegador para todos estos, o para omitir el atributo detype
completo. Siempre he tenido un buen éxito con eltext/javascript
.
Al igual que con HTML, puede colocar el código del script directamente en el documento, o puede hacer referencia a un archivo externo. Al hacer esto último, debe usar un atributo href
(no src
) para el URI, con el atributo en el espacio de nombres 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>
¿Cómo ejecuto el script dentro de un archivo SVG?
Al igual que con HTML, el código incluido en su documento SVG se ejecutará tan pronto como se encuentre. Si coloca su elemento <script>
sobre el resto del documento (como podría hacer al colocar <script>
en el <head>
de un documento HTML), ninguno de los elementos del documento estará disponible cuando se ejecute el código.
La forma más sencilla de evitar esto es colocar sus elementos <script>
en la parte inferior de su documento:
<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>
Alternativamente, puede crear una función de devolución de llamada en la parte superior de su documento que solo se invoca cuando el resto del documento está listo:
<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>
¿Cómo accedo a los datos de un elemento <path>
desde el script?
Hay dos formas de acceder a la mayoría de la información sobre los elementos en SVG: puede acceder al atributo como una cadena a través del método básico estándar DOM Nivel 1 getAttribute()
, o puede usar los objetos y métodos DOM SVG . Miremos ambos:
Accediendo a datos de ruta a través de getAttribute()
El uso de getAttribute()
devuelve la misma cadena como la que vería al ver la fuente:
<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>
- Pros: muy simple de llamar; no tienes que saber nada sobre el SVG DOM
- Con: dado que recuperas una cadena, debes analizar el atributo tú mismo; para los datos de SVG
<path>
, esto puede ser insoportable.
Acceso a los datos de ruta a través de los métodos 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>
El script anterior produce el siguiente resultado:
Move to 150 0
Line to 75 200
Line to 225 200
Close Path
Pros: los datos de ruta se analizan por usted; obtienes los números exactos de la API; el uso de
normalizedPathSegList
toma los comandos relativos y los convierte en absolutos para ti; si la animación SMIL está cambiando los datos de la ruta, usar pathSegList no animado puede darle acceso a la información básica, no animada, no disponible a través degetAttribute()
.Contras: dulce chimpancés a-llama, mira ese código! Y eso ni siquiera maneja todos los posibles segmentos de ruta disponibles.
Debido a que puede ser difícil leer las especificaciones W3C para SVG DOM, hace muchos años creé una herramienta en línea para explorar qué propiedades y objetos existen. Puede usarlo aquí: http://objjob.phrogz.net/svg/hierarchy
¿Cómo puedo manipular los datos de un elemento <path>
desde el script
Similar a lo anterior, puede crear una nueva cadena y usar setAttribute()
para setAttribute()
en el objeto, o puede manipular el SVG DOM.
Manipular datos de ruta usando 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>
Manipulación de datos de ruta usando 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>
En general, solo tiene que modificar las propiedades de las diversas instancias de la subclase SVGPathSeg
; los cambios se hacen de inmediato en el DOM. (Con el ejemplo anterior, el triángulo original está sesgado ya que el último punto se mueve ligeramente hacia arriba).
Cuando necesite crear nuevos segmentos de ruta, debe usar métodos como var newSegment = myPath.createSVGPathSegArcAbs(100,200,10,10,Math.PI/2,true,false)
y luego use uno de los métodos para insertar este segmento en la lista, por ejemplo, segments.appendItem(newSegment)
.
¿Puede alguien realmente realmente ayudarme, por favor? He estado buscando formas de ejecutar scripts para mi SVG. ¡Pero todas las cosas que obtuve no coinciden! Y no contiene suficiente información sobre por qué utilizó ese conjunto de códigos. Por ejemplo, uno usa event.target, otro tenía event.getTarget () y otro tenía event.target.firstchild.data. ¿Alguien puede ayudarme, por favor?
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<path d="M150 0 L75 200 L225 200 Z" />
</svg>
es un ejemplo de una ruta svg ¿verdad? Lo que necesito es obtener esas coordenadas, probablemente ponerlas en una variable, y usarlas como coordenadas para otra svg. Entonces, ¿cómo puedo hacer eso? Otra cosa es cómo puedo cambiar esas coordenadas al ingresar números en una interfaz.
Así que traté de buscar respuestas, pero como dije, no encontré la información que necesitaba o quizás simplemente no entendí lo que me mostró.
Elementos de ruta dinámica en SVG con soporte Javascript y Css
var XMAX = 500;
var YMAX = 500;
var _xx=10;
var _reg=100;
var _l=10;
// Create PATH element
for(var x=1;x<20;x++)
{
var pathEl = document.createElementNS("http://www.w3.org/2000/svg", "path");
pathEl.setAttribute(''d'',''M''+_l+'' 100 Q 100 300 ''+_l+'' 500'' );
pathEl.style.stroke = ''rgb(''+(_reg)+'',0,0)'';
pathEl.style.strokeWidth = ''5'';
pathEl.style.fill = ''none'';
$(pathEl).mousemove(function(evt){$(this).css({"strokeWidth":"3","stroke":"#ff7200"}).hide(100).show(500).css({"stroke":"#51c000"})});
document.querySelector(''svg'').appendChild(pathEl);
_l+=50;
}