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