snap morris library examples descargar javascript svg raphael

javascript - morris - Convierta todos los nodos de texto SVG en nodos de ruta con Raphael JS



snap svg (1)

Si entendí correctamente, básicamente quieres convertir las fuentes en rutas SVG.

Puede convertir las fuentes en comandos de ruta usando Opentype.js .

La lib le devolverá una serie de comandos de trazado (originalmente destinados a dibujar en un elemento Canvas).

Sin embargo, es trivial construir una ruta SVG con esos comandos, ya que la conversión de fuente no incluye ningún comando que sea compatible con el dibujo de ruta de Canvas incompatible con un comando de ruta SVG.

Lo he usado con éxito por la misma razón que usted mencionó anteriormente, sin ningún problema en absoluto.

Como nota al margen, su creador tenía la intención de incluir SVG-paths como devoluciones hace un tiempo, así que no sé si se han implementado aún lo que haría que fuera más fácil para usted, de cualquier manera, funciona para su propósito.

Estoy intentando escribir una función de RaphaelJS que tomará los nodos de texto existentes dentro de una instancia de papel de Rafael y los convertirá en rutas.

El objetivo es replicar la posición, el tamaño y el atributo del texto exactamente como aparece en la página, pero hacer que se represente mediante rutas en lugar de texto. Inicialmente no puedo renderizar el texto usando la función paper.print () de Raphael porque el texto se actualiza dinámicamente y requiere atributos basados ​​en "texto" para hacerlo. La conversión de nodos de texto existentes a rutas se producirá como el paso "final" en el proceso (una vez que se completen las modificaciones de texto).

Estoy haciendo esto para eliminar la necesidad de tener fuentes instaladas para ver o manejar el SVG más tarde.

Los desafíos que enfrento son:

  1. Los nodos de texto pueden incluir tspans con definiciones dy . Las rutas creadas deben estar alineadas a la perfección con cada una de las letras childNode (tspans).

  2. Recuperando los datos de posición reales del nodo de texto, y cada tspan. Aquí es donde estoy teniendo problemas y espero que alguien con más experiencia pueda ayudarme. Como los anchos de trazo y otros atributos afectan los valores de posicionamiento / bbox, no estoy seguro de cuál es el método más eficiente para obtener los datos de posicionamiento correctos para el texto.

Lo que he intentado hasta ahora:

Un simple desglose de mi código.

Escribí una función de atributo personalizada, textFormat, que formatea el texto en una formación escalonada. Esta función analiza el nodo de texto, lo divide por cada letra y agrega una nueva línea /n caracteres, y ajusta la posición para que se vea escalonada.

La función textToPaths es una función de papel que se supone que recorre los nodos de papel y convierte todos los nodos de texto encontrados en una ruta usando la función paper.print () de Raphael. Esta es la función con la que estoy teniendo problemas.

Vea el ejemplo completo de JSFiddle aquí

El código del problema
No estoy seguro de cómo obtener valores exactos y constantes de x para pasar a la función paper.print() . En este momento, estoy usando getBoundingClientRect() pero todavía está apagado y sesgado. Mi suposición es que los anchos de trazo están afectando los cálculos xey.

//Loop through each tspan and print the path for each. var i, children = node.node.childNodes, len = children.length; for (i = 0; i < len; i++) { var tspan = children[i], tspanText = tspan.innerHTML, x = tspan.getBoundingClientRect().left - node.node.getBoundingClientRect().left, //How do I get the correct x value? y = tspan.getBoundingClientRect().top - node.node.getBoundingClientRect().top; //How do I get the correcy y value? var path = paper.print(x, y, tspanText, font, fontSize), attrs = node.attrs; delete attrs.x; delete attrs.y; path.attr(attrs); path.attr(''fill'', ''#ff0000''); //Red, for testing purposes. }

Código completo Ver el ejemplo de JSFiddle

//Register Cufon Font var paper = Raphael(document.getElementById(''paper''), ''600'', ''600''); var text1 = paper.text(100, 100, ''abc'').attr({fill: ''none'',stroke: ''#000000'',"stroke-width": ''12'',"stroke-miterlimit": ''1'',"font-family" : "Lobster", "font-size": ''30px'',''stroke-opacity'': ''1''}); var text2 = paper.text(100, 100, ''abc'').attr({fill: ''none'',stroke: ''#ffffff'',"stroke-width": ''8'',"stroke-miterlimit": ''1'',"font-family" : "Lobster", "font-size": ''30px'',''stroke-opacity'': ''1''}); var text3 = paper.text(100, 100, ''abc'').attr({fill: ''#000000'',stroke: ''#ffffff'',"stroke-width": ''0'',"stroke-miterlimit": ''1'',"font-family" : "Lobster", "font-size": ''30px'',''stroke-opacity'': ''1''}); var text = paper.set(text1, text2, text3); text.attr(''textFormat'', ''stagger''); /* paper.textToPaths * Description: Converts all text nodes to paths within a paper. * * Example: paper.textToPaths(); */ (function(R) { R.fn.textToPaths = function() { var paper = this; //Loop all nodes in the paper. for (var node = paper.bottom; node != null; node = node.next ) { if ( node.node.style.display === ''none'' || node.type !== "text" || node.attrs.opacity == "0") continue; //skip non-text and hidden nodes. //Get the font config for this text node. var text = node.attr(''text''), fontFamily = node.attr(''font-family''), fontSize = parseInt(node.attr(''font-size'')), fontWeight = node.attr(''font-weight''), font = paper.getFont(fontFamily, fontWeight); //Loop through each tspan and print the path for each. var i, children = node.node.childNodes, len = children.length; for (i = 0; i < len; i++) { var tspan = children[i], tspanText = tspan.innerHTML, x = tspan.getBoundingClientRect().left - node.node.getBoundingClientRect().left, //How do I get the correct x value? y = tspan.getBoundingClientRect().top - node.node.getBoundingClientRect().top; //How do I get the correcy y value? var path = paper.print(x, y, tspanText, font, fontSize), attrs = node.attrs; delete attrs.x; delete attrs.y; path.attr(attrs); path.attr(''fill'', ''#ff0000''); //Red, for testing purposes. } } }; })(window.Raphael); textToPaths = function() { //Run textToPaths paper.textToPaths(); }; /* Custom Element Attribute: textFormat * Description: Formats a text element to either staggered or normal text. * * Example: element.attr(''textFormat, ''stagger''); */ paper.customAttributes.textFormat = function( value ) { // Sets the SVG dy attribute, which Raphael doesn''t control var selector = Raphael.svg ? ''tspan'' : ''v:textpath'', has = "hasOwnProperty", $node = $(this.node), text = $node.text(), $tspans = $node.find(selector); console.log(''format''); switch(value) { case ''stagger'' : var stagger = function(el) { var R = Raphael, letters = '''', newline = ''/n''; for (var c=0; c < text.length; c++) { var letter = text[c], append = ''''; if(c < text.length - 1) append = newline; letters += letter+append; } el.attr(''text'', letters); var children = el.node.childNodes; var i, a = el.attrs, node = el.node, len = children.length, letterOffset = 0, tspan, tspanHeight, tspanWidth, tspanX, prevTspan, prevTspanRight = 0, tspanDiff = 0, tspanTemp, fontSize, leading = 1.2, tempText; for (i = 0; i < len; i++) { tspan = children[i]; tspanHeight = tspan.getComputedTextLength(); tspanWidth = tspan.getComputedTextLength(); tspanX = tspan.getAttribute(''x''), prevTspanRight = tspan.getBoundingClientRect().right if(tspanX !== null) { tspanDiff = tspanDiff + prevTspanRight - tspan.getBoundingClientRect().left; var setX = parseInt(tspanX) + parseInt(tspanDiff); tspan.setAttribute(''x'', setX); tspan.setAttribute(''dy'', 15); } prevTspan = tspan; } } stagger(this); break; case ''normal'' : this.attr(''text'', text); break; default : this.attr(''text'', text); break; } eve("raphael.attr.textFormat." + this.id, this, value); // change no default Raphael attributes return {}; }; staggerText = function() { //Run textToPaths text.attr(''textFormat'', ''stagger''); };

Si alguien puede ayudarme a resolver este problema, lo agradecería mucho. ¡Gracias!