javascript - 将复杂的 SVG 文件与 paper.js 结合起来

标签 javascript svg paperjs

我正在尝试将相对复杂的 SVG 结合起来,例如 this一。我想将构成“HELLO”字母的路径与后面的大“A”字母结合起来。在 Inkscape 上,我可以通过选择所有路径并转到 Path->Union 来完成此操作,因此路径将从此转换:

enter image description here

对此:

enter image description here

请注意,中间的“HELLO”字母的路径现在是如何与它们后面的大“A”结合在一起的。我想通过使用 paper.js 来实现相同的目的,因为它是我能找到的使用 SVG 文件进行 bool 运算而不对其进行政治化的最佳解决方案,而且因为我无法在没有 GUI 的情况下使用 Inkscape CLI 来执行此操作.

我创建thispaper.js 中绘制草图以加载 SVG 文件并在所有 CompoundPathsPaths 之间进行联合,希望能够达到相同的效果,但是,显然事情没那么简单,草图生成的路径是:

<path xmlns="http://www.w3.org/2000/svg" d="M-177.63334,-177.64819h755.85598v755.85598h-755.85598z" id="path32" fill="#000000" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"/>

这几乎是一条空路!有 Ant 知道如何实现这一目标吗?我正在考虑像 Inkscape 那样检测形状的任何方法,我的意思是,在 Inkscape 上,您可以单独选择和操作每个字母作为单个形状,所以如果我可以识别每个形状(或闭合路径?),我可以进行并集操作他们之间。

我对如何实现这一目标有点迷茫,因此任何算法、技巧、书籍、博客、代码或任何东西都将受到极大的赞赏!

最佳答案

我终于解决了!我必须确保不联合用作clipMask的路径,并确保使用closePath()方法关闭所有路径。最终代码如下所示:

var canvas = document.getElementById('canvas')
var scope = paper.setup(new paper.Size(200, 200))

var svg = `{put your svg string here}`;

paper.project.importSVG(svg, function(pathItem) {
    // Get Path and CompoundPath which are children from this item
    let paths = pathItem.getItems({
        className: 'Path'
    });
    let compoundPaths = pathItem.getItems({
        className: 'CompoundPath'
    });

    // Filter paths that are inside CompoundPaths
    paths = paths
        .filter((p) => !compoundPaths.some((cp) => cp.children.includes(p)))
        // Filter paths that are used as clipping paths
        .filter((p) => !p.clipMask);
    compoundPaths = compoundPaths.filter((c) => !c.clipMask);

    // Close all paths to ensure a correct union
    for (const path of compoundPaths.filter((c) => !c.closed)) {
        path.closePath();
    }
    for (const path of paths.filter((c) => !c.closed)) {
        path.closePath();
    }

    // If not paths or compound paths are available, return the same input SVG
    if (!paths.length && !compoundPaths.length) {
        debugger;
    }
    else {
        // Merge all the paths to build a single path
        let unitedItem = undefined;
        let compoundPathsStartIndex = 0;
        if (paths.length) {
            unitedItem = paths[0];
            for (let n = 1; n < paths.length; ++n) {
                const path = paths[n];
                unitedItem = unitedItem.unite(path);
            }
        } else {
            unitedItem = compoundPaths[0];
            compoundPathsStartIndex = 1;
        }

        for (let n = compoundPathsStartIndex; n < compoundPaths.length; ++n) {
            const path = compoundPaths[n];
            unitedItem = unitedItem.unite(path);
        }

        // Set fill color otherwise paths exported in the server (which uses node 8) end up without
        //  a filling color
        unitedItem.fillColor = new paper.Color(0, 0, 0);

        // Generate the merged SVG string and save it
        const outputPathString = unitedItem.exportSVG({
            asString: true,
            bounds: new paper.Rectangle(0, 0, pathItem.getBounds().width, pathItem.getBounds().height)
        });
        // let outputSvg = outputPathString;
        let outputSvg = `<?xml version="1.0" encoding="utf-8"?>\n<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="${pathItem.getBounds().width}" height="${pathItem.getBounds().height}">`;
        outputSvg += outputPathString;
        outputSvg += '</svg>';
        
        console.log(outputSvg);
        debugger;
    }
});

包含 SVG 字符串的完整代码是 here因为我将其包含在答案中超出了最大正文长度。

关于javascript - 将复杂的 SVG 文件与 paper.js 结合起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63997581/

相关文章:

javascript - svg 旋转,缩放和平移鼠标

javascript - 如何使用 paperjs 滚动 Canvas ?

javascript - 如何让 GSAP 时间线识别在其中创建的元素?

javascript - JQuery 和 Underscore "each"保证数组的顺序?

javascript - 持续时间日期时间(django rest,json 输入)

javascript - 代码片段解释,函数参数

javascript - 在 google chrome 浏览器中将 HTML 表格导出到 csv

SVG 元素的 Javascript 工具提示

javascript - JavaScript 中的函数 &ID

javascript - PaperJS 在 mouseDown 上创建圆圈时遇到问题