diff --git a/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets b/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets index 2f935dd..936f8cb 100644 --- a/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets +++ b/imageknife/src/main/ets/components/imageknife/ImageKnifeComponent.ets @@ -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