From 01d0d30bcda270fd017d9bc9e1d9f2ef05d4afce Mon Sep 17 00:00:00 2001 From: caorunyu Date: Fri, 23 May 2025 16:38:29 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E6=96=B0=E5=A2=9E=E6=8B=8D?= =?UTF-8?q?=E6=91=84=E5=80=92=E8=AE=A1=E6=97=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: caorunyu --- .../main/ets/constants/CameraConstants.ets | 4 + entry/src/main/ets/pages/Index.ets | 108 ++++++++++++++++-- 2 files changed, 102 insertions(+), 10 deletions(-) diff --git a/entry/src/main/ets/constants/CameraConstants.ets b/entry/src/main/ets/constants/CameraConstants.ets index b2b5d73..41fd44c 100644 --- a/entry/src/main/ets/constants/CameraConstants.ets +++ b/entry/src/main/ets/constants/CameraConstants.ets @@ -106,4 +106,8 @@ export class CameraConstants { * camera preview size */ public static readonly FRONT_HEIGHT: number = 3072; + /** + * count down time font size + */ + public static readonly COUNT_DOWN_FONT_SIZE: number = 100; } \ No newline at end of file diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index d796fd9..de72f86 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -56,6 +56,21 @@ let videoUri: string; let foldAbleStatus: number = 0; let currentFov: number = 1; +class CountDownTimerModifier implements ContentModifier { + applyContent(): WrappedBuilder<[TextTimerConfiguration]> { + return wrapBuilder(buildTextTimer); + } +} + +@Builder +function buildTextTimer(config: TextTimerConfiguration) { + Text(Math.ceil(config.count / 1000 - config.elapsedTime / 100).toString()) + .width(CameraConstants.FULL_SCREEN) + .fontSize(CameraConstants.COUNT_DOWN_FONT_SIZE) + .fontColor(Color.White) + .textAlign(TextAlign.Center) +} + @Component @Entry(storage) struct XComponentPage { @@ -76,13 +91,24 @@ struct XComponentPage { @StorageLink('photoUri') photoUri: string | Resource | PixelMap = ''; // Indicates whether the current preview type is an image @State currentPic: boolean = true; + // Flash icon @LocalStorageLink('flashPic') flashPic: Resource = $r('app.media.ic_camera_public_flash_off'); @LocalStorageLink('zoom') zoom: number = 1; @LocalStorageLink('isStabilization') isStabilization: boolean = false; @LocalStorageLink('isMovingPhoto') isMovingPhoto: boolean = false; + @LocalStorageLink('countDownTime') countDownTime: number = 0; + // Video record timer textTimerController: TextTimerController = new TextTimerController(); + // Custom count down timer + countDownTimeController: TextTimerController = new TextTimerController(); + countDownTimeModifier: CountDownTimerModifier = new CountDownTimerModifier(); + countDownInterval: number = 0; @State rotation: number = 0; + // Show zoom info on screen @State isShowZoom: boolean = false; + // Show count down time on screen + @State isCountingDown: boolean = false; + // Global context @State context: Context = this.getUIContext().getHostContext()!; onPageShow(): void { @@ -135,6 +161,7 @@ struct XComponentPage { } aboutToDisappear(): void { + clearInterval(this.countDownInterval); sensor.off(sensor.SensorId.GRAVITY); } @@ -253,13 +280,56 @@ struct XComponentPage { } ] ); + Image($r('sys.media.ohos_ic_public_clock')) + .fillColor(Color.White) + .height(CameraConstants.IMAGE_HEIGHT) + .margin(CameraConstants.MARGIN) + .visibility(this.isFront ? Visibility.Hidden : Visibility.Visible) + .rotate({ angle: this.rotation }) + .animation({ curve: curves.springMotion() }) + .bindMenu( + [ + { + value: 'off', + action: (): void => { + storage.setOrCreate('countDownTime', 0); + } + }, + { + value: '2s', + action: (): void => { + storage.setOrCreate('countDownTime', 2000); + } + }, + { + value: '5s', + action: (): void => { + storage.setOrCreate('countDownTime', 5000); + } + }, + { + value: '10s', + action: (): void => { + storage.setOrCreate('countDownTime', 10000); + } + }, + ] + ); } - .visibility(this.recording ? Visibility.Hidden : Visibility.Visible) + .visibility(this.recording || this.isCountingDown ? Visibility.Hidden : Visibility.Visible) .width(CameraConstants.FULL_SCREEN) .margin({ top: CameraConstants.MARGIN_TOP, bottom: CameraConstants.MARGIN_HEIGHT }) .justifyContent(FlexAlign.SpaceAround); Stack() { + TextTimer({ controller: this.countDownTimeController, isCountDown: true, count: this.countDownTime }) + .contentModifier(this.countDownTimeModifier) + .visibility(this.isCountingDown ? Visibility.Visible : Visibility.Hidden) + .position({ + top: this.isPhoto || this.foldAbleStatus === FoldStatus.FOLD_STATUS_EXPANDED ? 200 : 285 + }) + .zIndex(1) + XComponent({ type: XComponentType.SURFACE, controller: this.mXComponentController @@ -267,7 +337,7 @@ struct XComponentPage { .gesture( PinchGesture({ fingers: 2 }) .onActionUpdate((event: GestureEvent) => { - if (event && !this.isStabilization) { + if (event && !this.isStabilization && !this.isCountingDown) { this.zoom = currentFov * event.scale; this.isShowZoom = true; if (this.zoom > (this.isPhoto ? zoomRatioRange[1] : 15)) { @@ -342,13 +412,13 @@ struct XComponentPage { this.setZoom(); }) } - .visibility(this.isFront || this.isStabilization ? Visibility.Hidden : Visibility.Visible) + .visibility(this.isFront || this.isStabilization || this.isCountingDown ? Visibility.Hidden : Visibility.Visible) .margin({ top: this.isFoldAble ? CameraConstants.PREVIEW_HEIGHT_BUTTON : 450 }) Text(this.zoom === zoomRatioRange[0] ? 'wide angle' : this.zoom.toFixed(1) + 'x') .fontColor(Color.White) .margin({ top: 250 }) - .visibility(this.isShowZoom && !this.isFront ? Visibility.Visible : Visibility.Hidden) + .visibility(this.isShowZoom && !this.isFront && !this.isCountingDown ? Visibility.Visible : Visibility.Hidden) Column() { Row() { @@ -381,7 +451,7 @@ struct XComponentPage { } }) } - .visibility(this.recording ? Visibility.Hidden : Visibility.Visible) + .visibility(this.recording || this.isCountingDown ? Visibility.Hidden : Visibility.Visible) .justifyContent(FlexAlign.SpaceAround) .width(CameraConstants.CENTER_WIDTH) .height(CameraConstants.CAPTURE_SIZE) @@ -407,16 +477,32 @@ struct XComponentPage { .height(CameraConstants.CAPTURE_SIZE) .visibility(this.isPhoto ? Visibility.Visible : Visibility.Hidden) .onClick(() => { - capture(this.isFront); - this.currentPic = true; + if (this.countDownTime !== 0) { + this.isCountingDown = true; + this.countDownTimeController.start(); + } + this.countDownInterval = setTimeout(() => { + this.isCountingDown = false; + this.countDownTimeController.reset(); + capture(this.isFront); + this.currentPic = true; + }, this.countDownTime); }) Image($r('app.media.record')) .height(CameraConstants.CAPTURE_SIZE) .visibility(this.isPhoto ? Visibility.Hidden : this.recording ? Visibility.Hidden : Visibility.Visible) .onClick(async () => { - startRecord(); - this.textTimerController.start(); - this.recording = true; + if (this.countDownTime !== 0) { + this.isCountingDown = true; + this.countDownTimeController.start(); + } + this.countDownInterval = setTimeout(() => { + this.isCountingDown = false; + this.countDownTimeController.reset(); + startRecord(); + this.textTimerController.start(); + this.recording = true; + }, this.countDownTime); }) Image($r('app.media.recording')) .visibility(this.isPhoto ? Visibility.Hidden : this.recording ? Visibility.Visible : Visibility.Hidden) @@ -457,6 +543,7 @@ struct XComponentPage { this.isFront = cameraPosition !== 0; }) } + .visibility(this.isCountingDown ? Visibility.Hidden : Visibility.Visible) .width(CameraConstants.FULL_SCREEN) .justifyContent(FlexAlign.SpaceAround) @@ -520,5 +607,6 @@ export async function fromBack(context: Context): Promise { currentFov = 1; storage.setOrCreate('isStabilization', false); storage.setOrCreate('isMovingPhoto', false); + storage.setOrCreate('countDownTime', 0); cameraShooting(isVideo, cameraPosition, surfaceId, context, foldAbleStatus); } \ No newline at end of file -- Gitee