import { ActionType, Position, RectPosition } from './RectCropView'; @ComponentV2 export struct SelectBoundsView { private settings: RenderingContextSettings = new RenderingContextSettings(true); private canvasContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); private actionType: ActionType = ActionType.move; private touchPosition: Position = { x: 0, y: 0 }; private sw: number = 0; //图片展示框固定宽度 private sh: number = 0; //图片展示框固定高度 @Param onRectChange?: (rect: RectPosition) => void = undefined @Param onClose?: () => void = undefined @Local clipRect: RectPosition = { x: 0, y: 0, width: 80, height: 40 }; @Local initPosition: Position = { x: 0, y: 0 } @Local fontSize: number = 15 build() { Stack() { Stack() .position({ x: this.clipRect.x, y: this.clipRect.y }) .width(this.clipRect.width) .height(this.clipRect.height) .blur(20) .id('mosaic') Image($r('app.media.ic_right_bottom_rect')) .position({ x: this.clipRect.x + this.clipRect.width - 9, y: this.clipRect.y + this.clipRect.height - 9 }) .width(15) .height(15) // 裁剪框 Canvas(this.canvasContext) .position({ x: this.clipRect.x, y: this.clipRect.y }) .width(this.clipRect.width) .height(this.clipRect.height) .onReady(() => { this.drawClipImage() }) .onTouch(event => { if (event.type === TouchType.Down) { this.isMove(event.target.area, event.touches[0]); this.touchPosition = { x: event.touches[0].screenX, y: event.touches[0].screenY } } else if (event.type === TouchType.Move) { let moveX = event.changedTouches[0].screenX - this.touchPosition.x; let moveY = event.changedTouches[0].screenY - this.touchPosition.y; this.touchPosition = { x: event.changedTouches[0].screenX, y: event.changedTouches[0].screenY } this.moveClipCanvas(moveX, moveY); } }) Image($r('app.media.ic_left_top_rect')) .position({ x: this.clipRect.x - 7, y: this.clipRect.y - 7 }) .width(16) .height(16) .onClick(() => { if (this.onClose) { this.onClose() } }) } .width('100%') .height('100%') .onAreaChange((_oldArea, newArea) => { this.sw = newArea.width as number this.sh = newArea.height as number if (this.onRectChange) { this.onRectChange(this.clipRect) } }) } // 绘制裁剪框 drawClipImage() { this.canvasContext.clearRect(0, 0, this.clipRect.width, this.clipRect.height); this.canvasContext.lineWidth = 2 this.canvasContext.strokeStyle = Color.White this.canvasContext.beginPath() this.canvasContext.rect(0, 0, this.clipRect.width, this.clipRect.height) this.canvasContext.stroke() } // 裁剪框位置和大小变化 初始位置为图片的初始坐标 移动的坐标 moveClipCanvas(moveX: number, moveY: number) { let clipRect: RectPosition = { x: this.clipRect.x, y: this.clipRect.y, width: this.clipRect.width, height: this.clipRect.height } switch (this.actionType) { case ActionType.move: clipRect.x += moveX; clipRect.y += moveY; break; case ActionType.topLeft: clipRect.x += moveX; clipRect.y += moveY; clipRect.width += -moveX; clipRect.height += -moveY; break; case ActionType.topRight: clipRect.y += moveY; clipRect.width += moveX; clipRect.height += -moveY; break; case ActionType.bottomLeft: clipRect.x += moveX; clipRect.width += -moveX; clipRect.height += moveY; break; case ActionType.bottomRight: clipRect.width += moveX; clipRect.height += moveY; break; default: break; } // 偏移坐标小于初始位置 if (clipRect.x < this.initPosition.x) { clipRect.x = this.initPosition.x; } if (clipRect.y < this.initPosition.y) { clipRect.y = this.initPosition.y; } // 横坐标限制位置 if (clipRect.width + clipRect.x > this.sw + this.initPosition.x) { if (this.actionType === ActionType.move) { clipRect.x = this.sw + this.initPosition.x - clipRect.width; } else { clipRect.width = this.sw + this.initPosition.x - clipRect.x; } } // 纵坐标限制 if (clipRect.height + clipRect.y > this.sh + this.initPosition.y) { if (this.actionType === ActionType.move) { clipRect.y = this.sh + this.initPosition.y - clipRect.height; } else { clipRect.height = this.sh + this.initPosition.y - clipRect.y; } } //裁剪框位置大小 this.clipRect = { x: Math.round(clipRect.x), y: Math.round(clipRect.y), width: Math.max(Math.round(clipRect.width), 80), height: Math.max(Math.round(clipRect.height), 40) }; if (this.onRectChange) { this.onRectChange(this.clipRect) } } // 判断操作类型 isMove(area: Area, touch: TouchObject) { if (touch.x < 30 && touch.y < 30) { // 左上角 this.actionType = ActionType.topLeft } else if (touch.x < 30 && touch.y > (Number(area.height) - 30)) { // 左下 this.actionType = ActionType.bottomLeft } else if (touch.x > Number(area.width) - 30 && touch.y < 30) { // 右上 this.actionType = ActionType.topRight } else if (touch.x > Number(area.width) - 30 && touch.y > (Number(area.height) - 30)) { // 右下 this.actionType = ActionType.bottomRight } else { this.actionType = ActionType.move } } }