平滑SVGmatrix在Inkscape中转换
我有一个免费的剪贴画SVG文件,最初在Inkscape中创build,我正在修改以用于Windows 8 JavaScript游戏。 它包含了一个matrix变换应用于周围组的path的许多实例,如下所示:
<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)"> <path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" /> </g>
我希望通过将其应用于Inkscape的path来平滑这一转换,从而减lessanimation过程中的浏览器工作。 但是,当我将这6个matrix值插入Inkscape中的ABCDEF参数并应用它时,它将为IE10引擎提供完全不同的旋转和缩放比例。
我已经检查了很多次,我已经正确映射了6个值。 我究竟做错了什么?
编辑:好的,这里是从IE10和Inkscape截图之前和之后。 对于IE10的情况,SVG直接驻留在空的HTML文档的主体内(在Firefox中呈现完全相同)。 在Inkscape中,我只打开了“before”SVG文件,其中只包含path元素,select了path,并将6个matrix变换值插入到Object> Transform> Matrix中。 我对matrix知之甚less,我只是希望能够像浏览器一样预先应用这些转换,理想地理解为什么Inkscape有所不同。 谢谢。
简短的回答
在Inkscape中input变换matrix参数时,确保选中“编辑当前matrix”,因为如果将新的变换matrix应用于对象,实际上是将该新matrix与对象的现有变换matrix相乘,所以确保你编辑它。
长答案
如何自己重新计算一切。
首先让我们尝试一下了解转换matrix。 变换matrix是将仿射变换(保持直线的变换)应用于vector的快捷巧妙的工具。
所以,如果你有一个向量(比如说2d坐标)和一个变换matrix,并且把它们相乘,那么最终将得到变换后的坐标,并且应用在变换matrix中定义的变换。
计算x'
和y'
的方法如下:
x' = a*x + c*y + ey' = b*x + d*y + f
接下来,我们需要了解一下svg格式。
根据w3c svg规范 , matrix
变换恰好将这6个参数(a,b,c,d,e,f)作为参数。
所以,从你的例子来看,
<g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)">
我们有以下转换matrix参数:
a=0.443 b=0.896 c=-0.896 d=0.443 e=589.739 f=-373.223
现在,如果我们有下面的坐标: x=27, y=-9
,我们可以使用之前定义的变换matrix进行变换:
x' = a*x + c*y + ex' = 0.443*27 + -0.896*-9 + 589.739 x' = 609.764 y' = b*x + d*y + f y' = 0.896*27 + 0.443*-9 -373.223 y' = −353.018
整洁,嗯? 你可以在这里获得更多的信息
但是,这不是全部。 我们还需要了解svgpath数据。
根据w3c svgpathdspecification ,path数据中的每个字母代表一条指令。 跟随指令的每个数字对代表一个坐标值。
从你的例子中,我们有以下path:
<path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />
在这里我们看到,这个path对象使用一个绝对moveto
指令(大写M ),一个相对smooth curveto
三次Bézier曲线(小写s ),一个相对的lineto
指令(小写l ),另一个相对smooth curveto
三次Bézier曲线指令,接着是一个closepath
指令(小写字母z )。
M486,313
翻译为绝对移动到x = 486,y = 313
s27-9,43-29
阅读起来有点复杂,因为一些昏迷被省略,因为如果负数是负数,则不需要,所以负号就像昏迷一样 – 反正,它转化为相对平滑的贝塞尔曲线x = 27,y = -9,x = 43,y = -29 (一个目标点和一个控制点)
等等。
那么,我们如何应用并从您的svg组中删除转换matrix呢? 像这样:
// we read the transformation matrix params // <g transform="matrix(0.443,0.896,-0.896,0.443,589.739,-373.223)"> a=0.443 b=0.896 c=-0.896 d=0.443 e=589.739 f=-373.223 // we read the path data, and transform each instruction // <path d="M486,313s27-9,43-29l26,4,1,23-22,5s-25-6-48-3z" />
M486,313绝对移动到
x' = a*x + c*y + e = a*486 + c*313 + e = 524.589 y' = b*x + d*y + f = b*486 + d*313 + f = 200.892
移到指令现在是M524.589,200.892
S27-9,43-29 – 平滑curveto,对每个坐标重复相同的过程,但是将e
和f
(平移参数)设置为0,因为它是相对的指令而不是绝对的。
就是现在
s20.025,20.205,45.033,25.680999999999997
l26,4,1,23-22,5
会变成
l7.934000000000001,25.067999999999998,-20.165,11.085,-14.226,-17.497
S-25-6-48-3
会变成
S-5.698999999999999,-25.058000000000003,-18.576,-44.337
而z将保持z
所以最终的转换path将是:
<path d="M524.589,200.892s20.025,20.205,45.033,25.680999999999997l7.934000000000001,25.067999999999998,-20.165,11.085,-14.226,-17.497s-5.698999999999999,-25.058000000000003,-18.576,-44.337z" />
我希望这对你有意义。
您可以使用path – >联合(CTRL ++)来烘烤selectpath的坐标。 希望这可以帮助
粘贴到位可以帮助您:
- 双击 Inkscape中的组 ,input它。
- 按Ctrl + A select组中的所有内容,并用Ctrl + C 复制它们。
- 双击组外部离开组。
- 编辑“>” 粘贴到位“ (Ctrl + Alt + V) – 此时,组转换将应用于粘贴的对象。
- 再次分组对象(Ctrl + G)
- 将新组移动到与原始组相同的深度,并删除原始组 。 (使用XML编辑器Ctrl + Shift + X可能会更容易一些。)
在@andraaspar的回答之后,您还可以尝试取消分组(Ctrl-U)并再次分组(Ctrl-G)。 它为我工作。
感谢ArtBIT所有的信息! 我在PHP应用程序中遇到了一些问题,并编写了一个处理字体数据(来自SVG文件)的库,并对其进行任何types的转换。 任何有兴趣的人都可以试试GitHub:
https://github.com/kartsims/easysvg
用法示例:
require 'easySVG.php'; $svg = new EasySVG(); $svg->setFont("paris-bold-webfont.svg", 100, "#000000"); $svg->addText("Simple text display"); $svg->addAttribute("width", "800px"); $svg->addAttribute("height", "100px"); echo $svg->asXML();
SVG数据操作示例:
$def = 'YOUR SVG DEFINITION HERE'; $easySVG = new EasySVG(); // rotate by 40° $rotated_def = $easySVG->defRotate($def, 40) // rotate by 40° with center at (200,100) $rotated_def2 = $easySVG->defRotate($def, 40, 200, 100) // scale transform : width*4 $scaled_def = $easySVG->defScale($def, 4)