material-hmos/entry/src/main/ets/view/SelectBoundsView.ets

201 lines
5.9 KiB
Plaintext

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
}
}
}