leafer-ui icon indicating copy to clipboard operation
leafer-ui copied to clipboard

矢量导入SVG,这种思路可行否?

Open ajaxjs opened this issue 1 month ago • 1 comments

可复制到Playground去看看,有何建议。 https://www.leaferjs.com/playground/

import { App } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件  
import '@leafer-in/viewport' // 导入视口插件 (可选)

const app = new App({
    view: window,
    editor: {}  //  配置 editor 会自动创建并添加 app.editor 实例、tree 层、sky 层
})

function svgToPath(svgString: string) {
    const parser = new DOMParser();
    // 解析HTML字符串为Document对象
    const doc = parser.parseFromString(svgString, "image/svg+xml");
    // 
    const attrToObj = (attrs: NamedNodeMap, res: any = {}) => {
        Array.from(attrs).reduce((obj: any, attr) => {
            obj[attr.name] = !isNaN(Number(attr.value)) ? +attr.value : attr.value;
            return obj;
        }, res);
        return res;
    }
    const svgAttrs = attrToObj(doc.documentElement.attributes, {});
    const svgData = Array.from(doc.documentElement.children).map(item => {
        const name = String(item.nodeName).replace(/^[a-z]/, match => match.toUpperCase())
        let itemObj: any = {
            tag: name,
            stroke: '#32cd79',
            strokeWidth: svgAttrs['stroke-width'],
            strokeJoin: svgAttrs['stroke-linecap'],
            strokeCap: svgAttrs['stroke-linejoin']
        }
        if (item.nodeName === 'path') {
            itemObj.path = item.attributes[0].nodeValue
        } else if (item.nodeName === 'rect') {
            attrToObj(item.attributes, itemObj)
        }
        return itemObj
    });
    return { tag: 'Group', children: svgData, editable: true }
}

const svgData = svgToPath(`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-memory-stick-icon lucide-memory-stick"><path d="M6 19v-3"/><path d="M10 19v-3"/><path d="M14 19v-3"/><path d="M18 19v-3"/><path d="M8 11V9"/><path d="M16 11V9"/><path d="M12 11V9"/><path d="M2 15h20"/><path d="M2 7a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v1.1a2 2 0 0 0 0 3.837V17a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-5.1a2 2 0 0 0 0-3.837Z"/></svg>`)

app.tree.add(svgData)

ajaxjs avatar Nov 16 '25 15:11 ajaxjs

解析简单的svg,这样弄是可以的。

要想能解析复杂的svg,需要把逻辑分解的更细,为每一个svg标签建一个解析类,方便以后扩展、维护。

leaferjs avatar Nov 17 '25 00:11 leaferjs