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