中国优质的IT技术网站
专业IT技术创作平台
IT职业在线教育平台
微信扫码分享
@Entry @Component struct NovelPage { @Provide('fontSize') @Watch('onFontSizeChange') fontSize: number = Constants.INIT_FONT_SIZE; @Provide('bgColorIndex') @Watch('onBgColorChanged') bgColorIndex: BGColorType = BGColorType.WHITE; @Provide('bgColor') bgColor: string = BG_COLOR_ARRAY[BGColorType.WHITE]; @Provide('offsetX') offsetX: number = 0 @Provide('offsetY') offsetY: number = 0; @Provide('screenH') screenH: number = 0; @Provide('screenW') screenW: number = 0; @Provide('sumRow') sumRow: number = 0; @Provide('rowWord') rowWord: number = 0; @Provide('rotateAngleOne') rotateAngleOne: number = Constants.INIT_ROTATE_ANGLE_ONE; @Provide('rotateAngleTwo') rotateAngleTwo: number = 0.0; @Provide('curPosition') curPosition: number = 0; @Provide('turnStyle') turnStyle: FlipPageType = FlipPageType.SLIDE_FLIP_PAGE; @Provide('currentPageNum') @Watch('onFlush') currentPageNum: number = 1; @Provide('pageWordSum') pageWordSum: number = 0; @Provide('light') light: number = Constants.INIT_SCREEN_LIGHT; @Provide('isSystemLight') isSystemLight: boolean = false; @Provide('rowGap') rowGap: number = Constants.INIT_ROW_GAP; @State currentStartIndex: number = 0; @State isShow: boolean = false; @State isFontChanged: boolean = false; aboutToAppear(): void { this.screenW = px2vp(display.getDefaultDisplaySync().width); this.screenH = px2vp(display.getDefaultDisplaySync().height - (AppStorage.get('avoidHeight') as number)); this.sumRow = Math.floor((this.screenH) / (this.fontSize + this.rowGap)); this.rowWord = Math.floor((this.screenW - Constants.SCREEN_MARGIN_LEFT * 2) / this.fontSize); this.simulatePageContent(); this.changeSystemBarStatue(); } onFontSizeChange() { this.sumRow = Math.floor((this.screenH) / (this.fontSize + this.rowGap)); this.rowWord = Math.floor((this.screenW - Constants.SCREEN_MARGIN_LEFT * 2) / this.fontSize); let pageWordSum = this.sumRow * this.rowWord; if (this.currentStartIndex > pageWordSum) { this.currentPageNum = Math.floor(this.currentStartIndex / (pageWordSum)) + (this.currentStartIndex > 1 && this.currentStartIndex % pageWordSum > 0 ? 2 : 1); } else if (this.currentStartIndex > 0) { this.currentPageNum = 2; } else { Logger.info('currentStartIndex = ' + this.currentStartIndex); } this.isFontChanged = true; this.simulatePageContent(); } changeSystemBarStatue(): void { window.getLastWindow(getContext(this), (err, data) => { const errCode = err.code; if (errCode) { return; } let SystemBarProperties: window.SystemBarProperties = { statusBarColor: BG_COLOR_ARRAY[this.bgColorIndex], navigationBarColor: BG_COLOR_ARRAY[this.bgColorIndex], navigationBarContentColor: Constants.TRANSPARENT }; try { data.setWindowSystemBarProperties(SystemBarProperties, (err: BusinessError) => { const errCode: number = err.code; if (errCode) { Logger.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(err)); return; } data.setWindowBackgroundColor(BG_COLOR_ARRAY[this.bgColorIndex]); }); } catch (exception) { Logger.error('Failed to set the system bar properties. Cause: ' + JSON.stringify(exception)); } }); } onBgColorChanged() { this.changeSystemBarStatue(); } onFlush() { Logger.info('currentPageNum=' + this.currentPageNum + ', isFontChanged=' + this.isFontChanged); if (this.isFontChanged && this.currentPageNum === 1) { this.isFontChanged = false; this.currentStartIndex = 0; } } simulatePageContent() { this.offsetY = 0; this.rotateAngleTwo = 0.0; this.rotateAngleOne = Constants.INIT_ROTATE_ANGLE_ONE; } private clickAnimateTo(isLeft: Boolean) { if (this.turnStyle === FlipPageType.SLIDE_FLIP_PAGE) { animateTo({ duration: Constants.SLIDE_DURATION, curve: Curve.EaseOut, onFinish: () => { if (this.offsetX > 0) { this.currentPageNum > 0 ? this.currentPageNum - 1 : this.currentPageNum; this.currentStartIndex -= this.sumRow * this.rowWord; } if (this.offsetX < 0) { this.currentPageNum += 1; this.currentStartIndex += this.sumRow * this.rowWord; } Logger.info(this.currentStartIndex.toString()); this.offsetX = 0; this.simulatePageContent(); } }, () => { if (isLeft) { this.offsetX = this.screenW; } else { this.offsetX = -this.screenW; } }) } } build() { Row() { if (this.turnStyle === FlipPageType.SLIDE_FLIP_PAGE) { SlideFlipView({ currentStartIndex: this.currentStartIndex }) } } .width(Constants.FULL_PERCENT) .height(Constants.FULL_PERCENT) .bindSheet( $$this.isShow, this.myBuilder(), { height: SheetSize.FIT_CONTENT, detents: [Constants.SHEET_HEIGHT, Constants.SHEET_HEIGHT + 1], showClose: true, dragBar: true, title: { title: Constants.SHEET_TITLE }, backgroundColor: Constants.SHEET_BACKGROUND_COLOR } ) .backgroundColor(this.bgColor) } @Builder myBuilder() { } } 接上一条:Reade.ets @Component export default struct Reader { @Consume('bgColor') @Watch('onPageChange') bgColor: string; @Consume('fontSize') @Watch('onPageChange') fontSize: number; @Consume('turnStyle') turnStyle: FlipPageType; @Consume('screenW') screenW: number; @Consume('screenH') screenH: number; @Consume('rowGap') rowGap: number; @Consume('sumRow') sumRow: number @Consume('rowWord') rowWord: number; @Prop @Watch('onPageChange') startIndex: number = 0; private settings: RenderingContextSettings = new RenderingContextSettings(true); private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); private wordWidth: number = 0; private wordHeight: number = 0; aboutToAppear(): void { this.drawText(this.startIndex); } onPageChange() { this.drawText(this.startIndex); } drawText(startIndex: number) { this.wordWidth = this.fontSize; this.wordHeight = this.fontSize; this.context.fillStyle = this.bgColor; this.context.fillRect(0, 0, this.screenW, this.screenH); this.context.fillStyle = Color.Black; this.context.font = vp2px(this.fontSize) + Constants.CANVAS_FONT_SET; if (startIndex < 0) { startIndex = 0; } let gap = ((this.screenW - Constants.SCREEN_MARGIN_LEFT * 2) - this.wordWidth * this.rowWord) / (this.rowWord - 1); let realRowGap = (this.screenH - this.sumRow * (this.wordHeight + this.rowGap)) / (this.sumRow - 1); let currentX = Constants.SCREEN_MARGIN_LEFT; let currentY = this.wordHeight; for (let i = startIndex;; i++) { if (currentX + this.wordWidth > this.screenW - (Constants.SCREEN_MARGIN_LEFT - 1)) { currentX = Constants.SCREEN_MARGIN_LEFT; currentY = currentY + this.rowGap + this.wordHeight + realRowGap; if (currentY > this.screenH) { break; } } this.context.fillText(Constants.TEXT.charAt(i % Constants.TEXT.length), currentX, currentY); currentX += this.wordWidth + gap; } } build() { Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) { Column() { Canvas(this.context) .width(Constants.FULL_PERCENT) .height(Constants.FULL_PERCENT) .onReady(() => { this.drawText(this.startIndex); }) } .width(Constants.FULL_PERCENT) } .height(Constants.FULL_PERCENT) } } 第三条:SlideFlipView.ets @Component export struct SlideFlipView { @Consume('offsetX') offsetX: number; @Consume('sumRow') sumRow: number; @Consume('rowWord') rowWord: number; @Consume('screenW') screenW: number; @Consume('currentPageNum') currentPageNum: number; @Link currentStartIndex: number; private isFirst: boolean = false; build() { Stack() { Reader({ startIndex: this.currentStartIndex + this.sumRow * this.rowWord }) .translate({ x: this.offsetX >= 0 ? this.screenW : this.screenW + this.offsetX, y: 0, z: 0 }) Reader({ startIndex: this.currentStartIndex }) .translate({ x: this.offsetX, y: 0, z: 0 }) .width(this.screenW) Reader({ startIndex: this.currentStartIndex - this.sumRow * this.rowWord }) .translate({ x: this.offsetX >= 0 ? -this.screenW + this.offsetX : -this.screenW, y: 0, z: 0 }) } .gesture( PanGesture() .onActionUpdate((event?: GestureEvent) => { if (!event) { return; } if (this.currentPageNum <= 1 && event.offsetX > 0) { this.isFirst = true; return; } this.offsetX = event.offsetX; }) .onActionEnd(() => { animateTo({ duration: Constants.FLIP_DURATION, curve: Curve.EaseOut, onFinish: () => { if (this.offsetX > 0) { this.currentPageNum -= 1; if (this.currentStartIndex !== 0) { this.currentStartIndex -= this.sumRow * this.rowWord; } } if (this.offset