50 lines
1.6 KiB
JavaScript
50 lines
1.6 KiB
JavaScript
/**
|
|
* 将 SVG 字符串转为小程序可用的 data URL(base64 在真机上更稳定)
|
|
*/
|
|
|
|
function utf8ToBytes(str) {
|
|
const encoded = encodeURIComponent(str)
|
|
const bytes = []
|
|
for (let i = 0; i < encoded.length; i++) {
|
|
if (encoded.charCodeAt(i) === 37) {
|
|
bytes.push(parseInt(encoded.substring(i + 1, i + 3), 16))
|
|
i += 2
|
|
} else {
|
|
bytes.push(encoded.charCodeAt(i))
|
|
}
|
|
}
|
|
return new Uint8Array(bytes)
|
|
}
|
|
|
|
function bytesToBase64(bytes) {
|
|
if (typeof uni !== 'undefined' && typeof uni.arrayBufferToBase64 === 'function') {
|
|
return uni.arrayBufferToBase64(bytes.buffer)
|
|
}
|
|
if (typeof btoa !== 'undefined') {
|
|
let binary = ''
|
|
for (let i = 0; i < bytes.length; i++) {
|
|
binary += String.fromCharCode(bytes[i])
|
|
}
|
|
return btoa(binary)
|
|
}
|
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
let result = ''
|
|
for (let i = 0; i < bytes.length; i += 3) {
|
|
const a = bytes[i]
|
|
const b = i + 1 < bytes.length ? bytes[i + 1] : 0
|
|
const c = i + 2 < bytes.length ? bytes[i + 2] : 0
|
|
result += chars[a >> 2]
|
|
result += chars[((a & 3) << 4) | (b >> 4)]
|
|
result += i + 1 < bytes.length ? chars[((b & 15) << 2) | (c >> 6)] : '='
|
|
result += i + 2 < bytes.length ? chars[c & 63] : '='
|
|
}
|
|
return result
|
|
}
|
|
|
|
export function svgToDataUrl(svg) {
|
|
const normalized = String(svg || '').trim()
|
|
if (!normalized) return ''
|
|
const base64 = bytesToBase64(utf8ToBytes(normalized))
|
|
return `data:image/svg+xml;base64,${base64}`
|
|
}
|