问题描述
是否有任何支持可变厚度路径/笔触的矢量图形标准,例如从手写笔输入中:
某些平滑程度是可以接受的。我认为最好的存储方式是将其作为常规路径(例如this),然后在路径中的各个点上逐点稀疏厚度信息,它们之间具有渐变。
我看过SVG,但似乎没有可以支持它的元素。有矢量图形标准可以吗?
解决方法
不幸的是,已经提出了该建议,但尚未将其进一步发展为SVG标准:
https://www.w3.org/Graphics/SVG/WG/wiki/Proposals/Variable_width_stroke
您最好的选择是根据所需的内部曲线和笔触宽度生成自己的轮廓曲线。
在使用其宽度工具时,Adobe Illustrator会执行此操作,而Inkscape也有一个feature。
从技术上讲,为了回答您的问题,.ai文件格式的确保存了笔划宽度信息,但是当导出到SVG时,它是带有填充的封闭路径。
,当前实施的单个路径不允许厚度可变。有W3.org proposal for SVG standard,但到目前为止,纯SVG都没有实现。
“可变厚度的路径”有几种实现方式,但是依赖于svg对象(例如,多个路径)和c ++或javascript函数。
- PowerStroke是Inkscape中这种可变厚度笔划想法的实现。 here是c ++中源代码的一个很好的入口。
SVG和javascript还有其他实现,它们依赖于多个路径:
-
Tubefy,一组少数js函数,其原理基于线性插值。 Tubefy有几种实现,最简单的是:
$ = 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,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() + ")"; }
-
Variable Stroke-Width,基于多路径,这可能是满足您需求的最佳答案。
在其中一个示例中,js函数使用Tubefy,并直接在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],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>