vue.js 动态生成的SVG不使用剪切路径

4sup72z8  于 2023-01-26  发布在  Vue.js
关注(0)|答案(2)|浏览(172)

我有一个SVG文件,我用vite-svg-loader用Vue JS导入。我把这个文件作为一个原始字符串导入,如下所示:

import DelawareBounds from './assets/images/DelawareOutlineNew.min.svg?raw'

然后,我将字符串读入SVG元素,如下所示:

const parser = new DOMParser();
        const DelawareMask = parser.parseFromString(DelawareBounds, "image/svg+xml").documentElement

然后,我向svg添加一些内容,并从svg中已经存在的#DelawareBounds添加一个clip-path

const dataGroup = document.createElementNS('http://www.w3.org/2000/svg','g')
            dataGroup.setAttributeNS('http://www.w3.org/2000/svg','id','data')
            dataGroup.setAttributeNS('http://www.w3.org/2000/svg','clip-path','url(#DelawareBounds)')

            let pathGroup
            for (let path of paths) {
                pathGroup = document.createElementNS('http://www.w3.org/2000/svg','g')                                
                pathGroup.setAttribute('style','transform: scale('+xScale+','+yScale+')')
                pathGroup.setAttributeNS('http://www.w3.org/2000/svg','class','delaware-bounds-scale')
                pathGroup.appendChild(path)

                dataGroup.appendChild(pathGroup)
            }

            DelawareMask.appendChild(dataGroup)

当我用这种方式添加内容时,clip-path不起作用。如果我把生成的内容粘贴到一个新文件中,clip-path就能很好地工作。
根据我的研究,大多数这类问题都归结为确保分配正确的svg名称空间,对于我所有的动态内容,我都确保添加了名称空间。
我唯一能想到的是,当我解析导入的svg字符串时,数据内容没有进入正确的名称空间。我不知道这里还能做什么?任何建议都是非常感谢的。
在添加动态内容之前,svg如下所示:

<svg version="1.2" viewBox="0 0 2431 5145" xmlns="http://www.w3.org/2000/svg" fill="none">
    <defs>
      <clipPath id="DelawareBounds">
        <path d="...some content here..."/>
      </clipPath>
    </defs>
</svg>

添加动态内容后,svg如下所示:

<svg version="1.2" viewBox="0 0 2431 5145" xmlns="http://www.w3.org/2000/svg" fill="none">
    <defs>
      <clipPath id="DelawareBounds">
        <path d="...some content here..."/>
      </clipPath>
    </defs>
    <g id="data" clip-path="url(#DelawareBounds)">
      ...some data here... 
    </g>
</svg>

结果是数据显示正确,但clip-path不剪切数据内容。

ctehm74n

ctehm74n1#

我找到了解决我问题的方法,但仍然好奇是否有其他方法可以做到这一点。
我的解决方案是包括:

<g id="data" clip-path="url(#DelawareBounds)"></g>

然后在#data组中添加内容就可以了,而不是动态生成上面的行和里面的内容。

yr9zkbsy

yr9zkbsy2#

通常只有元素在特定的命名空间中创建。
属性通常位于空命名空间中,因此正确的代码为。

const dataGroup = document.createElementNS('http://www.w3.org/2000/svg','g')
            dataGroup.setAttribute('id','data')
            dataGroup.setAttribute('clip-path','url(#DelawareBounds)')

            let pathGroup
            for (let path of paths) {
                pathGroup = document.createElementNS('http://www.w3.org/2000/svg','g')                                
                pathGroup.setAttribute('style','transform: scale('+xScale+','+yScale+')')
                pathGroup.setAttribute('class','delaware-bounds-scale')
                pathGroup.appendChild(path)

                dataGroup.appendChild(pathGroup)
            }

            DelawareMask.appendChild(dataGroup)

相关问题