2025-07-03 13:14:39 +08:00

197 lines
7.6 KiB
JavaScript

Page({
data: {
frameX: 100, // canvas 左上角 X 坐标
frameY: 100, // canvas 左上角 Y 坐标
frameWidth: 200, // canvas 宽度
frameHeight: 200, // canvas 高度
isDragging: false, // 是否正在拖拽
startX: 0, // 触摸起始 X 坐标
startY: 0, // 触摸起始 Y 坐标
startFrameX: 0, // 拖拽前 canvas 的 X 坐标
startFrameY: 0, // 拖拽前 canvas 的 Y 坐标
canvasWidth: wx.getSystemInfoSync().windowWidth, // 屏幕宽度
canvasHeight: wx.getSystemInfoSync().windowHeight, // 屏幕高度
cameraX: 0, // camera 左上角 X 坐标
cameraY: 0, // camera 左上角 Y 坐标
cameraWidth: wx.getSystemInfoSync().windowWidth, // camera 宽度
cameraHeight: wx.getSystemInfoSync().windowHeight, // camera 高度
isResizing: false, // 是否正在调整大小
resizeCorner: '', // 调整大小的角
startCameraWidth: 0, // 调整大小前 camera 的宽度
startCameraHeight: 0 // 调整大小前 camera 的高度
},
onReady() {
this.ctx = wx.createCanvasContext('myCanvas');
this.drawCanvas();
},
// 触摸开始事件(调整大小)
onResizeStart(e) {
const { x, y } = e.touches[0];
const corner = e.currentTarget.dataset.corner;
this.setData({
isResizing: true,
resizeCorner: corner,
startX: x,
startY: y,
startCameraWidth: this.data.cameraWidth,
startCameraHeight: this.data.cameraHeight
});
},
// 触摸移动事件(调整大小)
onResizeMove(e) {
if (!this.data.isResizing) return;
const { x, y } = e.touches[0];
const { startX, startY, startCameraWidth, startCameraHeight, cameraX, cameraY, canvasWidth, canvasHeight } = this.data;
const deltaX = x - startX;
const deltaY = y - startY;
let newWidth = startCameraWidth;
let newHeight = startCameraHeight;
let newX = cameraX;
let newY = cameraY;
switch (this.data.resizeCorner) {
case 'tl':
newWidth = Math.max(50, startCameraWidth - deltaX);
newHeight = Math.max(50, startCameraHeight - deltaY);
newX = Math.min(cameraX + deltaX, canvasWidth - 50);
newY = Math.min(cameraY + deltaY, canvasHeight - 50);
break;
case 'tr':
newWidth = Math.max(50, startCameraWidth + deltaX);
newHeight = Math.max(50, startCameraHeight - deltaY);
newY = Math.min(cameraY + deltaY, canvasHeight - 50);
break;
case 'bl':
newWidth = Math.max(50, startCameraWidth - deltaX);
newHeight = Math.max(50, startCameraHeight + deltaY);
newX = Math.min(cameraX + deltaX, canvasWidth - 50);
break;
case 'br':
newWidth = Math.max(50, startCameraWidth + deltaX);
newHeight = Math.max(50, startCameraHeight + deltaY);
break;
}
this.setData({
cameraWidth: newWidth,
cameraHeight: newHeight,
cameraX: newX,
cameraY: newY
});
},
// 触摸结束事件(调整大小)
onResizeEnd() {
this.setData({ isResizing: false });
},
// 绘制 canvas 内容
drawCanvas() {
const { frameWidth, frameHeight } = this.data;
this.ctx.clearRect(0, 0, frameWidth, frameHeight);
this.ctx.setFillStyle('rgba(0, 0, 0, 0.5)');
this.ctx.fillRect(0, 0, frameWidth, frameHeight);
this.ctx.draw();
},
// 触摸开始事件
onTouchStart(e) {
const { x, y } = e.touches[0];
this.setData({
isDragging: true,
startX: x,
startY: y,
startFrameX: this.data.frameX,
startFrameY: this.data.frameY
});
},
// 触摸移动事件
onTouchMove(e) {
if (!this.data.isDragging) return;
const { x, y } = e.touches[0];
const { startX, startY, startFrameX, startFrameY, canvasWidth, canvasHeight, frameWidth, frameHeight } = this.data;
const deltaX = x - startX;
const deltaY = y - startY;
// 计算新的坐标并限制不超出屏幕边界
const newFrameX = Math.max(0, Math.min(startFrameX + deltaX, canvasWidth - frameWidth));
const newFrameY = Math.max(0, Math.min(startFrameY + deltaY, canvasHeight - frameHeight));
this.setData({
frameX: newFrameX,
frameY: newFrameY
});
},
// 触摸结束事件
onTouchEnd() {
this.setData({ isDragging: false });
},
// 拍照方法
takePhoto() {
const ctx = wx.createCameraContext();
const { frameX, frameY, frameWidth, frameHeight } = this.data;
// 调用相机拍照
ctx.takePhoto({
quality: 'high',
success: (res) => {
const tempFilePath = res.tempImagePath;
// 获取图片信息,用于计算比例
wx.getImageInfo({
src: tempFilePath,
success: (imageInfo) => {
const { width: imageWidth, height: imageHeight } = imageInfo;
const { canvasWidth, canvasHeight } = this.data;
// 计算图片与屏幕的比例
const ratioX = imageWidth / canvasWidth;
const ratioY = imageHeight / canvasHeight;
// 计算截取区域的实际坐标和尺寸
const cropX = Math.floor(frameX * ratioX);
const cropY = Math.floor(frameY * ratioY);
const cropWidth = Math.floor(frameWidth * ratioX);
const cropHeight = Math.floor(frameHeight * ratioY);
// 创建临时 canvas 用于裁剪图片
const tempCanvasId = 'tempCanvas';
const tempCtx = wx.createCanvasContext(tempCanvasId);
// 将拍摄的图片绘制到临时 canvas
tempCtx.drawImage(tempFilePath, 0, 0, imageWidth, imageHeight);
tempCtx.draw(false, () => {
// 从临时 canvas 截取指定区域图片
wx.canvasToTempFilePath({
canvasId: tempCanvasId,
x: cropX,
y: cropY,
width: cropWidth,
height: cropHeight,
destWidth: cropWidth,
destHeight: cropHeight,
success: (cropRes) => {
console.log('裁剪后的图片路径:', cropRes.tempFilePath);
},
fail: (err) => {
console.error('裁剪图片失败:', err);
}
});
});
},
fail: (err) => {
console.error('获取图片信息失败:', err);
}
});
},
fail: (err) => {
console.error('拍照失败:', err);
}
});
}
});