feat:web Add image placeholder

This commit is contained in:
wangxiangyuan 2023-08-28 12:01:27 +08:00 committed by osborn
parent e198c92530
commit 0c83159523
4 changed files with 177 additions and 23 deletions

View File

@ -245,6 +245,15 @@ class ImageDemo extends Panel {
scaleType: ScaleType.Tile,
layoutConfig: layoutConfig().just(),
}),
label("placeHolder"),
image({
imageUrl: "https://p.upyun.com/eror.404",
layoutConfig: layoutConfig().just(),
height: 100,
width: 100,
placeHolderColor: Color.GREEN,
errorColor: Color.RED,
}),
],
{
layoutConfig: layoutConfig().most().configHeight(LayoutSpec.FIT),

View File

@ -6507,7 +6507,6 @@ var doric_web = (function (exports, axios, sandbox) {
}
}
set backgroundColor(v) {
console.log('background');
if (typeof v === 'number') {
this.applyCSSStyle({ backgroundColor: toRGBAString(v) });
}
@ -7238,21 +7237,30 @@ var doric_web = (function (exports, axios, sandbox) {
ret.style.objectFit = "fill";
return ret;
}
blend(props) {
this.placeHolderImage = props['placeHolderImage'];
this.placeHolderImageBase64 = props['placeHolderImageBase64'];
this.placeHolderColor = props['placeHolderColor'];
this.errorImage = props['errorImage'];
this.errorImageBase64 = props['errorImageBase64'];
this.errorColor = props['errorColor'];
super.blend(props);
}
blendProps(v, propName, prop) {
switch (propName) {
case 'imageUrl':
v.setAttribute('src', prop);
break;
case 'imageBase64':
v.setAttribute('src', prop);
this.loadIntoTarget(v, prop);
break;
case 'placeHolderImage':
case 'placeHolderImageBase64':
case 'placeHolderColor':
case 'errorImage':
case 'errorImageBase64':
case 'errorColor':
break;
case 'loadCallback':
v.onload = () => {
this.callJSResponse(prop, {
width: v.width,
height: v.height
});
};
this.onloadFuncId = prop;
break;
case 'scaleType':
switch (prop) {
@ -7280,6 +7288,65 @@ var doric_web = (function (exports, axios, sandbox) {
break;
}
}
loadIntoTarget(v, src) {
if (this.placeHolderImage) {
v.src = this.placeHolderImage;
}
else if (this.placeHolderImageBase64) {
v.src = this.placeHolderImageBase64;
}
else if (this.placeHolderColor) {
v.style.backgroundColor = toRGBAString(this.placeHolderColor);
}
v.onload = () => {
if (this.placeHolderColor) {
v.style.removeProperty('background-color');
}
if (this.onloadFuncId) {
this.callJSResponse(this.onloadFuncId, {
width: v.width,
height: v.height,
});
}
};
v.onerror = () => {
const error = this.getError(v.offsetWidth, v.offsetHeight);
if (!error)
return;
const same = src === error;
const srcLoadError = v.src === src;
if (same || !srcLoadError)
return;
v.src = error;
};
setTimeout(() => {
v.src = src;
});
}
getError(width, height) {
if (this.errorImage) {
return this.errorImage;
}
else if (this.errorImageBase64) {
return this.errorImageBase64;
}
else if (this.errorColor && this.view) {
return this.createColoredCanvas(width, height, this.errorColor);
}
return null;
}
createColoredCanvas(width, height, color) {
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const context = canvas.getContext('2d');
if (context) {
context.fillStyle = toRGBAString(color);
context.fillRect(0, 0, width, height);
return canvas.toDataURL('image/png');
}
return null;
}
}
class DoricScrollerNode extends DoricSuperNode {

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
import { DoricViewNode, LEFT, RIGHT, CENTER_X, CENTER_Y, TOP, BOTTOM, toPixelString } from "./DoricViewNode";
import { toRGBAString } from "../utils/color";
import { DoricViewNode, LEFT, RIGHT, CENTER_X, CENTER_Y, TOP, BOTTOM, toPixelString } from './DoricViewNode'
import { toRGBAString } from '../utils/color'
enum ScaleType {
ScaleToFill = 0,
@ -8,6 +8,13 @@ enum ScaleType {
}
export class DoricImageNode extends DoricViewNode {
onloadFuncId?: string
placeHolderImage?: string
placeHolderImageBase64?: string
placeHolderColor?: number
errorImage?: string
errorImageBase64?: string
errorColor?: number
build(): HTMLElement {
const ret = document.createElement('img')
@ -15,21 +22,31 @@ export class DoricImageNode extends DoricViewNode {
return ret
}
blend(props: { [index: string]: any }): void {
this.placeHolderImage = props['placeHolderImage']
this.placeHolderImageBase64 = props['placeHolderImageBase64']
this.placeHolderColor = props['placeHolderColor']
this.errorImage = props['errorImage']
this.errorImageBase64 = props['errorImageBase64']
this.errorColor = props['errorColor']
super.blend(props)
}
blendProps(v: HTMLImageElement, propName: string, prop: any) {
switch (propName) {
case 'imageUrl':
v.setAttribute('src', prop)
break
case 'imageBase64':
v.setAttribute('src', prop)
this.loadIntoTarget(v, prop)
break
case 'placeHolderImage':
case 'placeHolderImageBase64':
case 'placeHolderColor':
case 'errorImage':
case 'errorImageBase64':
case 'errorColor':
break
case 'loadCallback':
v.onload = () => {
this.callJSResponse(prop, {
width: v.width,
height: v.height
})
}
this.onloadFuncId = prop
break
case 'scaleType':
switch (prop) {
@ -57,4 +74,65 @@ export class DoricImageNode extends DoricViewNode {
}
}
private loadIntoTarget(v: HTMLImageElement, src: any) {
let placeHolderSrc = ''
if (this.placeHolderImage) {
placeHolderSrc = v.src = this.placeHolderImage
} else if (this.placeHolderImageBase64) {
placeHolderSrc = v.src = this.placeHolderImageBase64
} else if (this.placeHolderColor) {
v.style.backgroundColor = toRGBAString(this.placeHolderColor)
}
v.onload = () => {
if (this.placeHolderColor) {
v.style.removeProperty('background-color')
}
if (this.onloadFuncId) {
this.callJSResponse(this.onloadFuncId, {
width: v.width,
height: v.height,
})
}
}
v.onerror = () => {
const error = this.getError(v.offsetWidth, v.offsetHeight)
if (!error) return
const same = src === error
const srcLoadError = v.src === src
if (same || !srcLoadError) return
v.src = error
}
setTimeout(() => {
v.src = src
})
}
private getError(width: number, height: number) {
if (this.errorImage) {
return this.errorImage
} else if (this.errorImageBase64) {
return this.errorImageBase64
} else if (this.errorColor && this.view) {
return this.createColoredCanvas(
width, height,
this.errorColor
)
}
return null
}
private createColoredCanvas(width: number, height: number, color: number) {
const canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
const context = canvas.getContext('2d')
if (context) {
context.fillStyle = toRGBAString(color)
context.fillRect(0, 0, width, height)
return canvas.toDataURL('image/png')
}
return null
}
}