1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import display from '@ohos.display' 17 18import { Log } from '../../utils/Log' 19import { getStore, OhCombinedState } from '../../redux/store' 20import { Action } from '../../redux/actions/Action' 21import { EventBus } from '../../worker/eventbus/EventBus' 22import { EventBusManager } from '../../worker/eventbus/EventBusManager' 23 24let localDispatcher = (dispatch) => { 25 return { 26 updateZoomRatio: (zoomRatio: number) => { 27 dispatch(Action.changeZoomRatio(zoomRatio)) 28 }, 29 updateShowZoomFlag: (flag: boolean) => { 30 dispatch(Action.updateShowZoomTextFlag(flag)) 31 }, 32 updateShowZoomLabelValue: (flag: boolean) => { 33 dispatch(Action.updateShowZoomLabelValue(flag)) 34 } 35 } 36} 37 38let SHOW_FOLD_CANVAS: number = 0 39let SHOW_NOT_TAKE_VIDEO_CANVAS: number = 1 40let SHOW_TAKING_VIDEO_CANVAS: number = 2 41 42class StateStruct { 43 mode 44 videoState 45 cameraPosition 46 isShowPressScrollDetailPhotoButton 47 minZoomRatio 48 maxZoomRatio 49 scrollDetailsBox 50 isPhotoZoomDetails 51 photoDetailsOffsetX 52 photoDetailsOffsetXInit 53 updateZoomRatio: Function 54 updateShowZoomFlag: Function 55 updateShowZoomLabelValue: Function 56} 57 58@Component 59export struct ZoomViewLand { 60 private TAG: string = '[ZoomViewLand]:' 61 private mConnect: any 62 private appEventBus: EventBus = EventBusManager.getInstance().getEventBus() 63 64 @State state: StateStruct = new StateStruct() 65 @State @Watch('onZoomRatioRefresh') zoomRatio: number = 0 66 @State @Watch('onZoomRatioRefresh') showZoomLabelValue: boolean = true 67 @State @Watch('onZoomRatioRefresh') isShowZoomText: boolean = false 68 @State @Watch('onZoomRatioRefresh') curZoomRatio: number = 0 69 @State offsetY: number = 0 70 @State triggerRebuildNum: number = 0 71 72 private canvasWidth: number = 82 73 private notTakeVideoExtCanvasHeight: number = 360 74 private takingVideoExtCanvasHeight: number = 196 75 private foldCanvasHeight: number = 94 76 77 private touchedOffsetY: number = this.takingVideoExtCanvasHeight / 2 78 private startOffsetY: number = 0 79 80 private canvasSettings: RenderingContextSettings = new RenderingContextSettings(true) 81 private notTakeVideoExtCanvasCxt: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.canvasSettings) 82 private takingVideoExtCanvasCxt: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.canvasSettings) 83 private foldCanvasCxt: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.canvasSettings) 84 private notTakeVideoExtOffCanvasCxt: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D( 85 this.canvasWidth, this.notTakeVideoExtCanvasHeight, this.canvasSettings) 86 private takingVideoExtOffCanvasCxt: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D( 87 this.canvasWidth, this.notTakeVideoExtCanvasHeight, this.canvasSettings) 88 private foldOffCanvasCxt: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D( 89 this.canvasWidth, this.foldCanvasHeight, this.canvasSettings) 90 91 private lpgTimer: number = 0 92 private pgTimer: number = 0 93 private lpgExp: boolean = false 94 private pgExp: boolean = false 95 private zoomTimer: number = 0 96 private baseZoomRatio: number = 1 97 98 private mainDotRadius: number = 1.5 99 private secDotRadius: number = 0.75 100 private centerDotRadius: number = 2.5 101 private dotSpacing: number = 4 102 private refreshSwitchCanvas: number = -1 103 104 aboutToAppear(): void { 105 this.mConnect = getStore().connect((state: OhCombinedState) => { 106 this.zoomRatio = state.ZoomReducer.zoomRatio 107 this.showZoomLabelValue = state.ZoomReducer.showZoomLabelValue 108 this.isShowZoomText = state.ZoomReducer.isShowZoomText 109 return { 110 mode: state.ModeReducer.mode, 111 videoState: state.RecordReducer.videoState, 112 cameraPosition: state.CameraReducer.cameraPosition, 113 isShowPressScrollDetailPhotoButton: state.ZoomReducer.isShowPressScrollDetailPhotoButton, 114 minZoomRatio: state.ZoomReducer.minZoomRatio, 115 maxZoomRatio: state.ZoomReducer.maxZoomRatio, 116 scrollDetailsBox: state.ZoomReducer.scrollDetailsBox, 117 isPhotoZoomDetails: state.ZoomReducer.isPhotoZoomDetails, 118 photoDetailsOffsetX: state.ZoomReducer.photoDetailsOffsetX, 119 photoDetailsOffsetXInit: state.ZoomReducer.photoDetailsOffsetXInit, 120 } 121 }, localDispatcher)(this.state) 122 this.appEventBus.on(Action.ACTION_CHANGE_ZOOM_RATIO, this.updateZoomOffset.bind(this)) 123 this.appEventBus.on(Action.ACTION_UPDATE_VIDEO_STATE, this.updateZoomState.bind(this)) 124 } 125 126 aboutToDisappear(): void { 127 this.appEventBus.off(Action.ACTION_CHANGE_ZOOM_RATIO, this.updateZoomOffset.bind(this)) 128 this.appEventBus.off(Action.ACTION_UPDATE_VIDEO_STATE, this.updateZoomState.bind(this)) 129 this.mConnect?.destroy() 130 } 131 132 private getCurrentCanvasType(): number { 133 if (this.isShowZoomText && (this.state.videoState === 'beforeTakeVideo' 134 && (this.state.mode === 'PHOTO' || this.state.mode === 'VIDEO'))) { 135 return SHOW_NOT_TAKE_VIDEO_CANVAS 136 } else if (this.state.mode === 'VIDEO' 137 && (this.isShowZoomText || this.state.videoState !== 'beforeTakeVideo')) { 138 return SHOW_TAKING_VIDEO_CANVAS 139 } else { 140 return SHOW_FOLD_CANVAS 141 } 142 } 143 144 private changeZoomRatioOnTakingVideoExt(): void { 145 if (this.touchedOffsetY < this.takingVideoExtCanvasHeight / 2) { 146 this.addZoomRatio() 147 } else if (this.touchedOffsetY > this.takingVideoExtCanvasHeight / 2) { 148 this.subtractZoomRatio() 149 } else { 150 this.triggerRebuildNum = this.triggerRebuildNum + 0.0001 151 this.state.updateShowZoomFlag(false) 152 } 153 } 154 155 private addZoomRatio(): void { 156 this.curZoomRatio = this.zoomRatio + 0.1 157 if (this.curZoomRatio > this.state.maxZoomRatio) { 158 this.curZoomRatio = this.state.maxZoomRatio 159 } 160 this.state.updateZoomRatio(this.curZoomRatio) 161 this.state.updateShowZoomFlag(true) 162 this.triggerRebuildNum = this.triggerRebuildNum + 0.0001 163 } 164 165 private subtractZoomRatio(): void { 166 this.curZoomRatio = this.zoomRatio - 0.1 167 if (this.curZoomRatio < this.state.minZoomRatio) { 168 this.curZoomRatio = this.state.minZoomRatio 169 } 170 this.state.updateZoomRatio(this.curZoomRatio) 171 this.state.updateShowZoomFlag(true) 172 this.triggerRebuildNum = this.triggerRebuildNum - 0.0001 173 } 174 175 private takingVideoExtTouched(event: TouchEvent): void { 176 if (event.type === TouchType.Down) { 177 this.touchedOffsetY = event.touches[0].y 178 this.startOffsetY = event.touches[0].y 179 this.changeZoomRatioOnTakingVideoExt() 180 } 181 if (event.type === TouchType.Up) { 182 this.touchedOffsetY = this.takingVideoExtCanvasHeight / 2 183 this.changeZoomRatioOnTakingVideoExt() 184 } 185 } 186 187 private takingVideoExtLongPgAction(event: GestureEvent): void { 188 this.touchedOffsetY = event.fingerList[0].localY 189 this.changeZoomRatioOnTakingVideoExt() 190 } 191 192 private takingVideoExtLongPgActionEnd(): void { 193 this.touchedOffsetY = this.takingVideoExtCanvasHeight / 2 194 this.changeZoomRatioOnTakingVideoExt() 195 } 196 197 private takingVideoExtPgActionStart(event: GestureEvent): void { 198 this.touchedOffsetY = this.startOffsetY + event.offsetY 199 this.changeZoomRatioOnTakingVideoExt() 200 } 201 202 private takingVideoExtPgActionUpdate(event: GestureEvent): void { 203 this.touchedOffsetY = this.startOffsetY + event.offsetY 204 let takingVideoExtMaxOffsetY = this.takingVideoExtCanvasHeight - this.getZoomBtnRadius() - this.secDotRadius 205 let takingVideoExtMinOffsetY = this.getZoomBtnRadius() + this.secDotRadius 206 if (this.touchedOffsetY > takingVideoExtMaxOffsetY) { 207 this.touchedOffsetY = takingVideoExtMaxOffsetY 208 } else if (this.touchedOffsetY < takingVideoExtMinOffsetY) { 209 this.touchedOffsetY = takingVideoExtMinOffsetY 210 } 211 this.changeZoomRatioOnTakingVideoExt() 212 } 213 214 private takingVideoExtPgActionEnd(event: GestureEvent): void { 215 this.touchedOffsetY = this.takingVideoExtCanvasHeight / 2 216 this.startOffsetY = 0 217 this.changeZoomRatioOnTakingVideoExt() 218 } 219 220 private subtractTouched(event: TouchEvent): void { 221 if (event.type === TouchType.Down) { 222 this.subtractZoomRatio() 223 } 224 if (event.type === TouchType.Up) { 225 this.state.updateShowZoomFlag(false) 226 } 227 } 228 229 private subtractLongOnAction(event: GestureEvent): void { 230 this.subtractZoomRatio() 231 } 232 233 private subtractLongOnActionEnd(): void { 234 this.state.updateShowZoomFlag(false) 235 } 236 237 private addTouched(event: TouchEvent): void { 238 if (event.type === TouchType.Down) { 239 this.addZoomRatio() 240 } 241 if (event.type === TouchType.Up) { 242 this.state.updateShowZoomFlag(false) 243 } 244 } 245 246 private addLongOnAction(event: GestureEvent): void { 247 this.addZoomRatio() 248 } 249 250 private addLongOnActionEnd(): void { 251 this.state.updateShowZoomFlag(false) 252 } 253 254 private lpgOnAction(event: GestureEvent): void { 255 this.clearTimer() 256 this.state.updateShowZoomFlag(true) 257 this.baseZoomRatio = this.zoomRatio 258 this.offsetY = (this.zoomRatio - 1) * this.getZoomOffsetUnit() 259 this.lpgExp = true 260 this.pgExp = false 261 this.triggerRebuildNum = this.triggerRebuildNum + 0.0001 262 } 263 264 private lpgOnActionEnd(): void { 265 if (this.lpgTimer) { 266 clearTimeout(this.lpgTimer) 267 } 268 this.lpgTimer = setTimeout(() => { 269 if (this.lpgExp && !this.pgExp) { 270 this.state.updateShowZoomFlag(false) 271 this.triggerRebuildNum = this.triggerRebuildNum - 0.0001 272 } 273 this.lpgExp = false 274 }, 3000) 275 } 276 277 private pgOnActionStart(event: GestureEvent): void { 278 this.clearTimer() 279 this.state.updateShowZoomFlag(true) 280 this.state.updateShowZoomLabelValue(false) 281 this.baseZoomRatio = this.zoomRatio 282 this.pgExp = true 283 this.lpgExp = false 284 } 285 286 private pgOnActionUpdate(event: GestureEvent): void { 287 this.offsetY = (this.baseZoomRatio - this.state.minZoomRatio) * this.getZoomOffsetUnit() - event.offsetY 288 this.updateZoomRatio() 289 } 290 291 private pgOnActionEnd(event: GestureEvent): void { 292 this.state.updateShowZoomLabelValue(true) 293 if (this.pgTimer) { 294 clearTimeout(this.pgTimer) 295 } 296 this.pgTimer = setTimeout(() => { 297 if (this.pgExp && !this.lpgExp) { 298 this.state.updateShowZoomFlag(false) 299 } 300 this.pgExp = false 301 }, 3000) 302 } 303 304 private mOnTouch(event: TouchEvent): void { 305 if (event.type === TouchType.Down) { 306 this.clearTimer() 307 this.state.updateShowZoomFlag(true) 308 this.pgExp = true 309 this.lpgExp = false 310 311 let y = event.touches[0].y 312 let zoomRatio = this.zoomRatio 313 if (this.state.videoState === 'beforeTakeVideo' && this.getCurrentCanvasType() === SHOW_NOT_TAKE_VIDEO_CANVAS) { 314 if (y < vp2px(36)) { 315 zoomRatio = this.state.maxZoomRatio 316 } 317 if (y > this.notTakeVideoExtCanvasHeight - vp2px(36)) { 318 zoomRatio = this.state.minZoomRatio 319 } 320 if (y > vp2px(36) && y < this.notTakeVideoExtCanvasHeight - vp2px(36)) { 321 this.offsetY = this.notTakeVideoExtCanvasHeight - y - this.getPadding() 322 this.updateZoomRatio() 323 return; 324 } 325 } 326 this.offsetY = (zoomRatio - 1) * this.getZoomOffsetUnit() 327 this.updateZoomRatio() 328 } else if (event.type === TouchType.Up) { 329 if (this.pgTimer) { 330 clearTimeout(this.pgTimer) 331 } 332 this.pgTimer = setTimeout(() => { 333 if (this.pgExp && !this.lpgExp) { 334 this.state.updateShowZoomFlag(false) 335 } 336 this.pgExp = false 337 }, 3000) 338 } 339 } 340 341 private getZoomBtnCenterY(): number { 342 if (this.getCurrentCanvasType() === SHOW_TAKING_VIDEO_CANVAS) { 343 return this.touchedOffsetY 344 } 345 if (this.offsetY === 0 && this.zoomRatio !== 1) { 346 this.offsetY = (this.zoomRatio - this.state.minZoomRatio) * this.getZoomOffsetUnit() 347 } 348 if (this.zoomRatio === 1 && this.offsetY !== 0) { 349 this.offsetY = 0 350 } 351 let padding = this.getPadding() 352 let result = this.notTakeVideoExtCanvasHeight - padding - this.offsetY 353 return result 354 } 355 356 private getZoomOffsetUnit(): number { 357 let padding = this.getPadding() 358 let fullHeight = this.notTakeVideoExtCanvasHeight - padding * 2 - this.mainDotRadius * 2 359 return fullHeight / (this.state.maxZoomRatio - this.state.minZoomRatio) 360 } 361 362 private updateZoomOffset(data): void { 363 let padding = this.getPadding() 364 let offset = (data.zoomRatio - this.state.minZoomRatio) * this.getZoomOffsetUnit() 365 this.offsetY = offset 366 } 367 368 private updateZoomState(data): void { 369 if (data.videoState === 'beforeTakeVideo') { 370 this.clearTimer() 371 this.state.updateShowZoomFlag(false) 372 this.pgExp = false 373 } 374 } 375 376 private clearTimer(): void { 377 if (this.pgTimer) { 378 clearTimeout(this.pgTimer) 379 } 380 if (this.lpgTimer) { 381 clearTimeout(this.lpgTimer) 382 } 383 } 384 385 private updateZoomRatio(): void { 386 let padding = this.getPadding() 387 let fullHeight = this.notTakeVideoExtCanvasHeight - padding * 2 - this.mainDotRadius * 2 388 this.curZoomRatio = (this.offsetY / fullHeight) * (this.state.maxZoomRatio - this.state.minZoomRatio) + this.state.minZoomRatio 389 if (this.curZoomRatio > this.state.maxZoomRatio) { 390 this.curZoomRatio = this.state.maxZoomRatio 391 } 392 if (this.curZoomRatio < this.state.minZoomRatio) { 393 this.curZoomRatio = this.state.minZoomRatio 394 } 395 this.state.updateZoomRatio(this.curZoomRatio) 396 } 397 398 private getPadding(): number { 399 if (this.getCurrentCanvasType() === SHOW_NOT_TAKE_VIDEO_CANVAS) { 400 return 32 401 } else if (this.getCurrentCanvasType() === SHOW_TAKING_VIDEO_CANVAS) { 402 return 15.5 403 } else { 404 return 32 405 } 406 } 407 408 private getZoomText() { 409 return `${Number(this.zoomRatio.toFixed(1))}x` 410 } 411 412 private getZoomBtnRadius(): number { 413 if (!this.showZoomLabelValue) { 414 return 17.25 415 } else { 416 return 15.25 417 } 418 } 419 420 private onZoomRatioRefresh() { 421 if (this.getCurrentCanvasType() === this.refreshSwitchCanvas) { 422 this.refreshCanvas(this.refreshSwitchCanvas) 423 } 424 } 425 426 private canvasInit(mType: number) { 427 this.refreshSwitchCanvas = mType 428 this.refreshCanvas(mType) 429 } 430 431 private refreshCanvas(mType: number) { 432 switch (mType) { 433 case SHOW_NOT_TAKE_VIDEO_CANVAS: 434 this.notTakeVideoCanvas(); 435 break; 436 case SHOW_TAKING_VIDEO_CANVAS: 437 this.takingVideoCanvas(); 438 break; 439 default: 440 this.foldCanvas() 441 } 442 } 443 444 private notTakeVideoCanvas() { 445 this.notTakeVideoExtCanvasCxt.clearRect(0, 0, this.canvasWidth, this.notTakeVideoExtCanvasHeight) 446 this.notTakeVideoExtOffCanvasCxt.clearRect(0, 0, this.canvasWidth, this.notTakeVideoExtCanvasHeight) 447 this.notTakeVideoExtOffCanvasCxt.strokeStyle = '#ffffff' 448 this.notTakeVideoExtOffCanvasCxt.fillStyle = '#ffffff' 449 this.notTakeVideoExtOffCanvasCxt.lineWidth = 1.5 450 this.notTakeVideoExtOffCanvasCxt.beginPath() 451 this.notTakeVideoExtOffCanvasCxt.arc(this.canvasWidth / 2, this.getZoomBtnCenterY(), this.getZoomBtnRadius(), 0, 6.28) 452 this.notTakeVideoExtOffCanvasCxt.stroke() 453 if (this.showZoomLabelValue) { 454 this.notTakeVideoExtOffCanvasCxt.font = `bold ${vp2px(11)}px` 455 this.notTakeVideoExtOffCanvasCxt.textAlign = 'center' 456 this.notTakeVideoExtOffCanvasCxt.fillText(this.getZoomText(), this.canvasWidth / 2, this.getZoomBtnCenterY() + 5) 457 } else { 458 this.notTakeVideoExtOffCanvasCxt.beginPath() 459 this.notTakeVideoExtOffCanvasCxt.arc(this.canvasWidth / 2, this.getZoomBtnCenterY(), this.centerDotRadius, 0, 6.28) 460 this.notTakeVideoExtOffCanvasCxt.fill() 461 } 462 463 let spotCount = (this.notTakeVideoExtCanvasHeight - this.getPadding() * 2 - this.mainDotRadius * 4 - this.dotSpacing) / (this.dotSpacing + this.secDotRadius * 2) + 2 464 for (let i = 0; i < spotCount; i++) { 465 let spotCenter = 0 466 let spotRadius = 0 467 if (i === 0) { 468 spotRadius = this.mainDotRadius 469 spotCenter = this.notTakeVideoExtCanvasHeight - this.getPadding() - spotRadius 470 this.notTakeVideoExtOffCanvasCxt.font = `bold ${vp2px(11)}px` 471 this.notTakeVideoExtOffCanvasCxt.textAlign = 'right' 472 this.notTakeVideoExtOffCanvasCxt.fillText(`${this.state.minZoomRatio}x`,this.canvasWidth / 2 - (!this.showZoomLabelValue ? 26: 24), spotCenter) 473 } else if (i === spotCount - 1) { 474 spotRadius = this.mainDotRadius 475 spotCenter = this.getPadding() + spotRadius 476 this.notTakeVideoExtOffCanvasCxt.font = `bold ${vp2px(11)}px` 477 this.notTakeVideoExtOffCanvasCxt.textAlign = 'right' 478 this.notTakeVideoExtOffCanvasCxt.fillText(`${this.state.maxZoomRatio}x`,this.canvasWidth / 2 - (!this.showZoomLabelValue ? 26: 24), spotCenter) 479 } else { 480 spotRadius = this.secDotRadius 481 spotCenter = this.notTakeVideoExtCanvasHeight - this.getPadding() - this.mainDotRadius * 2 - (2 * i - 1) * this.secDotRadius - i * this.dotSpacing 482 this.notTakeVideoExtOffCanvasCxt.globalAlpha = 0.2 483 } 484 if (spotCenter < this.getZoomBtnCenterY() - this.getZoomBtnRadius() || spotCenter > this.getZoomBtnCenterY() + this.getZoomBtnRadius()) { 485 this.notTakeVideoExtOffCanvasCxt.beginPath() 486 this.notTakeVideoExtOffCanvasCxt.arc(this.canvasWidth / 2, spotCenter, spotRadius, 0, 6.28) 487 this.notTakeVideoExtOffCanvasCxt.fill() 488 } 489 this.notTakeVideoExtOffCanvasCxt.globalAlpha = 1 490 } 491 this.notTakeVideoExtCanvasCxt.transferFromImageBitmap(this.notTakeVideoExtOffCanvasCxt.transferToImageBitmap()) 492 } 493 494 private takingVideoCanvas() { 495 this.takingVideoExtCanvasCxt.clearRect(0, 0, this.canvasWidth, this.takingVideoExtCanvasHeight) 496 this.takingVideoExtOffCanvasCxt.clearRect(0, 0, this.canvasWidth, this.takingVideoExtCanvasHeight) 497 this.takingVideoExtOffCanvasCxt.strokeStyle = '#ffffff' 498 this.takingVideoExtOffCanvasCxt.fillStyle = '#ffffff' 499 this.takingVideoExtOffCanvasCxt.lineWidth = 1.5 500 this.takingVideoExtOffCanvasCxt.beginPath() 501 this.takingVideoExtOffCanvasCxt.arc(this.canvasWidth / 2, this.getZoomBtnCenterY(), this.getZoomBtnRadius(), 0, 6.28) 502 this.takingVideoExtOffCanvasCxt.stroke() 503 if (this.isShowZoomText) { 504 this.takingVideoExtOffCanvasCxt.beginPath() 505 this.takingVideoExtOffCanvasCxt.arc(this.canvasWidth / 2, this.getZoomBtnCenterY(), this.centerDotRadius, 0, 6.28) 506 this.takingVideoExtOffCanvasCxt.fill() 507 } else { 508 this.takingVideoExtOffCanvasCxt.font = `bold ${vp2px(11)}px` 509 this.takingVideoExtOffCanvasCxt.textAlign = 'center' 510 this.takingVideoExtOffCanvasCxt.fillText(this.getZoomText(), this.canvasWidth / 2, this.getZoomBtnCenterY() + 5) 511 } 512 513 let spotCount = 30 514 for (let i = 0; i < spotCount; i++) { 515 let spotCenter = 0 516 let spotRadius = 0 517 spotRadius = this.secDotRadius 518 spotCenter = this.getPadding() + (2 * i + 1) * this.secDotRadius + i * this.dotSpacing 519 this.takingVideoExtOffCanvasCxt.globalAlpha = 0.2 520 if (spotCenter < this.getZoomBtnCenterY() - this.getZoomBtnRadius() || spotCenter > this.getZoomBtnCenterY() + this.getZoomBtnRadius()) { 521 this.takingVideoExtOffCanvasCxt.beginPath() 522 this.takingVideoExtOffCanvasCxt.arc(this.canvasWidth / 2, spotCenter, spotRadius, 0, 6.28) 523 this.takingVideoExtOffCanvasCxt.fill() 524 } 525 this.takingVideoExtOffCanvasCxt.globalAlpha = 1 526 } 527 528 this.takingVideoExtCanvasCxt.transferFromImageBitmap(this.takingVideoExtOffCanvasCxt.transferToImageBitmap()) 529 } 530 531 private foldCanvas() { 532 this.foldCanvasCxt.clearRect(0, 0, this.canvasWidth, this.foldCanvasHeight) 533 this.foldOffCanvasCxt.clearRect(0, 0, this.canvasWidth, this.foldCanvasHeight) 534 this.foldOffCanvasCxt.strokeStyle = '#ffffff' 535 this.foldOffCanvasCxt.fillStyle = '#ffffff' 536 this.foldOffCanvasCxt.lineWidth = 1.5 537 this.foldOffCanvasCxt.beginPath() 538 this.foldOffCanvasCxt.arc(this.canvasWidth / 2, this.foldCanvasHeight / 2, this.getZoomBtnRadius(), 0, 6.28) 539 this.foldOffCanvasCxt.stroke() 540 541 this.foldOffCanvasCxt.font = `bold ${vp2px(10)}px` 542 this.foldOffCanvasCxt.textAlign = 'center' 543 this.foldOffCanvasCxt.fillText(this.getZoomText(), this.canvasWidth / 2, this.foldCanvasHeight / 2 + 3) 544 545 let fullHeight = this.foldCanvasHeight / 2 - this.mainDotRadius 546 let spotCount = (fullHeight - this.mainDotRadius * 2 - this.dotSpacing) / (this.dotSpacing + this.secDotRadius * 2) + 2 547 let spotOffset = (this.zoomRatio === this.state.maxZoomRatio) ? this.foldCanvasHeight / 2 + fullHeight 548 : this.foldCanvasHeight / 2 549 for (let i = 0; i < spotCount; i++) { 550 let spotCenter = 0 551 let spotRadius = 0 552 if (i === 0) { 553 spotRadius = this.mainDotRadius 554 spotCenter = spotOffset - spotRadius 555 } else if (i === spotCount - 1) { 556 spotRadius = this.mainDotRadius 557 spotCenter = spotOffset - this.mainDotRadius * 2 - (i - 1) * this.dotSpacing - (2 * i - 1) * this.secDotRadius + this.secDotRadius - spotRadius 558 } else { 559 spotRadius = this.secDotRadius 560 spotCenter = spotOffset - this.mainDotRadius * 2 - (i - 1) * this.dotSpacing - (2 * i - 1) * this.secDotRadius - spotRadius 561 this.foldOffCanvasCxt.globalAlpha = 0.2 562 } 563 if (spotCenter > this.foldCanvasHeight / 2 + this.getZoomBtnRadius() || spotCenter < this.foldCanvasHeight / 2 - this.getZoomBtnRadius()) { 564 this.foldOffCanvasCxt.beginPath() 565 this.foldOffCanvasCxt.arc(this.canvasWidth / 2, spotCenter, spotRadius, 0, 6.28) 566 this.foldOffCanvasCxt.fill() 567 } 568 this.foldOffCanvasCxt.globalAlpha = 1 569 } 570 this.foldCanvasCxt.transferFromImageBitmap(this.foldOffCanvasCxt.transferToImageBitmap()) 571 } 572 573 build() { 574 Stack({ alignContent: Alignment.Start}) { 575 Stack({ alignContent: Alignment.Top }).width(this.triggerRebuildNum).height(this.offsetY + this.touchedOffsetY + this.zoomRatio).visibility(Visibility.None) 576 if (this.getCurrentCanvasType() === SHOW_NOT_TAKE_VIDEO_CANVAS) { 577 Canvas(this.notTakeVideoExtCanvasCxt) 578 .width(this.canvasWidth) 579 .height(this.notTakeVideoExtCanvasHeight) 580 .onReady(() => this.canvasInit(SHOW_NOT_TAKE_VIDEO_CANVAS)) 581 .gesture( 582 GestureGroup( 583 GestureMode.Parallel, 584 PanGesture({ fingers: 1, distance: 1, direction: PanDirection.Vertical}) 585 .onActionStart(this.pgOnActionStart.bind(this)) 586 .onActionUpdate(this.pgOnActionUpdate.bind(this)) 587 .onActionEnd(this.pgOnActionEnd.bind(this)) 588 ) 589 ) 590 .onTouch(this.mOnTouch.bind(this)) 591 } else if (this.getCurrentCanvasType() === SHOW_TAKING_VIDEO_CANVAS) { 592 Column() { 593 Image($r('app.media.ic_camera_public_focus_ev_bright_add')) 594 .width(24) 595 .height(24) 596 .fillColor(Color.White) 597 .onTouch(this.addTouched.bind(this)) 598 .gesture( 599 GestureGroup( 600 GestureMode.Parallel, 601 LongPressGesture({ repeat: true }) 602 .onAction(this.addLongOnAction.bind(this)) 603 .onActionEnd(this.addLongOnActionEnd.bind(this)) 604 ) 605 ) 606 Canvas(this.takingVideoExtCanvasCxt) 607 .width(this.canvasWidth) 608 .height(this.takingVideoExtCanvasHeight) 609 .onReady(() => this.canvasInit(SHOW_TAKING_VIDEO_CANVAS)) 610 .gesture( 611 GestureGroup( 612 GestureMode.Parallel, 613 LongPressGesture({ repeat: true }) 614 .onAction(this.takingVideoExtLongPgAction.bind(this)) 615 .onActionEnd(this.takingVideoExtLongPgActionEnd.bind(this)), 616 PanGesture({ fingers: 1, distance: 1, direction: PanDirection.Vertical }) 617 .onActionStart(this.takingVideoExtPgActionStart.bind(this)) 618 .onActionUpdate(this.takingVideoExtPgActionUpdate.bind(this)) 619 .onActionEnd(this.takingVideoExtPgActionEnd.bind(this)) 620 ) 621 ) 622 .onTouch(this.takingVideoExtTouched.bind(this)) 623 Image($r('app.media.ic_camera_public_focus_ev_bright_subtract')) 624 .width(24) 625 .height(24) 626 .fillColor(Color.White) 627 .onTouch(this.subtractTouched.bind(this)) 628 .gesture( 629 GestureGroup( 630 GestureMode.Parallel, 631 LongPressGesture({ repeat: true }) 632 .onAction(this.subtractLongOnAction.bind(this)) 633 .onActionEnd(this.subtractLongOnActionEnd.bind(this)) 634 ) 635 ) 636 }.width('100%').height(this.notTakeVideoExtCanvasHeight).padding({ top: 58, bottom: 58 }) 637 } else { 638 Canvas(this.foldCanvasCxt) 639 .width(this.canvasWidth) 640 .height(this.foldCanvasHeight) 641 .onReady(() => this.canvasInit(SHOW_FOLD_CANVAS)) 642 .gesture( 643 GestureGroup( 644 GestureMode.Parallel, 645 LongPressGesture({ repeat: true }) 646 .onAction(this.lpgOnAction.bind(this)) 647 .onActionEnd(this.lpgOnActionEnd.bind(this)), 648 PanGesture({ fingers: 1, distance: 1, direction: PanDirection.Vertical }) 649 .onActionStart(this.pgOnActionStart.bind(this)) 650 .onActionUpdate(this.pgOnActionUpdate.bind(this)) 651 .onActionEnd(this.pgOnActionEnd.bind(this)) 652 ) 653 ) 654 } 655 }.width(82).height('100%') 656 } 657}