fix:web stretching insets when original image exceeds img dimensions

This commit is contained in:
wangxiangyuan 2023-09-19 18:35:46 +08:00 committed by osborn
parent 067cd28bfb
commit 2029fc26c0
4 changed files with 78 additions and 11 deletions

View File

@ -7441,6 +7441,15 @@ var doric_web = (function (exports, axios, sandbox) {
this.loadPlaceHolder(targetElement);
let tempLoadElement = this.stretchInset ? document.createElement('img') : targetElement;
tempLoadElement.onload = () => {
if (this.stretchInset) {
if (!this.resizeObserver) {
this.resizeObserver = new ResizeObserver(entry => {
this.onResize.call(this, { width: tempLoadElement.naturalWidth, height: tempLoadElement.naturalHeight });
});
this.resizeObserver.observe(targetElement);
}
this.onResize({ width: tempLoadElement.naturalWidth, height: tempLoadElement.naturalHeight });
}
//remove placeHolderColor
targetElement.style.removeProperty('background-color');
if (tempLoadElement.src === src && this.onloadFuncId) {
@ -7475,11 +7484,16 @@ var doric_web = (function (exports, axios, sandbox) {
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}`;
}
calculateStretchBorderWidth(originalSize, targetSize, stretchInset) {
const widthRatio = targetSize.width / originalSize.width;
const heightRatio = targetSize.height / originalSize.height;
const scaleFactor = Math.min(widthRatio, heightRatio);
const scaledStretchInset = {};
for (const key in stretchInset) {
scaledStretchInset[key] = Math.round(stretchInset[key] * scaleFactor);
}
return scaledStretchInset;
}
loadPlaceHolder(v) {
if (this.placeHolderImage) {
@ -7522,6 +7536,19 @@ var doric_web = (function (exports, axios, sandbox) {
}
return null;
}
onResize(originalSize) {
if (!this.stretchInset) {
return;
}
if (this.view.offsetWidth !== 0 || this.view.offsetHeight !== 0) {
const scaledStretchInset = this.calculateStretchBorderWidth({ width: originalSize.width, height: originalSize.height }, { width: this.view.offsetWidth, height: this.view.offsetHeight }, this.stretchInset);
const top = toPixelString(scaledStretchInset.top);
const right = toPixelString(scaledStretchInset.right);
const bottom = toPixelString(scaledStretchInset.bottom);
const left = toPixelString(scaledStretchInset.left);
this.view.style.borderImageWidth = `${top} ${right} ${bottom} ${left}`;
}
}
}
class DoricScrollerNode extends DoricSuperNode {

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
import { DoricViewNode, LEFT, RIGHT, CENTER_X, CENTER_Y, TOP, BOTTOM, toPixelString } from './DoricViewNode'
import { toRGBAString } from '../utils/color'
import { resourceManager } from '../DoricRegistry'
import Size from '../utils/Size'
enum ScaleType {
ScaleToFill = 0,
@ -8,6 +9,7 @@ enum ScaleType {
ScaleAspectFill,
}
type StretchInset = {
[key: string]: number;
left: number,
top: number,
right: number,
@ -23,6 +25,7 @@ export class DoricImageNode extends DoricViewNode {
errorImageBase64?: string
errorColor?: number
stretchInset?: StretchInset
resizeObserver?: ResizeObserver | null
build(): HTMLElement {
const ret = document.createElement('img')
@ -97,6 +100,15 @@ export class DoricImageNode extends DoricViewNode {
this.loadPlaceHolder(targetElement)
let tempLoadElement = this.stretchInset ? document.createElement('img') : targetElement
tempLoadElement.onload = () => {
if (this.stretchInset) {
if (!this.resizeObserver) {
this.resizeObserver = new ResizeObserver(entry => {
this.onResize.call(this, { width: tempLoadElement.naturalWidth, height: tempLoadElement.naturalHeight })
})
this.resizeObserver.observe(targetElement)
}
this.onResize({ width: tempLoadElement.naturalWidth, height: tempLoadElement.naturalHeight })
}
//remove placeHolderColor
targetElement.style.removeProperty('background-color')
if (tempLoadElement.src === src && this.onloadFuncId) {
@ -130,11 +142,18 @@ export class DoricImageNode extends DoricViewNode {
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 calculateStretchBorderWidth(originalSize: Size, targetSize: Size, stretchInset: StretchInset) {
const widthRatio = targetSize.width / originalSize.width
const heightRatio = targetSize.height / originalSize.height
const scaleFactor = Math.min(widthRatio, heightRatio)
const scaledStretchInset: { [key: string]: number; } = {}
for (const key in stretchInset) {
scaledStretchInset[key] = Math.round(stretchInset[key] * scaleFactor)
}
return scaledStretchInset
}
private loadPlaceHolder(v: HTMLImageElement) {
@ -182,4 +201,21 @@ export class DoricImageNode extends DoricViewNode {
return null
}
private onResize(originalSize: Size) {
if (!this.stretchInset) {
return
}
if (this.view.offsetWidth !== 0 || this.view.offsetHeight !== 0) {
const scaledStretchInset = this.calculateStretchBorderWidth(
{ width: originalSize.width, height: originalSize.height },
{ width: this.view.offsetWidth, height: this.view.offsetHeight },
this.stretchInset)
const top = toPixelString(scaledStretchInset.top)
const right = toPixelString(scaledStretchInset.right)
const bottom = toPixelString(scaledStretchInset.bottom)
const left = toPixelString(scaledStretchInset.left)
this.view.style.borderImageWidth = `${top} ${right} ${bottom} ${left}`
}
}
}

View File

@ -0,0 +1,4 @@
export default interface Size {
width: number;
height: number;
}