Supporto per corsa a spessore variabile

Oct 27 2020

Esistono standard di grafica vettoriale che supportano tracciati / tratti a spessore variabile, ad esempio da un input dello stilo:

Una certa quantità di levigatura può essere accettabile. Presumo che il modo migliore per memorizzarlo sarebbe come un percorso regolare (ad esempio questo ) e quindi informazioni sullo spessore scarso punto per punto in vari punti del percorso, con gradienti tra di loro.

Ho esaminato SVG ma non sembra esserci un elemento in grado di supportarlo. Esistono standard di grafica vettoriale che possono farlo?

Risposte

1 Soleil Dec 01 2020 at 11:53

Un unico percorso attualmente implementato non consente spessori variabili. Esiste una proposta W3.org per lo standard SVG , ma finora nessuna implementazione in SVG puro.

Esistono diverse implementazioni di un "percorso con spessore variabile", ma che si basa su oggetti svg (es. Percorsi multipli) e funzioni c ++ o javascript.

  • PowerStroke è un'implementazione di tale idea di un tratto a spessore variabile in Inkscape. Una buona voce per il codice sorgente in c ++ è qui .

Esistono altre implementazioni in SVG e javascript, che si basano su più percorsi:

  • Tubefy , un insieme di poche funzioni js, il principio si basa su un'interpolazione lineare. Esistono diverse implementazioni di Tubefy, la più semplice è:

     $ = function (id) { return typeof id=='string'?document.getElementById(id):id };
     var root = document.rootElement;
    
     function lerp(p, a, b) { return Number(a)+(b-a)*p; }
    
     function lerpA(p, a, b) { var c=[];
         for(var i=0; i<a.length; i++) c[i]=lerp(p, a[i], b[i]);
         return c;
     }
    
     function toCss(a){ 
         for(var i=0; i<a.length; i++) a[i]=Math.round(a[i]);
         return "rgb(" + a.join() + ")";
     }
    
  • Larghezza tratto variabile , basata su più percorsi, che potrebbe essere la migliore risposta alle tue esigenze.

In uno degli esempi, la funzione js utilizza Tubefy ed è implementata direttamente nel file svg:

<script>//<![CDATA[
    var op=1, op1=1;

    function vsw0(p0, n, g){    p0=$(p0);
        var SW=p0.getAttribute('stroke-widths').replace(/ /g,'').split(',');
        var T=p0.getTotalLength();
        var n_1=n-1,  dt=T/n, dash=(dt+1)+','+T;
        p0.setAttribute('stroke-dasharray', dash);

        for(var i=0; i<n; i++){ p=i/n_1;
            var sw=lerp(p, SW[0], SW[1]); // current stroke width
            var off=-i*dt; // current dash offset
            var c=toCss(lerpA(p, [255,0,0], [255,255,0])); // curr color

            var newP=p0.cloneNode(true);
            newP.setAttribute('style', 'stroke-width:'+sw+';stroke-dashoffset:'+off+';stroke:'+c);
            $(g).appendChild(newP); } } function f(){ $('abg').setAttribute('stroke', $('bg').getAttribute('fill')) }

//]]></script>
</svg>

1 Manstie Dec 01 2020 at 09:48

Sfortunatamente questo è stato proposto ma non ulteriormente sviluppato come standard SVG:

https://www.w3.org/Graphics/SVG/WG/wiki/Proposals/Variable_width_stroke

La soluzione migliore sarebbe generare la propria curva di contorno in base alla curva interna e alle larghezze del tratto desiderate.

Adobe Illustrator lo fa quando usa il loro strumento di larghezza e Inkscape ha una funzione che fa anche questo.

Quindi, tecnicamente, per rispondere alla tua domanda, il formato di file .ai salva le informazioni sulla larghezza del tratto, ma quando esportato in SVG è un tracciato chiuso con riempimento.