leafer-ui
leafer-ui copied to clipboard
矢量导入SVG,这种思路可行否?
可复制到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)
解析简单的svg,这样弄是可以的。
要想能解析复杂的svg,需要把逻辑分解的更细,为每一个svg标签建一个解析类,方便以后扩展、维护。