【问题标题】:vis.js library - Rendering a network of nodes with svg and custom htmlvis.js 库 - 使用 svg 和自定义 html 渲染节点网络
【发布时间】:2021-04-07 23:18:34
【问题描述】:

我正在使用 vis.js 库,并通过 svg 标记使用自定义 HTML 呈现节点。

我的在线项目在:https://stackblitz.com/edit/visjs-with-angular

我遇到的问题是当我尝试将图像添加到div 时,它位于svg 内。

您可以在我的项目的“app\app\vis”文件夹中看到vis.component.ts,及其关联的 HTML 视图文件。

drawSvgNetwork() 函数中,您将看到我构建 SVG 的位置。我想我可以添加一个带有background-image url<i> 标签,但是当 vis.js 渲染节点时它似乎没有渲染:

var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="390" height="65">' +
          '<rect x="0" y="0" width="100%" height="100%" fill="#7890A7" stroke-width="20" stroke="#ffffff" ></rect>' +
          '<foreignObject x="15" y="10" width="100%" height="100%">' +
          '<div xmlns="http://www.w3.org/1999/xhtml" style="font-family:Arial; font-size:30px">' +
          ' <em>I</em> am' +
          '<span style="color:white; text-shadow:0 0 20px #000000;">' +            
            ' HTML in SVG!</span>' +

          // * THIS IMAGE IS NOT RENDERING * 
          '<i style="background-image: url(https://openclipart.org/download/280615/July-4th-v2B.svg);"></i>' +

          '</div>' +
          '</foreignObject>' +
          '</svg>';

即这是您在运行我的在线项目时将看到的内容。

.

*供参考:

完整的在线示例位于:https://visjs.github.io/vis-network/examples/ 而具体的demo页面在这里(查看源码看js代码):https://visjs.github.io/vis-network/examples/network/nodeStyles/HTMLInNodes.html

【问题讨论】:

    标签: javascript angular vis.js


    【解决方案1】:

    看起来visjs 无法在 SVG 中加载外部图像,&lt;foreignObject&gt;&lt;Image&gt; 标记中也一样。 这是github上问题的一个未解决问题:Image tag is not loading inside the svg

    仓库的维护者answered认为这是不可能的。

    可以在同一个线程中找到解决方法(但它可能不适合你):想法是单独加载图像并将其呈现为 dataUrl

    加载 svg 图片并将其转换为 dataUrl:

      loadImage(url) {
        const img = new Image();
    
        img.crossOrigin = "anonymous";
        img.src = url;
    
        return Observable.fromEvent(img, 'load')
            .map((e: Event) => {
                const canvas = document.createElement('canvas');
                canvas.getContext('2d').drawImage(e.target as HTMLImageElement, 0, 0);
                const dataURL = canvas.toDataURL();
                return dataURL;
            })
      }
    
    

    使用获取的dataUrl作为背景而不是直接的svg文件url:

      '<i style="background-image: url(' + dataUrl + '); display: inline-block; width: 40px; height: 20px; background-size: contain;"></i>' +
    

    这是更正后的项目https://stackblitz.com/edit/visjs-with-angular-m63jme(我还用另一个任意svg替换了原始项目中使用的包含美国国旗的svg文件,以避免FF中的问题,见下文)

    在画布上渲染 svg 的 FF 问题

    当文件包含指定为百分比的widthheight 属性时,Firefox 在画布上呈现svg 文件时存在一些问题。有关详细信息,请参阅 SO 问题:12。所以一定要使用带有widthheight 属性的svg,它们不是百分比。

    【讨论】:

    • 这看起来确实是一个可行的选择。我会在某个时候回到我的旧问题并尝试一下。非常感谢。
    • 我看到您正在加载美国国旗 svg,但我没有看到它在任何地方呈现 - 即 this.loadImage('https://openclipart.org/download/280615/July-4th-v2B.svg').subscribe( (dataUrl) =&gt; this.drawSvgNetwork(dataUrl) // DRAW SVG WITH CUSTOM HTML );
    • 它在 Chrome 中肯定可以正常渲染(参见屏幕截图prnt.sc/pkut0w),但我刚刚检查了 FF,令人惊讶的是标志丢失了:P 会调查的。 (顺便说一句,您使用的是什么浏览器?)
    • 修复了项目并在答案中添加了解释。
    • 好东西,谢谢!我可以看到您的 dataUrl 想法效果很好。我仍然不敢相信我差不多一年前就发布了这个!谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    相关资源
    最近更新 更多