This commit is contained in:
th committed 2026-04-19 17:53:36 +02:00
commit c6863f2bfc
34 files changed
+6909

No files matched your search

+53
View File
@@ -0,0 +1,53 @@
export function readAsDataUrl(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => resolve(reader.result as string)
reader.onerror = () => reject(reader.error)
reader.readAsDataURL(file)
})
}
export function loadImage(src: string): Promise<HTMLImageElement> {
return new Promise((resolve, reject) => {
const img = new Image()
img.crossOrigin = 'anonymous'
img.onload = () => resolve(img)
img.onerror = () => reject(new Error(`failed to load image: ${src.slice(0, 60)}…`))
img.src = src
})
}
export interface Dimensions {
width: number
height: number
}
export function parseSvgDimensions(svgText: string): Dimensions | null {
const doc = new DOMParser().parseFromString(svgText, 'image/svg+xml')
const svg = doc.documentElement
if (!svg || svg.nodeName !== 'svg') return null
const parseLen = (attr: string | null) => {
if (!attr) return 0
const num = parseFloat(attr)
return Number.isFinite(num) ? num : 0
}
let w = parseLen(svg.getAttribute('width'))
let h = parseLen(svg.getAttribute('height'))
if (!w || !h) {
const vb = svg.getAttribute('viewBox')?.trim().split(/[\s,]+/).map(Number)
if (vb && vb.length === 4 && vb.every((n) => Number.isFinite(n))) {
if (!w) w = vb[2]
if (!h) h = vb[3]
}
}
if (!w || !h) return null
return { width: w, height: h }
}
export function isSvgFile(file: File): boolean {
return file.type === 'image/svg+xml' || file.name.toLowerCase().endsWith('.svg')
}