1.重构回调后的流程:为了保证所有绘制都是在Canvas的onReady之后,目前的策略是生命周期的回调方法,如果onReady没触发就绑定到自定义组件的onReadyNext方法上,等待onReady触发之后调用。

Signed-off-by: zhoulisheng1 <zhoulisheng1@huawei.com>
This commit is contained in:
zhoulisheng1 2022-12-06 23:12:38 -08:00
parent 40af0d2285
commit 01eea2d9c2
1 changed files with 76 additions and 99 deletions

View File

@ -82,6 +82,8 @@ export struct ImageKnifeComponent {
}
private canvasHasReady:boolean = false;
private firstDrawFlag:boolean = false;
private onReadyNext:Function = undefined
build() {
Canvas(this.context)
.width('100%')
@ -92,9 +94,10 @@ export struct ImageKnifeComponent {
if(this.currentWidth <=0 || this.currentHeight <=0 ){
// 存在宽或者高为0,此次重回无意义,无需进行request请求
}else{
if(this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth){
// 宽高发生了变化
console.log('onAreaChange isValid Canvas currentWidth =' + this.currentWidth + ' currentHeight=' + this.currentHeight)
// 前提:宽高值均有效,值>0. 条件1当前宽高与上一次宽高不同 条件2:当前是第一次绘制
if( (this.currentHeight != this.lastHeight || this.currentWidth != this.lastWidth) || this.firstDrawFlag){
this.firstDrawFlag = false;
console.log('ImageKnifeComponent onAreaChange isValid Canvas currentWidth =' + this.currentWidth + ' currentHeight=' + this.currentHeight)
this.lastWidth = this.currentWidth
this.lastHeight = this.currentHeight
this.imageKnifeExecute()
@ -103,6 +106,11 @@ export struct ImageKnifeComponent {
})
.onReady(() => {
this.canvasHasReady = true;
if(this.onReadyNext){
console.log('ImageKnifeComponent onReadyNext is running!')
this.onReadyNext()
this.onReadyNext = undefined;
}
})
.onClick((event:ClickEvent) => {
// 需要将点击事件回传
@ -116,72 +124,60 @@ export struct ImageKnifeComponent {
}
watchImageKnifeOption() {
console.log('watchImageKnifeOption is happened!')
// if (this.imageKnifeOption.sizeAnimate) {
// animateTo(this.imageKnifeOption.sizeAnimate, () => {
// this.resetGifData();
// this.whetherWaitSize();
// })
// } else {
this.resetGifData();
console.log('ImageKnifeComponent watchImageKnifeOption is happened!')
this.whetherWaitSize();
// }
}
whetherWaitSize() {
/**
* 判断当前是否由宽高,有直接重绘,没有则等待onAreaChange回调,当出现aboutToAppear第一次绘制的时候
* 给firstDrawFlag置为true,保证size即使没有变化也要进入 请求绘制流程
* @param drawFirst 是否是aboutToAppear第一次绘制
*/
whetherWaitSize(drawFirst?:boolean) {
if(this.currentHeight <= 0 || this.currentWidth <= 0){
// 宽或者高没有高度,需要等待canvas组件初始化完成
if(drawFirst){
this.firstDrawFlag = true;
}
}else{
console.log('whetherWaitSize 宽高有效 直接发送请求')
console.log('ImageKnifeComponent whetherWaitSize 宽高有效 直接发送请求')
this.imageKnifeExecute()
}
// this.componentWidth = this.imageKnifeOption.size.width
// this.componentHeight = this.imageKnifeOption.size.height
// if (this.newSizeEqualPreSize(this.imageKnifeOption.size)) {
// console.log('whetherWaitSize 宽高不变 直接发送请求')
// this.imageKnifeExecute()
// } else {
// this.onAreaCount++;
// // waitSize changed
// this.preSize = this.imageKnifeOption.size
// console.log('whetherWaitSize 宽高改变 等待组件回调onAreaChange后发送请求')
// }
}
// newSizeEqualPreSize(newSize: {
// width: string,
// height: string
// }): boolean {
// if (this.preSize.width == newSize.width && this.preSize.height == newSize.height) {
// return true;
// }
// return false;
// }
retryClick() {
this.hasDisplayRetryholder = false;
this.imageKnifeExecute();
}
aboutToAppear() {
console.log('imageKnifeComponent aboutToAppear happened!')
/**
* 为了保证执行方法在canvas的onReay之后
* 如果onReady未初始化,则将最新的绘制生命周期绑定到onReadNext上
* 待onReady执行的时候执行
* @param nextFunction 下一个方法
*/
runNextFunction(nextFunction:Function){
if(!this.canvasHasReady){
// canvas未初始化完成
this.onReadyNext = nextFunction;
}else{
nextFunction();
}
}
configNecessary(request: RequestOption) {
request.load(this.imageKnifeOption.loadSrc)
.addListener((err, data) => {
console.log('request.load callback')
this.displayMainSource(data)
console.log('ImageKnifeComponent request.load callback')
this.runNextFunction(this.displayMainSource.bind(this,data));
return false;
})
// if (this.imageKnifeOption.size) {
let realSize = {
width: this.currentWidth,
height: this.currentHeight
}
request.setImageViewSize(realSize)
// }
}
configCacheStrategy(request: RequestOption) {
@ -204,22 +200,21 @@ export struct ImageKnifeComponent {
configDisplay(request: RequestOption) {
if (this.imageKnifeOption.placeholderSrc) {
request.placeholder(this.imageKnifeOption.placeholderSrc, (data) => {
console.log('request.placeholder callback')
this.displayPlaceholder(data)
console.log('ImageKnifeComponent request.placeholder callback')
this.runNextFunction(this.displayPlaceholder.bind(this,data))
})
}
if (this.imageKnifeOption.thumbSizeMultiplier) {
request.thumbnail(this.imageKnifeOption.thumbSizeMultiplier, (data) => {
console.log('request.thumbnail callback')
this.displayThumbSizeMultiplier(data)
console.log('ImageKnifeComponent request.thumbnail callback')
this.runNextFunction(this.displayThumbSizeMultiplier.bind(this,data))
}, this.imageKnifeOption.thumbSizeDelay)
}
if (this.imageKnifeOption.errorholderSrc) {
request.errorholder(this.imageKnifeOption.errorholderSrc, (data) => {
console.log('request.errorholder callback')
this.displayErrorholder(data)
console.log('ImageKnifeComponent request.errorholder callback')
this.runNextFunction(this.displayErrorholder.bind(this, data))
})
}
@ -240,21 +235,22 @@ export struct ImageKnifeComponent {
if (this.imageKnifeOption.displayProgress) {
request.addProgressListener((percentValue: number) => {
// 如果进度条百分比 未展示大小,展示其动画
this.displayProgress(percentValue)
console.log('ImageKnifeComponent request.addProgressListener callback')
this.runNextFunction(this.displayProgress.bind(this,percentValue))
})
}
if (this.imageKnifeOption.retryholderSrc) {
request.retryholder(this.imageKnifeOption.retryholderSrc, (data) => {
console.log("RetryListener callback!")
console.log('ImageKnifeComponent request.retryholder callback')
this.hasDisplayRetryholder = true
this.displayRetryholder(data)
this.runNextFunction(this.displayRetryholder.bind(this,data))
})
}
}
// imageknife 第一次启动和数据刷新后重新发送请求
imageKnifeExecute() {
this.resetGifData()
let request = new RequestOption();
this.configNecessary(request);
this.configCacheStrategy(request);
@ -263,10 +259,6 @@ export struct ImageKnifeComponent {
}
displayPlaceholder(data: ImageKnifeData) {
if(!this.canvasHasReady){
console.log('Canvas is not Initialized! displayPlaceholder is Failed!')
return;
}
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayPlaceholder', this.context, data, this.imageKnifeOption,
this.currentWidth, this.currentHeight, (gifTimeId) => {
this.setGifTimeId(gifTimeId)
@ -285,10 +277,6 @@ export struct ImageKnifeComponent {
}
displayProgress(percent: number) {
if(!this.canvasHasReady){
console.log('Canvas is not Initialized! displayProgress is Failed!')
return;
}
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayProgress', this.context, percent, this.imageKnifeOption,
this.currentWidth, this.currentHeight, (gifTimeId) => {
this.setGifTimeId(gifTimeId)
@ -307,10 +295,6 @@ export struct ImageKnifeComponent {
}
displayThumbSizeMultiplier(data: ImageKnifeData) {
if(!this.canvasHasReady){
console.log('Canvas is not Initialized! displayThumbSizeMultiplier is Failed!')
return;
}
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayThumbSizeMultiplier', this.context, data, this.imageKnifeOption,
this.currentWidth, this.currentHeight, (gifTimeId) => {
this.setGifTimeId(gifTimeId)
@ -329,10 +313,6 @@ export struct ImageKnifeComponent {
}
displayMainSource(data: ImageKnifeData) {
if(!this.canvasHasReady){
console.log('Canvas is not Initialized! displayMainSource is Failed!')
return;
}
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayMainSource', this.context, data, this.imageKnifeOption,
this.currentWidth, this.currentHeight, (gifTimeId) => {
this.setGifTimeId(gifTimeId)
@ -351,11 +331,6 @@ export struct ImageKnifeComponent {
}
displayRetryholder(data: ImageKnifeData) {
if(!this.canvasHasReady){
console.log('Canvas is not Initialized! displayRetryholder is Failed!')
return;
}
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayRetryholder', this.context, data, this.imageKnifeOption,
this.currentWidth, this.currentHeight, (gifTimeId) => {
this.setGifTimeId(gifTimeId)
@ -373,10 +348,6 @@ export struct ImageKnifeComponent {
}
displayErrorholder(data: ImageKnifeData) {
if(!this.canvasHasReady){
console.log('Canvas is not Initialized! displayErrorholder is Failed!')
return;
}
if (!this.drawLifeCycleHasConsumed(this.imageKnifeOption.drawLifeCycle, 'displayErrorholder', this.context, data, this.imageKnifeOption,
this.currentWidth, this.currentHeight, (gifTimeId) => {
this.setGifTimeId(gifTimeId)
@ -395,16 +366,16 @@ export struct ImageKnifeComponent {
}
drawPlaceholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
console.log('default drawPlaceholder start!')
console.log('ImageKnifeComponent default drawPlaceholder start!')
// @ts-ignore
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
console.log('imageinfo widht =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
console.log('ImageKnifeComponent imageinfo widht =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
let scaleType = (typeof imageKnifeOption.placeholderScaleType == 'number') ? imageKnifeOption.placeholderScaleType : ScaleType.FIT_CENTER
context.save();
context.clearRect(0, 0, compWidth, compHeight)
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
context.restore();
console.log('default drawPlaceholder end!')
console.log('ImageKnifeComponent default drawPlaceholder end!')
})
}
@ -450,65 +421,62 @@ export struct ImageKnifeComponent {
}
drawThumbSizeMultiplier(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
console.log('default drawThumbSizeMultiplier start!')
console.log('ImageKnifeComponent default drawThumbSizeMultiplier start!')
// @ts-ignore
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
console.log('imageinfo widht =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
console.log('ImageKnifeComponent imageinfo widht =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
let scaleType = (typeof imageKnifeOption.thumbSizeMultiplierScaleType == 'number') ? imageKnifeOption.thumbSizeMultiplierScaleType : ScaleType.FIT_CENTER
context.save();
context.clearRect(0, 0, compWidth, compHeight)
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
context.restore();
console.log('default drawThumbSizeMultiplier end!')
console.log('ImageKnifeComponent default drawThumbSizeMultiplier end!')
})
}
drawMainSource(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
console.log('default drawMainSource start!')
console.log('ImageKnifeComponent default drawMainSource start!')
if (data.isPixelMap()) {
// @ts-ignore
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
let scaleType = (typeof imageKnifeOption.mainScaleType == 'number') ? imageKnifeOption.mainScaleType : ScaleType.FIT_CENTER
console.log('imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType)
console.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height + 'scaleType=' + scaleType)
context.save();
context.clearRect(0, 0, compWidth, compHeight)
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
context.restore();
console.log('default drawMainSource end!')
console.log('ImageKnifeComponent default drawMainSource end!')
})
} else if (data.isGIFFrame()) {
// GIF的数据返回在canvas onReady 之前 导致第一帧绘制不出来
setTimeout(()=>{
this.drawGIFFrame(context, data, imageKnifeOption, compWidth, compHeight, setGifTimeId)
},10)
}
}
drawRetryholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
console.log('default drawRetryholder start!')
console.log('ImageKnifeComponent default drawRetryholder start!')
// @ts-ignore
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
console.log('imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
console.log('ImageKnifeComponent imageinfo width =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
let scaleType = (typeof imageKnifeOption.retryholderScaleType == 'number') ? imageKnifeOption.retryholderScaleType : ScaleType.FIT_CENTER
context.save();
context.clearRect(0, 0, compWidth, compHeight)
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
context.restore();
console.log('default drawRetryholder end!')
console.log('ImageKnifeComponent default drawRetryholder end!')
})
}
drawErrorholder(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
console.log('default drawErrorholder start!')
console.log('ImageKnifeComponent default drawErrorholder start!')
// @ts-ignore
data.drawPixelMap.imagePixelMap.getImageInfo().then((imageInfo) => {
console.log('imageinfo widht =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
console.log('ImageKnifeComponent imageinfo widht =' + imageInfo.size.width + ' height=' + imageInfo.size.height)
let scaleType = (typeof imageKnifeOption.errorholderSrcScaleType == 'number') ? imageKnifeOption.errorholderSrcScaleType : ScaleType.FIT_CENTER
context.save();
context.clearRect(0, 0, compWidth, compHeight)
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, data.drawPixelMap.imagePixelMap, px2vp(imageInfo.size.width), px2vp(imageInfo.size.height), compWidth, compHeight, 0, 0)
context.restore();
console.log('default drawErrorholder end!')
console.log('ImageKnifeComponent default drawErrorholder end!')
})
}
@ -554,7 +522,14 @@ export struct ImageKnifeComponent {
}
}
aboutToAppear() {
console.log('ImageKnifeComponent aboutToAppear happened!')
this.canvasHasReady = false;
this.whetherWaitSize(true);
}
aboutToDisappear() {
console.log('ImageKnifeComponent aboutToDisappear happened!')
this.resetGifData();
}
@ -582,7 +557,7 @@ export struct ImageKnifeComponent {
private drawGIFFrame(context: CanvasRenderingContext2D, data: ImageKnifeData, imageKnifeOption: ImageKnifeOption, compWidth: number, compHeight: number, setGifTimeId?: (timeId: number) => void) {
let frames = data.drawGIFFrame.imageGIFFrames as GIFFrame[]
console.log('gifFrameLength =' + frames.length);
console.log('ImageKnifeComponent gifFrameLength =' + frames.length);
if (imageKnifeOption.gif && (typeof (imageKnifeOption.gif.seekTo) == 'number') && imageKnifeOption.gif.seekTo >= 0) {
this.autoPlay = false;
context.clearRect(0, 0, compWidth, compHeight)
@ -611,7 +586,7 @@ export struct ImageKnifeComponent {
}
private renderFrames(frames: GIFFrame[], index: number, context: CanvasRenderingContext2D, compWidth: number, compHeight: number) {
console.log('renderFrames frames length =' + frames.length)
console.log('ImageKnifeComponent renderFrames frames length =' + frames.length)
let start = new Date().getTime();
if (index === 0) {
// 如果是第一帧,我们只从开始渲染前记录时间
@ -672,7 +647,7 @@ export struct ImageKnifeComponent {
// 具体绘制过程
private canvasDrawPixelMap(frames: GIFFrame[], index: number, context: CanvasRenderingContext2D, compWidth: number, compHeight: number) {
console.log('canvasDrawPixelMap index=' + index)
console.log('ImageKnifeComponent canvasDrawPixelMap index=' + index)
let frame = frames[index];
let pixelmap = frame['drawPixelMap']
let disposal = 0
@ -691,7 +666,7 @@ export struct ImageKnifeComponent {
ScaleTypeHelper.drawImageWithScaleType(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth, compHeight, px2vp(frame.dims.left), px2vp(frame.dims.top))
// tips:worker如果不是在展示页面中创建,使用子线程回来的数据创建的图片,会导致canvas绘制不出来
context.restore();
console.log('default drawMainSource end!')
console.log('ImageKnifeComponent default drawMainSource end!')
}
}
@ -728,6 +703,8 @@ export enum ScaleType {
NONE = 8
}
export class ScaleTypeHelper {
static drawImageWithScaleType(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | ImageBitmap, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX: number, imageOffsetY: number) {
let scaleW = compWidth / imageWidth