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,
|
saveToFileSystem,
|
||||||
openAssetFromFileSystem,
|
openAssetFromFileSystem,
|
||||||
fileToBase64,
|
fileToBase64,
|
||||||
|
fileToText,
|
||||||
getImageSizeFromSrc,
|
getImageSizeFromSrc,
|
||||||
getVideoSizeFromSrc,
|
getVideoSizeFromSrc,
|
||||||
} from './data'
|
} from './data'
|
||||||
|
@ -2889,8 +2890,31 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
||||||
} else {
|
} else {
|
||||||
src = await fileToBase64(file)
|
src = await fileToBase64(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof src === 'string') {
|
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(
|
const match = Object.values(this.document.assets).find(
|
||||||
(asset) => asset.type === assetType && asset.src === src
|
(asset) => asset.type === assetType && asset.src === src
|
||||||
)
|
)
|
||||||
|
@ -2923,6 +2947,17 @@ export class TldrawApp extends StateManager<TDSnapshot> {
|
||||||
return this
|
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 */
|
/* 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[]> {
|
export function getImageSizeFromSrc(src: string): Promise<number[]> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const img = new Image()
|
const img = new Image()
|
||||||
|
|
Loading…
Reference in a new issue