将SVG绘制到Canvas中并使用其ID操纵绘制的元素

M O*_*O H 6 html javascript svg canvas

我有一个SVG文件加载到<object>标签.我正在使用javascript来操纵这个svg中的一些元素.例如:

var theSvgXml = document.getElementById('theObject').contentDocument;
theSvgXml.getElementById('theElementId').style.display = 'inline';
theSvgXml.getElementById('theElementId').style.fill = 'red';
theSvgXml.getElementById('anotherElement').style.display = 'none';
Run Code Online (Sandbox Code Playgroud)

这很完美,一切都很顺利.但我想知道是否可以用画布做同样的事情.我已经阅读了关于kinetic js,fabric js,canvg js的内容,我看到了通过文件目录,xml或图像将svg文件加载到画布中的各种方法.

但是在将这个svg文件绘制到画布之后,我可以通过它们的ID来操作这些元素吗?

SVG是使用Adove Illustrator创建的,每个图层或组都有一个id,可以使用css选择器访问.再次,可以在将SVG绘制到画布上之后在画布中完成.(请注意,SVG是巨大的,我考虑画布解决方案的唯一原因是因为svg没有显示插图画家的多重效果来创建阴影)

任何帮助将受到高度赞赏.谢谢.

代码片段:

<g id="Pockets">
<g id="Pen__x26__Radio_Arm_Pocket" class="st791"> … </g>
<g id="Pen_Pocket_Arm" class="st791"> … </g>
<g id="Card_Zipper_Arm_Pocket" class="st791"> … </g>
<g id="Radio_Pocket_Arm_Pocket" class="st791"> … </g>
<g id="Angled_Chest_Pocket_Right" class="st791"> … </g>
<g id="Angled_Chest_Pocket_Left" class="st791"> … </g>
<g id="Angled_Chest_Pocket_left_and_Right" class="st791"> … </g>
<g id="Chest_Pocket_Right" class="st791"> … </g>
<g id="Chest_Pocket_Left" class="st791"> … </g>
<g id="Chest_Pocket_left_and_Right" class="st791"> … </g>
<g id="Tool_Pocket" class="st791"> … </g>
<g id="Cargo_x2F_Mobile_Pocket_Velcro" class="st791"> … </g>
<g id="Cargo_x2F_Mobile_Pocket_Zip" class="st791"> … </g>
<g id="Cargo_x2F_Mobile_Pocket_Button" class="st791"> … </g>
<g id="Cargo_Pocket_Velcro" class="st791"> … </g>
<g id="Cargo_Pocket_Button" class="st791"> … </g>
<g id="Cargo_Pocket_Zip" class="st791"> … </g>
<g id="Back_Pocket_Right_Velcro" class="st791"> … </g>
<g id="Back_Pocket_left_Velcro" class="st791"> … </g>
<g id="Back_Pocket_left_and_Right_Velcro" class="st791"> … </g>
<g id="Back_Pocket_Right_Velcro_Button" class="st791"> … </g>
<g id="Back_Pocket_left_Velcro_Button" class="st791"> … </g>
<g id="Back_Pocket_left_and_Right_Button" class="st791"> … </g>
<g id="Back_Pocket_Right_Zip" class="st791"> … </g>
<g id="Back_Pocket_left_Zip" class="st791"> … </g>
<g id="Back_Pocket_left_and_Right_Zip" class="st791"> … </g>
</g>
Run Code Online (Sandbox Code Playgroud)

从adobe illustrator导出文件后,您可以看到形成xml片段,每个组都设置了一个ID.如何将这些作为对象保存在画布中(如Fabrics.js建议使用getObjects()方法)?有没有办法实现这个目标?如果是,我如何参考这些群组?此外,阴影是一个关键问题,我不想使用闪光灯.谢谢

kan*_*gax 9

以下是使用Fabric执行此操作的方法:

fabric.loadSVGFromURL('/assets/72.svg', function(objects, options){

  var group = fabric.util.groupSVGElements(objects, options);

  group
    .set({ left: 300, top: 200 })
    .scaleToWidth(500)
    .setCoords();

  canvas.add(group);
}, reviver);

function reviver(element, object) {
  object.id = element.getAttribute('id');
}
Run Code Online (Sandbox Code Playgroud)

代码应该是不言自明的.我们加载SVG; Fabric在内部解析它,吐出代表每个元素的对象集.然后,我们将这些元素分组,并将它们添加到画布中的一个块中.Reviver负责读取每个SVG元素的id并将其分配给相应的结构实例.

http://fabricjs.com/kitchensink/中运行此代码段,您将获得:

装svg

让我们检查一下这个分组对象:

canvas.item(0) + ''; "#<fabric.PathGroup (29303): { top: 200, left: 300 }>"
Run Code Online (Sandbox Code Playgroud)

它的孩子们:

canvas.item(0).getObjects(); // Array[2287]
Run Code Online (Sandbox Code Playgroud)

让我们通过id检索一个:

var greenland = canvas.item(0).getObjects().filter(function(obj) {
  return obj.id === 'path4206';
})[0];
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这都是普通的旧Javascript.让我们现在改变那个特定物体/形状的颜色:

greenland.fill = 'red';
Run Code Online (Sandbox Code Playgroud)

红色的格陵兰岛