Extract SVGs size from viewBox attibute (#590)
This commit is contained in:
parent
e43219ded8
commit
32203637f2
2 changed files with 48 additions and 1 deletions
|
@ -51,6 +51,7 @@ import {
|
|||
saveToFileSystem,
|
||||
openAssetFromFileSystem,
|
||||
fileToBase64,
|
||||
fileToText,
|
||||
getImageSizeFromSrc,
|
||||
getVideoSizeFromSrc,
|
||||
} from './data'
|
||||
|
@ -2889,8 +2890,31 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||
} else {
|
||||
src = await fileToBase64(file)
|
||||
}
|
||||
|
||||
if (typeof src === 'string') {
|
||||
const size = isImage ? await getImageSizeFromSrc(src) : await getVideoSizeFromSrc(src)
|
||||
let size = [0, 0]
|
||||
if (isImage) {
|
||||
// attempt to get actual svg size from viewBox attribute as
|
||||
if (extension[0] == '.svg') {
|
||||
let svgString: string | ArrayBuffer | null
|
||||
let viewBoxAttribute: string | null
|
||||
let viewBox: string[]
|
||||
|
||||
svgString = await fileToText(file)
|
||||
viewBoxAttribute = this.getViewboxFromSVG(svgString)
|
||||
if (viewBoxAttribute) {
|
||||
viewBox = viewBoxAttribute.split(' ')
|
||||
size[0] = parseFloat(viewBox[2])
|
||||
size[1] = parseFloat(viewBox[3])
|
||||
}
|
||||
}
|
||||
if (size == [0,0]) {
|
||||
size = await getImageSizeFromSrc(src)
|
||||
}
|
||||
} else {
|
||||
size = await getVideoSizeFromSrc(src)
|
||||
}
|
||||
|
||||
const match = Object.values(this.document.assets).find(
|
||||
(asset) => asset.type === assetType && asset.src === src
|
||||
)
|
||||
|
@ -2923,6 +2947,17 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
|||
return this
|
||||
}
|
||||
|
||||
private getViewboxFromSVG = (svgStr: string | ArrayBuffer | null) => {
|
||||
const viewBoxRegex = /.*?viewBox=["'](-?[\d\.]+[, ]+-?[\d\.]+[, ][\d\.]+[, ][\d\.]+)["']/
|
||||
if (typeof svgStr === 'string') {
|
||||
const matches = svgStr.match(viewBoxRegex)
|
||||
return matches && matches.length >= 2 ? matches[1] : null;
|
||||
}
|
||||
console.warn('could not get viewbox from svg string')
|
||||
this.setIsLoading(false)
|
||||
return null
|
||||
}
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* Event Handlers */
|
||||
/* -------------------------------------------------- */
|
||||
|
|
|
@ -129,6 +129,18 @@ export function fileToBase64(file: Blob): Promise<string | ArrayBuffer | null> {
|
|||
})
|
||||
}
|
||||
|
||||
export function fileToText(file: Blob): Promise<string | ArrayBuffer | null> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (file) {
|
||||
const reader = new FileReader()
|
||||
reader.readAsText(file)
|
||||
reader.onload = () => resolve(reader.result)
|
||||
reader.onerror = (error) => reject(error)
|
||||
reader.onabort = (error) => reject(error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function getImageSizeFromSrc(src: string): Promise<number[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image()
|
||||
|
|
Loading…
Reference in a new issue