feat:web support image stretch

This commit is contained in:
wangxiangyuan 2023-09-07 10:53:05 +08:00 committed by osborn
parent 0ebabc7d0a
commit 0cf75592ae
3 changed files with 123 additions and 58 deletions

View File

@ -7346,10 +7346,11 @@ var doric_web = (function (exports, axios, sandbox) {
ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit"; ScaleType[ScaleType["ScaleAspectFit"] = 1] = "ScaleAspectFit";
ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill"; ScaleType[ScaleType["ScaleAspectFill"] = 2] = "ScaleAspectFill";
})(ScaleType || (ScaleType = {})); })(ScaleType || (ScaleType = {}));
const transparentBase64 = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==";
class DoricImageNode extends DoricViewNode { class DoricImageNode extends DoricViewNode {
build() { build() {
const ret = document.createElement('img'); const ret = document.createElement('img');
ret.style.objectFit = "fill"; ret.style.objectFit = 'fill';
return ret; return ret;
} }
blend(props) { blend(props) {
@ -7359,6 +7360,7 @@ var doric_web = (function (exports, axios, sandbox) {
this.errorImage = props['errorImage']; this.errorImage = props['errorImage'];
this.errorImageBase64 = props['errorImageBase64']; this.errorImageBase64 = props['errorImageBase64'];
this.errorColor = props['errorColor']; this.errorColor = props['errorColor'];
this.stretchInset = props['stretchInset'];
super.blend(props); super.blend(props);
} }
blendProps(v, propName, prop) { blendProps(v, propName, prop) {
@ -7382,6 +7384,8 @@ var doric_web = (function (exports, axios, sandbox) {
case 'errorImageBase64': case 'errorImageBase64':
case 'errorColor': case 'errorColor':
break; break;
case 'stretchInset':
break;
case 'loadCallback': case 'loadCallback':
this.onloadFuncId = prop; this.onloadFuncId = prop;
break; break;
@ -7411,8 +7415,52 @@ var doric_web = (function (exports, axios, sandbox) {
break; break;
} }
} }
loadIntoTarget(v, src) { loadIntoTarget(targetElement, src) {
v.style.removeProperty('background-color'); this.clearStretchElementAttributes(targetElement);
this.loadPlaceHolder(targetElement);
let tempLoadElement = this.stretchInset ? document.createElement('img') : targetElement;
tempLoadElement.onload = () => {
//remove placeHolderColor
targetElement.style.removeProperty('background-color');
if (tempLoadElement.src === src && this.onloadFuncId) {
this.callJSResponse(this.onloadFuncId, {
width: tempLoadElement.naturalWidth,
height: tempLoadElement.naturalHeight,
});
}
};
tempLoadElement.onerror = () => {
this.clearStretchElementAttributes(targetElement);
const error = this.getError(targetElement.offsetWidth, targetElement.offsetHeight);
if (!error)
return;
const same = src === error;
const srcLoadError = tempLoadElement.src.length === 0 || tempLoadElement.src === src;
if (same || !srcLoadError)
return;
targetElement.src = error;
if (this.onloadFuncId) {
this.callJSResponse(this.onloadFuncId);
}
};
Promise.resolve().then(e => {
tempLoadElement.src = src;
if (this.stretchInset) {
this.loadImageWithStretch(targetElement, src, this.stretchInset);
}
});
}
loadImageWithStretch(v, src, stretchInset) {
v.src = transparentBase64;
v.style.borderImageSource = `url(${src})`;
v.style.borderImageSlice = `${stretchInset.top} ${stretchInset.right} ${stretchInset.bottom} ${stretchInset.left} fill`;
const top = toPixelString(stretchInset.top);
const right = toPixelString(stretchInset.right);
const bottom = toPixelString(stretchInset.bottom);
const left = toPixelString(stretchInset.left);
v.style.borderImageWidth = `${top} ${right} ${bottom} ${left}`;
}
loadPlaceHolder(v) {
if (this.placeHolderImage) { if (this.placeHolderImage) {
v.src = this.placeHolderImage; v.src = this.placeHolderImage;
} }
@ -7422,32 +7470,12 @@ var doric_web = (function (exports, axios, sandbox) {
else if (this.placeHolderColor) { else if (this.placeHolderColor) {
v.style.backgroundColor = toRGBAString(this.placeHolderColor); v.style.backgroundColor = toRGBAString(this.placeHolderColor);
} }
v.onload = () => { }
v.style.removeProperty('background-color'); clearStretchElementAttributes(v) {
if (v.src === src && this.onloadFuncId) { v.style.removeProperty('background-color');
this.callJSResponse(this.onloadFuncId, { v.style.removeProperty('border-image-source');
width: v.naturalWidth, v.style.removeProperty('border-image-slice');
height: v.naturalHeight, v.style.removeProperty('border-image-width');
});
}
};
v.onerror = () => {
v.style.removeProperty('background-color');
const error = this.getError(v.offsetWidth, v.offsetHeight);
if (!error)
return;
const same = src === error;
const srcLoadError = v.src.length === 0 || v.src === src;
if (same || !srcLoadError)
return;
v.src = error;
if (this.onloadFuncId) {
this.callJSResponse(this.onloadFuncId);
}
};
Promise.resolve().then(e => {
v.src = src;
});
} }
getError(width, height) { getError(width, height) {
if (this.errorImage) { if (this.errorImage) {

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,13 @@ enum ScaleType {
ScaleAspectFit, ScaleAspectFit,
ScaleAspectFill, ScaleAspectFill,
} }
type StretchInset = {
left: number,
top: number,
right: number,
bottom: number
}
const transparentBase64 = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg=="
export class DoricImageNode extends DoricViewNode { export class DoricImageNode extends DoricViewNode {
onloadFuncId?: string onloadFuncId?: string
placeHolderImage?: string placeHolderImage?: string
@ -16,10 +22,11 @@ export class DoricImageNode extends DoricViewNode {
errorImage?: string errorImage?: string
errorImageBase64?: string errorImageBase64?: string
errorColor?: number errorColor?: number
stretchInset?: StretchInset
build(): HTMLElement { build(): HTMLElement {
const ret = document.createElement('img') const ret = document.createElement('img')
ret.style.objectFit = "fill" ret.style.objectFit = 'fill'
return ret return ret
} }
@ -30,6 +37,7 @@ export class DoricImageNode extends DoricViewNode {
this.errorImage = props['errorImage'] this.errorImage = props['errorImage']
this.errorImageBase64 = props['errorImageBase64'] this.errorImageBase64 = props['errorImageBase64']
this.errorColor = props['errorColor'] this.errorColor = props['errorColor']
this.stretchInset = props['stretchInset']
super.blend(props) super.blend(props)
} }
@ -53,6 +61,8 @@ export class DoricImageNode extends DoricViewNode {
case 'errorImageBase64': case 'errorImageBase64':
case 'errorColor': case 'errorColor':
break break
case 'stretchInset':
break
case 'loadCallback': case 'loadCallback':
this.onloadFuncId = prop this.onloadFuncId = prop
break break
@ -82,8 +92,52 @@ export class DoricImageNode extends DoricViewNode {
} }
} }
private loadIntoTarget(v: HTMLImageElement, src: any) { private loadIntoTarget(targetElement: HTMLImageElement, src: any) {
v.style.removeProperty('background-color') this.clearStretchElementAttributes(targetElement)
this.loadPlaceHolder(targetElement)
let tempLoadElement = this.stretchInset ? document.createElement('img') : targetElement
tempLoadElement.onload = () => {
//remove placeHolderColor
targetElement.style.removeProperty('background-color')
if (tempLoadElement.src === src && this.onloadFuncId) {
this.callJSResponse(this.onloadFuncId, {
width: tempLoadElement.naturalWidth,
height: tempLoadElement.naturalHeight,
})
}
}
tempLoadElement.onerror = () => {
this.clearStretchElementAttributes(targetElement)
const error = this.getError(targetElement.offsetWidth, targetElement.offsetHeight)
if (!error) return
const same = src === error
const srcLoadError = tempLoadElement.src.length === 0 || tempLoadElement.src === src
if (same || !srcLoadError) return
targetElement.src = error
if (this.onloadFuncId) {
this.callJSResponse(this.onloadFuncId)
}
}
Promise.resolve().then(e => {
tempLoadElement.src = src
if (this.stretchInset) {
this.loadImageWithStretch(targetElement, src, this.stretchInset)
}
})
}
private loadImageWithStretch(v: HTMLImageElement, src: any, stretchInset: StretchInset) {
v.src = transparentBase64
v.style.borderImageSource = `url(${src})`
v.style.borderImageSlice = `${stretchInset.top} ${stretchInset.right} ${stretchInset.bottom} ${stretchInset.left} fill`
const top = toPixelString(stretchInset.top)
const right = toPixelString(stretchInset.right)
const bottom = toPixelString(stretchInset.bottom)
const left = toPixelString(stretchInset.left)
v.style.borderImageWidth = `${top} ${right} ${bottom} ${left}`
}
private loadPlaceHolder(v: HTMLImageElement) {
if (this.placeHolderImage) { if (this.placeHolderImage) {
v.src = this.placeHolderImage v.src = this.placeHolderImage
} else if (this.placeHolderImageBase64) { } else if (this.placeHolderImageBase64) {
@ -91,30 +145,13 @@ export class DoricImageNode extends DoricViewNode {
} else if (this.placeHolderColor) { } else if (this.placeHolderColor) {
v.style.backgroundColor = toRGBAString(this.placeHolderColor) v.style.backgroundColor = toRGBAString(this.placeHolderColor)
} }
v.onload = () => { }
v.style.removeProperty('background-color')
if (v.src === src && this.onloadFuncId) { private clearStretchElementAttributes(v: HTMLImageElement) {
this.callJSResponse(this.onloadFuncId, { v.style.removeProperty('background-color')
width: v.naturalWidth, v.style.removeProperty('border-image-source')
height: v.naturalHeight, v.style.removeProperty('border-image-slice')
}) v.style.removeProperty('border-image-width')
}
}
v.onerror = () => {
v.style.removeProperty('background-color')
const error = this.getError(v.offsetWidth, v.offsetHeight)
if (!error) return
const same = src === error
const srcLoadError = v.src.length === 0 || v.src === src
if (same || !srcLoadError) return
v.src = error
if (this.onloadFuncId) {
this.callJSResponse(this.onloadFuncId)
}
}
Promise.resolve().then(e => {
v.src = src
})
} }
private getError(width: number, height: number) { private getError(width: number, height: number) {