简体   繁体   English

如何更改画布上的 svg 颜色 - Fabricjs

[英]How to change svg color on Canvas - Fabricjs

I'm creating an app with Fabricjs .我正在使用Fabricjs创建一个应用程序。
I have to add an SVG file to the canvas and change the color every time a Minicolors input changes.我必须向画布添加一个 SVG 文件,并在每次Minicolors输入更改时更改颜色。
I first made the browser display the SVG images as SVG codes like so:我首先让浏览器将 SVG 图像显示为 SVG 代码,如下所示:

$('img[src$=".svg"]').each(function(){
var $img = $(this),
    imgURL = $img.attr('src'),
    attributes = $img.prop('attributes');

$.get(imgURL, function(data) {
  // Get the SVG tag, ignore the rest
  var $svg = $(data).find('svg');
  // Remove any invalid XML tags as per http://validator.w3.org
  $svg = $svg.removeAttr('xmlns:a');
  // Make sure that every attribute was copied
  $.each(attributes, function() {
    $svg.attr(this.name, this.value);
  });
  // Replace image with new SVG
  $img.replaceWith($svg);
}, 'xml');
});

Then I loaded the SVG images from the DOM to the canvas when they get clicked on, like so:然后,当单击它们时,我将 DOM 中的 SVG 图像加载到画布上,如下所示:

$('#images').on('click', 'svg', function() {
  var serializer = new XMLSerializer(),
  svgStr = serializer.serializeToString(this);

  fabric.loadSVGFromString(svgStr,function(objects, options) {
    options.id = this.id;
    var obj = fabric.util.groupSVGElements(objects, options);

    canvas.add(obj);

    obj.scaleToHeight(127) // Scales it down to some small size
       .scaleToWidth(90)
       .center() // Centers it (no s**t, Sherlock)
       .setCoords();

    canvas.setActiveObject(obj).renderAll();
  });
});

Now for my next goal, how do I change the path color of the selected svg file?现在为了我的下一个目标,如何更改所选 svg 文件的路径颜色? My main guess would be to follow these steps:我的主要猜测是遵循以下步骤:

  1. Save the left and top positions of the selected SVG保存所选SVG的左侧和顶部位置
  2. Change the color of the SVG image in the DOM更改 DOM 中 SVG 图像的颜色
  3. Remove the selected SVG object删除选定的 SVG 对象
  4. Replace it with the new SVG using the new color at the saved left and top positions使用保存的左侧和顶部位置的新颜色将其替换为新的 SVG

But I thought: "So I have to do all this every time a Minicolors input changes? Won't that be a performance issue later?"但我想:“所以每次 Minicolors 输入更改时我都必须执行所有这些操作?这不会成为以后的性能问题吗?”

Is there a better approach than this?还有比这更好的方法吗? Here's a JSFiddle that will get you started.这是一个可以帮助您入门的JSFiddle Thanks.谢谢。

Answer by Nick Rameau is not working with the latest version of the fabricjs. Nick Rameau 的回答不适用于最新版本的fabricjs。

In my case, I'm working with fabricjs 3.5 .就我而言,我正在使用fabricjs 3.5

In the latest version of the fabricjs, the paths attribute has been removed.在fabricjs 的最新版本中, paths属性已被删除。 The paths data has been added to the _objects property. paths数据已添加到_objects属性。

This is how, I got it working for me.就是这样,我让它为我工作。

var obj = this.canvas.itemObj;
var color = '#ff00ff';

if (obj && obj._objects) {
  for (var i = 0; i < obj._objects.length; i++) {
    obj._objects[i].set({
      fill: color
    });
  }
}

When added to the canvas, the SVG object contains a property called "paths", which contains all the paths that build the image.添加到画布后,SVG 对象包含一个名为“paths”的属性,其中包含构建图像的所有路径。 So we do:所以我们这样做:

activeObject.paths.forEach(function(path) {path.fill = color});

But I wonder if it won't be a performance issue for huge SVG files (I won't get to that point, hopefully).但我想知道对于巨大的 SVG 文件是否不会成为性能问题(希望我不会达到那个点)。 Here's a working JSFiddle .这是一个有效的JSFiddle

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM