From 3550ce7313c61f0b0f6b84716813b6899572633f Mon Sep 17 00:00:00 2001 From: parkerli Date: Fri, 16 Aug 2024 16:33:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=AE=80=E5=8D=95=E7=9A=84=E7=AB=A0?= =?UTF-8?q?=E8=8A=82=E7=BC=93=E5=AD=98=E4=B8=8E=E7=AB=A0=E8=8A=82=E9=97=B4?= =?UTF-8?q?=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ets/pages/view/Reader/ReaderPage2.ets | 8 +- .../ets/common/entity/ReaderChaptersItem.ets | 6 +- .../helper/NovelChapterOperateHelper.ets | 41 ++ .../src/main/ets/provider/configProvider.ets | 107 +++- .../src/main/ets/view/CoverFlipView.ets | 49 +- readerLibrary/src/main/ets/view/Reader.ets | 50 +- .../src/main/ets/view/SimulateCurlView.ets | 498 ++---------------- 7 files changed, 234 insertions(+), 525 deletions(-) create mode 100644 readerLibrary/src/main/ets/common/helper/NovelChapterOperateHelper.ets diff --git a/entry/src/main/ets/pages/view/Reader/ReaderPage2.ets b/entry/src/main/ets/pages/view/Reader/ReaderPage2.ets index 278a1972..4ca09573 100644 --- a/entry/src/main/ets/pages/view/Reader/ReaderPage2.ets +++ b/entry/src/main/ets/pages/view/Reader/ReaderPage2.ets @@ -45,12 +45,12 @@ struct ReaderPage2 { }) //txt小说 if (this.chapterList.length != 0) { - this.chapterList[0].chapterList = this.chapterList[0].content.split('\n').map((value) => value + '\n'); + this.chapterList[0].paragraphList = this.chapterList[0].content.split('\n').map((value) => value + '\n'); } if (this.chapterList.length >= 2) { for (let index = 1; index < this.chapterList.length; index++) { - this.chapterList[index].chapterList = this.chapterList[index].content.split('\n').map((value) => value + '\n'); + this.chapterList[index].paragraphList = this.chapterList[index].content.split('\n').map((value) => value + '\n'); } } this.currentChapters = temp.clickBookChapter @@ -498,8 +498,8 @@ struct ReaderPageContent { } if (this.turnStyle === FlipPageType.SIMULATE_FLIP_PAGE) { SimulateCurlView({ - currentChapterNum: this.currentChapterIndex, - currentPageNum: this.currentPageIndex, + currentChapterIndex: this.currentChapterIndex, + currentPageIndex: this.currentPageIndex, }) } if (this.turnStyle === FlipPageType.SLIDE_FLIP_PAGE) { diff --git a/readerLibrary/src/main/ets/common/entity/ReaderChaptersItem.ets b/readerLibrary/src/main/ets/common/entity/ReaderChaptersItem.ets index 02a66ae5..495de77e 100644 --- a/readerLibrary/src/main/ets/common/entity/ReaderChaptersItem.ets +++ b/readerLibrary/src/main/ets/common/entity/ReaderChaptersItem.ets @@ -3,16 +3,16 @@ export class ReaderChapterItem { content: string chapterTitleNumber: string title: string - chapterList: string[] + paragraphList: string[] chapterPageList: ReaderChapterPageItem[] - constructor(number: number, title = '', chapterTitleNumber = '', content = '', chapterList = [], + constructor(number: number, title = '', chapterTitleNumber = '', content = '', paragraphList = [], chapterPageList = []) { this.number = number this.content = content this.chapterTitleNumber = chapterTitleNumber this.title = title - this.chapterList = chapterList + this.paragraphList = paragraphList this.chapterPageList = chapterPageList } } diff --git a/readerLibrary/src/main/ets/common/helper/NovelChapterOperateHelper.ets b/readerLibrary/src/main/ets/common/helper/NovelChapterOperateHelper.ets new file mode 100644 index 00000000..a3b90dd7 --- /dev/null +++ b/readerLibrary/src/main/ets/common/helper/NovelChapterOperateHelper.ets @@ -0,0 +1,41 @@ +import { ReaderChapterItem } from '../entity/ReaderChaptersItem'; + +export class NovelChapterOperateHelper { + static nextPageIndex(chapterList: ReaderChapterItem[], chapterIndex: number, pageIndex: number): number[] | null { + if (chapterIndex >= chapterList.length - 1) { + if (pageIndex >= chapterList[chapterIndex].chapterPageList.length - 1) { + return null; + } else { + return [chapterIndex, pageIndex + 1]; + } + } else { + if (pageIndex >= chapterList[chapterIndex].chapterPageList.length - 1) { + if (chapterList[chapterIndex+1].chapterPageList.length === 0) { + return null; + } + return [chapterIndex + 1, 0]; + } else { + return [chapterIndex, pageIndex + 1]; + } + } + } + + static prePageIndex(chapterList: ReaderChapterItem[], chapterIndex: number, pageIndex: number): number[] | null { + if (chapterIndex <= 0) { + if (pageIndex <= 0) { + return null; + } else { + return [chapterIndex, pageIndex - 1]; + } + } else { + if (pageIndex <= 0) { + if (chapterList[chapterIndex-1].chapterPageList.length === 0) { + return null; + } + return [chapterIndex - 1, chapterList[chapterIndex-1].chapterPageList.length - 1]; + } else { + return [chapterIndex, pageIndex - 1]; + } + } + } +} \ No newline at end of file diff --git a/readerLibrary/src/main/ets/provider/configProvider.ets b/readerLibrary/src/main/ets/provider/configProvider.ets index 079c9a80..8afd87e7 100644 --- a/readerLibrary/src/main/ets/provider/configProvider.ets +++ b/readerLibrary/src/main/ets/provider/configProvider.ets @@ -2,6 +2,7 @@ import { BGColorType, BG_COLOR_ARRAY, Constants, FlipPageType } from '../common/ import { ReaderChapterItem, ReaderChapterPageItem } from '../common/entity/ReaderChaptersItem'; import { NovelContentParseHelper } from '../common/helper/NovelContentParseHelper'; import { display } from '@kit.ArkUI'; +import taskPool from '@ohos.taskpool'; @Component export struct ReaderProvider { @@ -31,18 +32,63 @@ export struct ReaderProvider { } } +@Concurrent +async function calChapterContent(width: number, height: number, targetParagraphList: string[], fontSize: number, + lineHeightRatio: number): Promise { + try { + return await NovelContentParseHelper.calculateChapterContent(targetParagraphList, + fontSize, + fontSize * lineHeightRatio, width, height) + } catch (e) { + console.info('loadNovel 出错 ' + e) + return []; + } + +} + @Component struct ReaderSourceProvider { @BuilderParam child: () => void // 通用组件 @Provide('chapterList') chapterList: ReaderChapterItem[] = []; - @Consume('lineHeightRatio') @Watch('onFontSizeChange') lineHeightRatio: number - @Consume('fontSize') @Watch('onFontSizeChange') fontSize: number - @Consume('displaySize') @Watch('calChapterContent') displaySize: number[] - @Consume('currentChapterIndex') currentChapterIndex: number - @Consume('paragraphSpacing') paragraphSpacing: number - - onFontSizeChange() { - this.calChapterContent() + @Consume('lineHeightRatio') @Watch('onConfigSizeChange') lineHeightRatio: number + @Consume('fontSize') @Watch('onConfigSizeChange') fontSize: number + @Consume('displaySize') @Watch('onDisplaySizeChange') displaySize: number[] + @Consume('currentChapterIndex') @Watch('calChapterContent') currentChapterIndex: number + @Consume('paragraphSpacing') @Watch('onConfigSizeChange') paragraphSpacing: number + + onConfigSizeChange() { + this.forceCalChapterContent() + } + + onDisplaySizeChange() { + this.forceCalChapterContent() + } + + private calContentOfTargetChapter(width: number, height: number, chapterIndex: number, fontSize: number, + lineHeightRatio: number, forceUpdate: boolean) { + if (!forceUpdate) { + if (this.chapterList[chapterIndex].chapterPageList.length !== 0) { + return + } + } + taskPool.execute(calChapterContent, width, height, this.chapterList[chapterIndex].paragraphList, fontSize, + lineHeightRatio).then((chapterList) => { + if (Array.isArray(chapterList)) { + let startIndex = 0 + let result: string[][] = chapterList as string[][] + if (result.length !== 0) { + this.chapterList[chapterIndex].chapterPageList = result.map((item) => { + let contentLength = item.reduce((accumulator, currentString) => { + return accumulator + currentString.length; + }, 0) + let result = new ReaderChapterPageItem(startIndex, startIndex + contentLength, item); + startIndex += contentLength; + return result + }) + this.chapterList = Array.from(this.chapterList) + } + } + }) } calChapterContent() { @@ -50,22 +96,35 @@ struct ReaderSourceProvider { let height = this.displaySize[1]; if (width !== 0 && height !== 0 && this.chapterList.length !== 0) { - NovelContentParseHelper.calculateChapterContent(this.chapterList[this.currentChapterIndex].chapterList, - this.fontSize, - this.fontSize * this.lineHeightRatio, width, height).then((chapterList) => { - let startIndex = 0 - this.chapterList[this.currentChapterIndex].chapterPageList = chapterList.map((item) => { - let contentLength = item.reduce((accumulator, currentString) => { - return accumulator + currentString.length; - }, 0) - let result = new ReaderChapterPageItem(startIndex, startIndex + contentLength, item); - startIndex += contentLength; - return result - }) - this.chapterList = Array.from(this.chapterList) - }).catch((reason: string) => { - console.log(reason); - }); + this.calContentOfTargetChapter(width, height, this.currentChapterIndex, + this.fontSize, this.lineHeightRatio, false); + if (this.currentChapterIndex > 0) { + this.calContentOfTargetChapter(width, height, this.currentChapterIndex - 1, + this.fontSize, this.lineHeightRatio, false); + } + if (this.currentChapterIndex < this.chapterList.length - 1) { + this.calContentOfTargetChapter(width, height, this.currentChapterIndex + 1, + this.fontSize, this.lineHeightRatio, false); + } + } + + } + + forceCalChapterContent() { + let width = this.displaySize[0]; + let height = this.displaySize[1]; + + if (width !== 0 && height !== 0 && this.chapterList.length !== 0) { + this.calContentOfTargetChapter(width, height, this.currentChapterIndex, + this.fontSize, this.lineHeightRatio, true); + if (this.currentChapterIndex > 0) { + this.calContentOfTargetChapter(width, height, this.currentChapterIndex - 1, + this.fontSize, this.lineHeightRatio, true); + } + if (this.currentChapterIndex < this.chapterList.length - 1) { + this.calContentOfTargetChapter(width, height, this.currentChapterIndex + 1, + this.fontSize, this.lineHeightRatio, true); + } } } diff --git a/readerLibrary/src/main/ets/view/CoverFlipView.ets b/readerLibrary/src/main/ets/view/CoverFlipView.ets index 6f9332ba..2bf4f00b 100644 --- a/readerLibrary/src/main/ets/view/CoverFlipView.ets +++ b/readerLibrary/src/main/ets/view/CoverFlipView.ets @@ -2,24 +2,39 @@ import { Constants } from '../common/constants/Constants'; import { Reader } from './Reader'; import { promptAction } from '@kit.ArkUI'; import { ReaderChapterItem } from '../common/entity/ReaderChaptersItem'; +import { NovelChapterOperateHelper } from '../common/helper/NovelChapterOperateHelper'; @Component export struct CoverFlipView { @State offsetX: number = 0 @Consume('screenW') screenW: number; @Link currentPageIndex: number; - @Consume('chapterList') chapterList: ReaderChapterItem[]; + @Consume('chapterList') @Watch('calPageIndex') chapterList: ReaderChapterItem[]; @Link currentChapterIndex: number; private isFirst: boolean = false; + @State nextPageIndex: number[] | null = null; + @State prePageIndex: number[] | null = null; + + aboutToAppear(): void { + this.calPageIndex(); + } + + calPageIndex() { + this.nextPageIndex = + NovelChapterOperateHelper.nextPageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + this.prePageIndex = + NovelChapterOperateHelper.prePageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + } + build() { Stack() { if (this.chapterList.length === 0 || this.chapterList[this.currentChapterIndex].chapterPageList.length === 0) { Reader({ content: '' }) } else { - if (this.currentPageIndex + 1 < this.chapterList[this.currentChapterIndex].chapterPageList.length) { + if (this.nextPageIndex !== null) { Reader({ - content: this.chapterList[this.currentChapterIndex].chapterPageList[this.currentPageIndex+1].content + content: this.chapterList[this.nextPageIndex[0]].chapterPageList[this.nextPageIndex[1]].content }) } @@ -27,9 +42,9 @@ export struct CoverFlipView { .translate({ x: this.offsetX >= 0 ? 0 : this.offsetX, y: 0, z: 0 }) .width(this.screenW) - if (this.currentPageIndex >= 1) { + if (this.prePageIndex != null) { Reader({ - content: this.chapterList[this.currentChapterIndex].chapterPageList[this.currentPageIndex-1].content + content: this.chapterList[this.prePageIndex[0]].chapterPageList[this.prePageIndex[1]].content }) .translate({ x: -this.screenW + this.offsetX @@ -40,13 +55,22 @@ export struct CoverFlipView { .gesture( PanGesture() .onActionUpdate((event?: GestureEvent) => { + let prePageIndex = + NovelChapterOperateHelper.prePageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + let nextPageIndex = + NovelChapterOperateHelper.nextPageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + if (!event) { return; } - if (this.currentPageIndex == 0 && event.offsetX > 0) { + if (prePageIndex === null && event.offsetX > 0) { this.isFirst = true; return; } + + if (nextPageIndex === null && event.offsetX < 0) { + return; + } this.offsetX = event.offsetX; }) .onActionEnd(() => { @@ -54,15 +78,14 @@ export struct CoverFlipView { duration: Constants.FLIP_DURATION, curve: Curve.EaseOut, onFinish: () => { + this.calPageIndex(); if (this.offsetX > 0) { - this.currentPageIndex -= 1; - // if (this.currentStartIndex !== 0) { - // this.currentStartIndex -= this.sumRow * this.rowWord; - // } + this.currentChapterIndex = (this.prePageIndex as number[])[0] + this.currentPageIndex = (this.prePageIndex as number[])[1] } if (this.offsetX < 0) { - this.currentPageIndex += 1; - // this.currentStartIndex += this.sumRow * this.rowWord; + this.currentChapterIndex = (this.nextPageIndex as number[])[0] + this.currentPageIndex = (this.nextPageIndex as number[])[1] } if (this.isFirst) { promptAction.showToast({ @@ -72,6 +95,7 @@ export struct CoverFlipView { this.isFirst = false; } this.offsetX = 0; + this.calPageIndex(); } }, () => { if (this.offsetX > 0) { @@ -80,6 +104,7 @@ export struct CoverFlipView { if (this.offsetX < 0) { this.offsetX = -this.screenW; } + this.calPageIndex(); }) }) ) diff --git a/readerLibrary/src/main/ets/view/Reader.ets b/readerLibrary/src/main/ets/view/Reader.ets index 6fb45a6f..0132639b 100644 --- a/readerLibrary/src/main/ets/view/Reader.ets +++ b/readerLibrary/src/main/ets/view/Reader.ets @@ -4,6 +4,7 @@ import { common2D, drawing } from '@kit.ArkGraphics2D'; import { ReaderChapterItem } from '../common/entity/ReaderChaptersItem'; import { componentSnapshot, MeasureText } from '@kit.ArkUI'; import { image } from '@kit.ImageKit'; +import { NovelChapterOperateHelper } from '../common/helper/NovelChapterOperateHelper'; @Component export struct Reader { @@ -32,10 +33,10 @@ export struct Reader { .layoutWeight(1) .onSizeChange((oldSize, newSize) => { if (typeof newSize.width === 'number' && typeof newSize.height === 'number') { - let width = newSize.width as number - let height = newSize.height as number + let width = vp2px(newSize.width as number) + let height = vp2px(newSize.height as number) if (this.displaySize[0] !== width || this.displaySize[1] !== height) { - this.displaySize = [vp2px(width), vp2px(height)]; + this.displaySize = [width, height]; } } console.info(`display size, width : ${vp2px(newSize.width as number)} , height : ${vp2px(newSize.height as number)}`) @@ -112,10 +113,10 @@ export struct ReaderForCurlView { .layoutWeight(1) .onSizeChange((oldSize, newSize) => { if (typeof newSize.width === 'number' && typeof newSize.height === 'number') { - let width = newSize.width as number - let height = newSize.height as number + let width = vp2px(newSize.width as number) + let height = vp2px(newSize.height as number) if (this.displaySize[0] !== width || this.displaySize[1] !== height) { - this.displaySize = [vp2px(width), vp2px(height)]; + this.displaySize = [width, height]; } } console.info(`display size, width : ${vp2px(newSize.width as number)} , height : ${vp2px(newSize.height as number)}`) @@ -205,8 +206,9 @@ export class SimulateDrawManager { this.canvasSize = size; } - updatePageIndex(index: number) { - this.currentPageIndex = index; + updatePageIndex(pageIndex: number, chapterIndex: number) { + this.currentPageIndex = pageIndex; + this.currentChapterIndex = chapterIndex; } updateChapterIndex(index: number) { @@ -275,25 +277,32 @@ export class SimulateDrawManager { this.isTurnNext = isTurnNextByHorizontal || isTurnNextByVertical + let nextPageIndex = + NovelChapterOperateHelper.nextPageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + let prePageIndex = + NovelChapterOperateHelper.prePageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + // todo: 这部分的限制逻辑不该放在这里,需要等到章节缓存处理模块做完再移走 if (this.isTurnNext && - this.currentPageIndex === this.chapterList[this.currentChapterIndex].chapterPageList.length - 1) { + nextPageIndex === null) { return null; } - if ((!this.isTurnNext) && this.currentPageIndex === 0) { + if ((!this.isTurnNext) && prePageIndex === null) { return null; } if (this.startTouch.y <= this.canvasSize.height / 3 || this.startTouch.y >= this.canvasSize.height / 3 * 2) { this.currentDrawHelper = new SimulationCornerTurnDrawHelper(this, this.context, this.fontSize, this.lineHeight, this.chapterList, - this.currentChapterIndex, this.isTurnNext ? this.currentPageIndex : this.currentPageIndex - 1, + this.isTurnNext ? this.currentChapterIndex : prePageIndex![0], + this.isTurnNext ? this.currentPageIndex : prePageIndex![1], this.bgColor); } else { this.currentDrawHelper = new SimulationPageTurnDrawHelper(this, this.context, this.fontSize, this.lineHeight, this.chapterList, - this.currentChapterIndex, - this.isTurnNext ? this.currentPageIndex : this.currentPageIndex - 1, this.bgColor); + this.isTurnNext ? this.currentChapterIndex : prePageIndex![0], + this.isTurnNext ? this.currentPageIndex : prePageIndex![1], + this.bgColor); } } @@ -495,9 +504,16 @@ abstract class SimulationDrawHelper { let currentY = startY; - // if(maskFilter!=null){ - // pen.setMaskFilter(maskFilter) + // let nextPageIndex = + // NovelChapterOperateHelper.nextPageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + // + // if (nextPageIndex == null) { + // return // } + // + // let currentPageLineList = + // this.chapterList[nextPageIndex[0]].chapterPageList[nextPageIndex[1]].lineContentList; + let currentPageLineList = this.chapterList[this.currentChapterIndex].chapterPageList[this.currentPageIndex+1].lineContentList; for (let index = 0; index < currentPageLineList.length; index++) { @@ -960,7 +976,7 @@ class SimulationPageTurnDrawHelper extends SimulationDrawHelper { if (canIUse('SystemCapability.Graphics.Drawing')) { let shadowWidth = (this.canvasSize.width - this.touch.dx) / 4 - if(shadowWidth<=0){ + if (shadowWidth <= 0) { return } let maskFilter = drawing.MaskFilter.createBlurMaskFilter(drawing.BlurType.NORMAL, shadowWidth / 2); @@ -985,7 +1001,7 @@ class SimulationPageTurnDrawHelper extends SimulationDrawHelper { let splitLineX = (this.canvasSize.width - this.touch.dx) / 2 + this.touch.dx; let shadowWidth = (Math.max(0, Math.min(this.canvasSize.width - splitLineX, splitLineX))) / 2 - if(shadowWidth<=0){ + if (shadowWidth <= 0) { return } let shadowMaskFilter = drawing.MaskFilter.createBlurMaskFilter(drawing.BlurType.NORMAL, shadowWidth) diff --git a/readerLibrary/src/main/ets/view/SimulateCurlView.ets b/readerLibrary/src/main/ets/view/SimulateCurlView.ets index 794e54b0..51a63041 100644 --- a/readerLibrary/src/main/ets/view/SimulateCurlView.ets +++ b/readerLibrary/src/main/ets/view/SimulateCurlView.ets @@ -4,6 +4,7 @@ import { Constants } from '../common/constants/Constants'; import { ReaderChapterItem } from '../common/entity/ReaderChaptersItem'; import { Reader, ReaderForCurlView, SimulateDrawManager } from './Reader'; import { image } from '@kit.ImageKit'; +import { NovelChapterOperateHelper } from '../common/helper/NovelChapterOperateHelper'; const NODE_CONTAINER_ID = 'root'; // 组件NodeContainer的id @@ -19,9 +20,9 @@ export struct SimulateCurlView { private lastTime: number | null = null private animatorResult: AnimatorResult | undefined | null @Consume('screenW') screenW: number; - @Link currentPageNum: number; + @Link currentPageIndex: number; @Consume('chapterList') chapterList: ReaderChapterItem[]; - @Link currentChapterNum: number; + @Link currentChapterIndex: number; @Consume('fontSize') fontSize: number; @Consume('lineHeightRatio') lineHeightRatio: number; @Consume('bgColor') bgColor: string; @@ -30,6 +31,15 @@ export struct SimulateCurlView { drawManager: SimulateDrawManager | null = null; isTurnNext: boolean | null = null; animationEndValue: number | null = null; + @State nextPageIndex: number[] | null = null; + @State prePageIndex: number[] | null = null; + + calPageIndex() { + this.nextPageIndex = + NovelChapterOperateHelper.nextPageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + this.prePageIndex = + NovelChapterOperateHelper.prePageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + } aboutToDisappear(): void { this.animatorResult = undefined; @@ -38,7 +48,8 @@ export struct SimulateCurlView { aboutToAppear(): void { this.drawManager = new SimulateDrawManager(this.context, this.fontSize, this.fontSize * this.lineHeightRatio, this.chapterList, - this.currentChapterNum, this.currentPageNum, this.bgColor); + this.currentChapterIndex, this.currentPageIndex, this.bgColor); + this.drawManager.setTextDisplaySize(this.displaySize) let options: AnimatorOptions = { duration: 300, easing: "linear", @@ -57,14 +68,26 @@ export struct SimulateCurlView { this.drawManager.dispatchPointerUPEvent(); } if (this.isTurnNext && this.animationEndValue === 1.0) { - this.currentPageNum++; - this.drawManager?.updatePageIndex(this.currentPageNum) + let nextPageIndex = + NovelChapterOperateHelper.nextPageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + if (nextPageIndex != null) { + this.currentChapterIndex = nextPageIndex![0]; + this.currentPageIndex = nextPageIndex![1]; + this.drawManager?.updatePageIndex(this.currentPageIndex, this.currentChapterIndex) + } + } else if (!this.isTurnNext && this.animationEndValue === -1.0) { - this.currentPageNum--; - this.drawManager?.updatePageIndex(this.currentPageNum) + let prePageIndex = + NovelChapterOperateHelper.prePageIndex(this.chapterList, this.currentChapterIndex, this.currentPageIndex); + if (prePageIndex != null) { + this.currentChapterIndex = prePageIndex![0]; + this.currentPageIndex = prePageIndex![1]; + this.drawManager?.updatePageIndex(this.currentPageIndex, this.currentChapterIndex) + } } this.isTurnNext = null; this.animationEndValue = null; + this.calPageIndex(); } this.animatorResult.onFrame = (progress) => { console.info(`animation: onFrame callback time is ${Date.now()} , progress : ${progress}}`) @@ -73,6 +96,7 @@ export struct SimulateCurlView { this.drawManager.draw() } }; + this.calPageIndex(); } setBatteryPixelMap() { @@ -109,7 +133,7 @@ export struct SimulateCurlView { Stack() { - if (this.chapterList[this.currentChapterNum].chapterPageList.length === 0) { + if (this.chapterList[this.currentChapterIndex].chapterPageList.length === 0) { Reader({ content: '' }) } else { Canvas(this.context) @@ -127,7 +151,7 @@ export struct SimulateCurlView { }) ReaderForCurlView({ - content: this.chapterList[this.currentChapterNum].chapterPageList[this.currentPageNum].content + content: this.chapterList[this.currentChapterIndex].chapterPageList[this.currentPageIndex].content }) .width(Constants.FULL_PERCENT) .height(Constants.FULL_PERCENT) @@ -188,459 +212,3 @@ export struct SimulateCurlView { ) } } - -// class SimulateDrawHelper { -// mTouch: Offset = Offset.zero(); -// currentSize: Size = Size.zero(); -// mBezierStart1 = Offset.zero(); // 贝塞尔曲线起始点 -// mBezierControl1 = Offset.zero(); // 贝塞尔曲线控制点 -// mBezierVertex1 = Offset.zero(); // 贝塞尔曲线顶点 -// mBezierEnd1 = Offset.zero(); // 贝塞尔曲线结束点 -// mBezierStart2 = Offset.zero(); // 另一条贝塞尔曲线 -// mBezierControl2 = Offset.zero(); -// mBezierVertex2 = Offset.zero(); -// mBezierEnd2 = Offset.zero(); -// mCornerX = 1; // 拖拽点对应的页脚 -// mCornerY = 1; -// mMiddleX = 0.0; -// mMiddleY = 0.0; -// mDegrees = 0.0; -// mTouchToCornerDis = 0.0; -// // Path mTopPagePath = Path(); -// mBottomPagePath = new drawing.Path(); -// mTopBackAreaPagePath = new drawing.Path(); -// // Path mShadowPath = Path(); -// -// isNeedCalCorner = true; -// isTurnNext = false; -// lastTouchPointOffset = Offset.zero(); -// preImage: image.PixelMap | null = null; -// -// // 计算贝塞尔曲线的各个关键点坐标 -// calBezierPoint() { -// this.mMiddleX = (this.mTouch.dx + this.mCornerX) / 2; -// this.mMiddleY = (this.mTouch.dy + this.mCornerY) / 2; -// -// this.mBezierControl1 = new Offset( -// this.mMiddleX - -// (this.mCornerY - this.mMiddleY) * -// (this.mCornerY - this.mMiddleY) / -// (this.mCornerX - this.mMiddleX), -// this.mCornerY); -// -// let f4 = this.mCornerY - this.mMiddleY; -// if (f4 === 0) { -// this.mBezierControl2 = new Offset(this.mCornerX, -// this.mMiddleY - (this.mCornerX - this.mMiddleX) * (this.mCornerX - this.mMiddleX) / 0.1); -// } else { -// this.mBezierControl2 = new Offset( -// this.mCornerX, -// this.mMiddleY - -// (this.mCornerX - this.mMiddleX) * -// (this.mCornerX - this.mMiddleX) / -// (this.mCornerY - this.mMiddleY)); -// } -// -// this.mBezierStart1 = new Offset( -// this.mBezierControl1.dx - (this.mCornerX - this.mBezierControl1.dx) / 2, -// this.mCornerY); -// -// // 当mBezierStart1.x < 0或者mBezierStart1.x > 480时 -// // 如果继续翻页,会出现BUG故在此限制 -// if (this.mTouch.dx > 0 && this.mTouch.dx < this.currentSize.width) { -// if (this.mBezierStart1.dx < 0 || this.mBezierStart1.dx > this.currentSize.width) { -// if (this.mBezierStart1.dx < 0) { -// this.mBezierStart1 = -// new Offset(this.currentSize.width - this.mBezierStart1.dx, this.mBezierStart1.dy); -// } -// -// let f1 = Math.abs(this.mCornerX - this.mTouch.dx); -// let f2 = this.currentSize.width * f1 / this.mBezierStart1.dx; -// this.mTouch = new Offset(Math.abs(this.mCornerX - f2), this.mTouch.dy); -// -// let f3 = -// Math.abs(this.mCornerX - this.mTouch.dx) * Math.floor(this.mCornerY - this.mTouch.dy) / f1; -// this.mTouch = new Offset(Math.abs(this.mCornerX - f2), Math.abs(this.mCornerY - f3)); -// -// this.mMiddleX = (this.mTouch.dx + this.mCornerX) / 2; -// this.mMiddleY = (this.mTouch.dy + this.mCornerY) / 2; -// -// this.mBezierControl1 = new Offset( -// this.mMiddleX - -// (this.mCornerY - this.mMiddleY) * -// (this.mCornerY - this.mMiddleY) / -// (this.mCornerX - this.mMiddleX), -// this.mCornerY); -// -// let f5 = this.mCornerY - this.mMiddleY; -// if (f5 === 0) { -// this.mBezierControl2 = new Offset(this.mCornerX, -// this.mMiddleY - (this.mCornerX - this.mMiddleX) * (this.mCornerX - this.mMiddleX) / 0.1); -// } else { -// this.mBezierControl2 = new Offset( -// this.mCornerX, -// this.mMiddleY - -// (this.mCornerX - this.mMiddleX) * -// (this.mCornerX - this.mMiddleX) / -// (this.mCornerY - this.mMiddleY)); -// } -// -// this.mBezierStart1 = new Offset( -// this.mBezierControl1.dx - (this.mCornerX - this.mBezierControl1.dx) / 2, -// this.mBezierStart1.dy); -// } -// } -// -// this.mBezierStart2 = new Offset(this.mCornerX, -// this.mBezierControl2.dy - (this.mCornerY - this.mBezierControl2.dy) / 2); -// -// this.mTouchToCornerDis = -// Math.sqrt(Math.pow((this.mTouch.dx - this.mCornerX), 2) + Math.pow((this.mTouch.dy - this.mCornerY), 2)); -// -// this.mBezierEnd1 = -// this.getCrossByPoint(this.mTouch, this.mBezierControl1, this.mBezierStart1, this.mBezierStart2); -// this.mBezierEnd2 = -// this.getCrossByPoint(this.mTouch, this.mBezierControl2, this.mBezierStart1, this.mBezierStart2); -// -// this.mBezierVertex1 = new Offset( -// (this.mBezierStart1.dx + 2 * this.mBezierControl1.dx + this.mBezierEnd1.dx) / 4, -// (2 * this.mBezierControl1.dy + this.mBezierStart1.dy + this.mBezierEnd1.dy) / 4); -// -// this.mBezierVertex2 = new Offset( -// (this.mBezierStart2.dx + 2 * this.mBezierControl2.dx + this.mBezierEnd2.dx) / 4, -// (2 * this.mBezierControl2.dy + this.mBezierStart2.dy + this.mBezierEnd2.dy) / 4); -// } -// -// // 获取交点(根据四点) // -// getCrossByPoint(p1: Offset, p2: Offset, p3: Offset, p4: Offset): Offset { -// let line1Info = this.getLineInfo(p1, p2); -// let line2Info = this.getLineInfo(p3, p4); -// -// return this.getCrossByLine( -// line1Info.dx, line1Info.dy, line2Info.dx, line2Info.dy); -// } -// -// // 根据两点获取直线的k、b; -// // return : dx = k,dy = b -// getLineInfo(p1: Offset, p2: Offset): Offset { -// let k1 = (p2.dy - p1.dy) / (p2.dx - p1.dx); -// let b1 = ((p1.dx * p2.dy) - (p2.dx * p1.dy)) / (p1.dx - p2.dx); -// return new Offset(k1, b1); -// } -// -// // 根据k和b -// getCrossByLine(k1: number, b1: number, k2: number, b2: number): Offset { -// return new Offset((b2 - b1) / (k1 - k2), k1 * ((b2 - b1) / (k1 - k2)) + b1); -// } -// -// calPath() { -// if (canIUse('SystemCapability.Graphics.Drawing')) { -// -// this.mBottomPagePath.reset(); -// this.mBottomPagePath.moveTo(this.mCornerX, this.mCornerY); -// this.mBottomPagePath.lineTo(this.mBezierStart1.dx, this.mBezierStart1.dy); -// this.mBottomPagePath.quadTo(this.mBezierControl1.x, this.mBezierControl1.y, this.mBezierEnd1.x, -// this.mBezierEnd1.y) -// -// this.mBottomPagePath.lineTo(this.mTouch.dx, this.mTouch.dy); -// this.mBottomPagePath.lineTo(this.mBezierEnd2.dx, this.mBezierEnd2.dy); -// this.mBottomPagePath.quadTo(this.mBezierControl2.x, this.mBezierControl2.y, this.mBezierStart2.x, -// this.mBezierStart2.y) -// -// this.mBottomPagePath.close(); -// -// // this.mTopBackAreaPagePath = new Path2D(); -// // this.mTopBackAreaPagePath.moveTo(this.mTouch.dx, this.mTouch.dy); -// // this.mTopBackAreaPagePath.lineTo(this.mBezierVertex1.dx, this.mBezierVertex1.dy); -// // this.mTopBackAreaPagePath.lineTo(this.mBezierVertex2.dx, this.mBezierVertex2.dy); -// // this.mTopBackAreaPagePath.closePath(); -// -// // if (this.mTopBackAreaPagePath..hasNaN || -// // this.mTopBackAreaPagePath.getBounds().isEmpty) { -// // return; -// // } -// -// // try { -// // this.mTopBackAreaPagePath = -// // this.mTopBackAreaPagePath = Path.combine( -// // PathOperation.intersect, mTopBackAreaPagePath, mBottomPagePath); -// // } on StateError { -// // print( -// // 'path combine failed , current backpackArea is ${mTopBackAreaPagePath.getBounds()} , current bottomArea is ${mBottomPagePath.getBounds()}'); -// // } -// } -// } -// -// dispatchPointerStart(pointerEvent: GestureEvent) { -// this.lastTouchPointOffset = -// new Offset(vp2px(pointerEvent.fingerList[0].localX), vp2px(pointerEvent.fingerList[0].localY)) -// -// this.mTouch = new Offset(vp2px(pointerEvent.fingerList[0].localX), vp2px(pointerEvent.fingerList[0].localY)) -// } -// -// dispatchPointerMoveEvent( -// pointerEvent: GestureEvent, canvasSize: Size, itemMainAxisDelta: number) { -// let touchPoint = new Offset( -// itemMainAxisDelta === 0 -// ? canvasSize.width -// : canvasSize.width + itemMainAxisDelta, -// vp2px(pointerEvent.fingerList[0].localY)); -// -// this.lastTouchPointOffset = -// new Offset(vp2px(pointerEvent.fingerList[0].localX), vp2px(pointerEvent.fingerList[0].localY)) -// -// if (this.isNeedCalCorner) { -// this.calcCornerXY(touchPoint.dy); -// this.isNeedCalCorner = false; -// this.isTurnNext = pointerEvent.velocityX <= 0; -// } -// -// this.mTouch = new Offset(vp2px(pointerEvent.fingerList[0].localX), vp2px(pointerEvent.fingerList[0].localY)) -// this.calBezierPoint(); -// } -// -// dispatchPointerUPEvent() { -// this.isNeedCalCorner = true; -// // this.mTouch = Offset.zero(); -// } -// -// /// 计算拖拽点对应的拖拽脚 /// -// calcCornerXY(y: number) { -// this.mCornerX = this.currentSize.width; -// if (y <= this.currentSize.height / 2) { -// this.mCornerY = 0; -// } else { -// this.mCornerY = this.currentSize.height; -// } -// } -// -// applyAnimation(process: number) { -// -// let isRecover = process <= 0 -// this.mTouch = -// new Offset(Math.min(this.lastTouchPointOffset.x + -// ((isRecover ? this.mCornerX : -this.mCornerX) - this.lastTouchPointOffset.x) * Math.abs(process), -// this.mCornerX), -// this.lastTouchPointOffset.y + this.mCornerY - this.lastTouchPointOffset.y * Math.abs(process)) -// -// console.info(`animation: mTouch is x:${this.mTouch.x},y:${this.mTouch.y}, process is ${process}`) -// -// this.calBezierPoint(); -// } -// -// draw(canvas: drawing.Canvas): void { -// -// let startTime = Date.now(); -// -// if (canIUse('SystemCapability.Graphics.Drawing')) { -// -// try { -// this.calPath(); -// -// console.info('draw called') -// this.drawCurrentPageArea(canvas); -// this.drawNextPage(canvas); -// this.drawCurrentTurningPage(canvas) -// -// let endTime = Date.now(); -// -// let shadowBrush = new drawing.Brush(); -// let maskFilter = drawing.MaskFilter.createBlurMaskFilter(drawing.BlurType.OUTER, 50); -// -// shadowBrush.setMaskFilter(maskFilter) -// canvas.attachBrush(shadowBrush) -// canvas.drawPath(this.mBottomPagePath); -// canvas.detachBrush() -// -// console.log(`绘制耗时:${endTime - startTime}`) -// -// } catch (e) { -// console.error(`绘制出错:${e}`) -// } -// } -// } -// -// private drawCurrentPageArea(canvas: drawing.Canvas): void { -// this.drawCurrentPage(canvas) -// this.drawCurrentPageShadow(canvas) -// } -// -// private drawCurrentPageShadow(canvas: drawing.Canvas): void { -// -// } -// -// private drawCurrentTurningPage(canvas: drawing.Canvas): void { -// if (canIUse('SystemCapability.Graphics.Drawing')) { -// -// canvas.save() -// canvas.clipPath(this.mBottomPagePath, drawing.ClipOp.INTERSECT) -// let backAreaPath = new drawing.Path() -// backAreaPath.moveTo(this.mTouch.x, this.mTouch.y) -// backAreaPath.lineTo(this.mBezierVertex1.x, this.mBezierVertex1.y) -// backAreaPath.lineTo(this.mBezierVertex2.x, this.mBezierVertex2.y) -// backAreaPath.close() -// canvas.clipPath(backAreaPath, drawing.ClipOp.INTERSECT) -// canvas.save(); -// -// let angle = -// 2 * (Math.PI / 2 - Math.atan2(this.mCornerY - this.mTouch.dy, this.mCornerX - this.mTouch.dx)); -// -// if (this.mCornerY === 0) { -// canvas.translate(this.currentSize.width, 0) -// canvas.scale(-1.0, 1.0) -// canvas.translate(-this.mTouch.x, this.mTouch.y) -// canvas.rotate(180 * ((angle) / Math.PI) - 180, this.mCornerX, this.mCornerY) -// this.drawCurrentPage(canvas,) -// } else { -// canvas.translate(0, this.currentSize.height,) -// canvas.scale(1.0, -1.0) -// canvas.translate(this.mTouch.x - this.currentSize.width, -this.mTouch.y) -// canvas.rotate(angle / Math.PI * 180, this.currentSize.width, this.currentSize.height,) -// this.drawCurrentPage(canvas,) -// } -// -// -// // canvas.drawColor(preBackColor) -// canvas.restore(); -// -// // const backMaskFilter = drawing.MaskFilter.createBlurMaskFilter(drawing.BlurType.INNER, 50); -// const maskBrush = new drawing.Brush(); -// // maskBrush.setMaskFilter(backMaskFilter) -// maskBrush.setColor({ -// alpha: 125, -// red: 255, -// green: 255, -// blue: 255 -// }); -// -// canvas.attachBrush(maskBrush); -// canvas.drawPath(backAreaPath); -// canvas.detachBrush(); -// -// const pen = new drawing.Pen(); -// pen.setStrokeWidth(150); -// pen.setColor({ -// alpha: 255, -// red: 0, -// green: 0, -// blue: 0 -// }); -// let maskFilter = drawing.MaskFilter.createBlurMaskFilter(drawing.BlurType.NORMAL, 70); -// pen.setMaskFilter(maskFilter); -// canvas.attachPen(pen); -// canvas.drawLine(this.mBezierVertex1.x, this.mBezierVertex1.y, this.mBezierVertex2.x, this.mBezierVertex2.y); -// canvas.detachPen(); -// -// -// canvas.restore() -// } -// -// } -// -// private drawCurrentPage(canvas: drawing.Canvas,): void { -// let preColor: common2D.Color = { -// alpha: 255, -// red: 255, -// green: 0, -// blue: 0 -// } -// -// let textColor: common2D.Color = { -// alpha: 255, -// red: 255, -// green: 255, -// blue: 255 -// } -// if (canIUse('SystemCapability.Graphics.Drawing')) { -// -// -// // const canvas = context.canvas; -// canvas.drawColor(preColor) -// const preBrush = new drawing.Brush(); -// preBrush.setColor({ -// alpha: 255, -// red: 255, -// green: 255, -// blue: 255 -// }); -// const preFont = new drawing.Font(); -// -// preFont.setSize(fp2px(20)); -// canvas.attachBrush(preBrush); -// let fontMetrics = preFont.getMetrics(); -// // 36是lineHeight,20是字号 -// let lineHeight = Math.round(fp2px(20) * (36 / 20)) -// let startY = Math.round(lineHeight * (Math.abs(fontMetrics.ascent) / (fontMetrics.descent - fontMetrics.ascent))) -// -// let pen = new drawing.Pen(); -// pen.setColor(textColor) -// // if(maskFilter!=null){ -// // pen.setMaskFilter(maskFilter) -// // } -// canvas.attachPen(pen) -// for (let index = 0; index < 20; index++) { -// const textBlob = drawing.TextBlob.makeFromString("第一页,第一页,第一页,第一页", preFont, -// drawing.TextEncoding.TEXT_ENCODING_UTF8); -// canvas.drawTextBlob(textBlob, vp2px(20), startY + (lineHeight * index)); -// } -// canvas.detachPen(); -// -// canvas.detachBrush(); -// } -// } -// -// private drawNextPage(canvas: drawing.Canvas): void { -// if (canIUse('SystemCapability.Graphics.Drawing')) { -// -// canvas.save() -// canvas.clipPath(this.mBottomPagePath, drawing.ClipOp.INTERSECT, true) -// let curColor: common2D.Color = { -// alpha: 255, -// red: 240, -// green: 240, -// blue: 40 -// } -// canvas.drawColor(curColor) -// const curBrush = new drawing.Brush(); -// curBrush.setColor({ -// alpha: 255, -// red: 0, -// green: 0, -// blue: 0 -// }); -// const curFont = new drawing.Font(); -// curFont.setSize(fp2px(20)); -// canvas.attachBrush(curBrush); -// let fontMetrics = curFont.getMetrics(); -// // 36是lineHeight,20是字号 -// let lineHeight = Math.round(fp2px(20) * (36 / 20)) -// let startY = Math.round(lineHeight * (Math.abs(fontMetrics.ascent) / (fontMetrics.descent - fontMetrics.ascent))) -// -// for (let index = 0; index <= 5; index++) { -// const textBlob = drawing.TextBlob.makeFromString("第二页,第二页,第二页,第二页", curFont, -// drawing.TextEncoding.TEXT_ENCODING_UTF8); -// canvas.drawTextBlob(textBlob, vp2px(20), startY + (lineHeight * index)); -// } -// -// canvas.detachBrush(); -// -// let k1 = (this.mBezierVertex1.y - this.mBezierVertex2.y) / (this.mBezierVertex1.x - this.mBezierVertex2.x); -// let b1 = this.mBezierVertex1.y - this.mBezierVertex1.x * k1; -// -// let shadowWidth = -// (Math.abs(k1 * this.mBezierStart1.x - this.mBezierStart1.y + b1)) / (Math.sqrt(Math.pow(k1, 2) + 1)) * 4 -// let shadowMaskFilter = drawing.MaskFilter.createBlurMaskFilter(drawing.BlurType.NORMAL, shadowWidth) -// -// const shadowPen = new drawing.Pen(); -// shadowPen.setStrokeWidth(shadowWidth) -// shadowPen.setMaskFilter(shadowMaskFilter) -// -// canvas.attachPen(shadowPen) -// canvas.drawLine(this.mBezierStart1.x, this.mBezierStart1.y, this.mBezierStart2.x, this.mBezierStart2.y) -// canvas.detachPen() -// -// canvas.restore() -// } -// } -// } -