feat: add fallback placeholder image

pr675
Hufe921 3 years ago
parent d0e1c9b526
commit 366374eb10

@ -1,5 +1,6 @@
import { IEditorOption } from '../../../interface/Editor'
import { IElement } from '../../../interface/Element'
import { convertStringToBase64 } from '../../../utils'
import { Draw } from '../Draw'
export class ImageParticle {
@ -18,6 +19,24 @@ export class ImageParticle {
this.draw.getImageObserver().add(promise)
}
protected getFallbackImage(width: number, height: number): HTMLImageElement {
const tileSize = 8
const x = (width - Math.ceil(width / tileSize) * tileSize) / 2
const y = (height - Math.ceil(height / tileSize) * tileSize) / 2
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
<rect width="${width}" height="${height}" fill="url(#mosaic)" />
<defs>
<pattern id="mosaic" x="${x}" y="${y}" width="${tileSize * 2}" height="${tileSize * 2}" patternUnits="userSpaceOnUse">
<rect width="${tileSize}" height="${tileSize}" fill="#cccccc" />
<rect width="${tileSize}" height="${tileSize}" fill="#cccccc" transform="translate(${tileSize}, ${tileSize})" />
</pattern>
</defs>
</svg>`
const fallbackImage = new Image()
fallbackImage.src = `data:image/svg+xml;base64,${convertStringToBase64(svg)}`
return fallbackImage
}
public render(ctx: CanvasRenderingContext2D, element: IElement, x: number, y: number) {
const { scale } = this.options
const width = element.width! * scale
@ -36,6 +55,11 @@ export class ImageParticle {
resolve(element)
}
img.onerror = (error) => {
const fallbackImage = this.getFallbackImage(width, height)
fallbackImage.onload = () => {
ctx.drawImage(fallbackImage, x, y, width, height)
this.imageCache.set(element.id!, fallbackImage)
}
reject(error)
}
})

@ -148,4 +148,12 @@ export function cloneProperty<T>(properties: (keyof T)[], sourceElement: T, targ
delete targetElement[property]
}
}
}
export function convertStringToBase64(input: string) {
const encoder = new TextEncoder()
const data = encoder.encode(input)
const charArray = Array.from(data, byte => String.fromCharCode(byte))
const base64 = window.btoa(charArray.join(''))
return base64
}
Loading…
Cancel
Save