import { reactive } from "vue"; import { Pos, Size } from "./math"; let imageCache: Record>; let imageCache1: Record; export let imageInfo: Record> = reactive({}) export let getImage = (url: string): Promise => { imageCache = {}; imageCache1 = {}; getImage = (url: string) => { if (url in imageCache) { if (imageCache1[url]?.width === 0 || imageCache1[url]?.height === 0) { delete imageCache1[url] delete imageCache[url]; delete imageInfo[url] } else { return imageCache[url]; } } return (imageCache[url] = new Promise((resolve, reject) => { const image = new Image(); image.crossOrigin = "anonymous"; image.onload = () => { resolve(image); imageInfo[url] = { width: image.width, height: image.height } imageCache1[url] = image }; image.onerror = (e) => { console.error(e) reject(e); }; image.src = url; })); }; return getImage(url); }; export const isSvgString = (str: string) => { // 检查字符串是否以 标签开头 const svgRegex = /^]*>.*<\/svg>$/is; return svgRegex.test(str); } let svgContentCache: Record>; export let getSvgContent = (url: string): Promise => { svgContentCache = {}; getSvgContent = async (url: string) => { if (isSvgString(url)) { return url; } if (url in svgContentCache) { return svgContentCache[url]; } else { const res = await fetch(url); return (svgContentCache[url] = res.text()); } }; return getSvgContent(url); }; export type SVGPath = { fill?: string; stroke?: string; strokeWidth?: number; data: string; }; export type SVGParseResult = Size & Pos & { paths: SVGPath[]; }; let svgParseCache: Record; let helpDOM: HTMLDivElement; export let parseSvgContent = (svgContent: string): SVGParseResult => { svgParseCache = {}; helpDOM = document.createElement("div"); helpDOM.style.position = "absolute"; helpDOM.style.left = "-99999px"; helpDOM.style.top = "-99999px"; parseSvgContent = (svgContent: string) => { if (svgContent in svgParseCache) return svgParseCache[svgContent]; helpDOM.innerHTML = svgContent; document.body.appendChild(helpDOM); let right = 0; let bottom = 0; let x = Number.MAX_VALUE; let y = Number.MAX_VALUE; const svgPaths = Array.from(helpDOM.querySelectorAll("path")); const paths = svgPaths.map((path) => { const box = path.getBBox(); x = Math.min(box.x, x); y = Math.min(box.y, y); right = Math.max(right, box.x + box.width); bottom = Math.max(bottom, box.y + box.height); const fill = path.getAttribute("fill")!; const data = path.getAttribute("d")!; const stroke = path.getAttribute("stroke")!; const strokeWidth = path.getAttribute("stroke-width")!; return { fill, data, stroke, strokeWidth: (strokeWidth && Number(strokeWidth)) || 1, }; }); helpDOM.innerHTML = ""; document.body.removeChild(helpDOM); return (svgParseCache[svgContent] = { paths, width: right - x, height: bottom - y, x, y }); }; return parseSvgContent(svgContent); };