<template>
	<view class="content">
		<view class="cropper-wrapper" :style="{ height: cropperOpt.height + 'px' }">
			<canvas
				class="cropper"
				:disable-scroll="true"
				@touchstart="touchStart"
				@touchmove="touchMove"
				@touchend="touchEnd"
				:style="{ width: cropperOpt.width, height: cropperOpt.height }"
				canvas-id="cropper"
				id="cropper"
			></canvas>
			<view class="cropper-circle-mask" v-show="circularCrop" :style="{
				left: `${cropperOpt.cut.x}px`,
				top: `${cropperOpt.cut.y}px`,
				width: `${cropperOpt.cut.width}px`,
				height: `${cropperOpt.cut.height}px`,
				zIndex: 100
			}"></view>
			<canvas
				class="cropper"
				:disable-scroll="true"
				:style="{
					position: 'fixed',
					top: `-${cropperOpt.width * cropperOpt.pixelRatio}px`,
					left: `-${cropperOpt.height * cropperOpt.pixelRatio}px`,
					width: `${cropperOpt.width * cropperOpt.pixelRatio}px`,
					height: `${cropperOpt.height * cropperOpt.pixelRatio}`,
					
				}"
				canvas-id="targetId"
				id="targetId"
			></canvas>
		</view>
		<view class="cropper-buttons safe-area-padding" :style="{ height: bottomNavHeight + 'px' }">
			<!-- #ifdef H5 -->
			<view class="upload" @tap="uploadTap">选择图片</view>
			<!-- #endif -->
			<!-- #ifndef H5 -->
			<view class="upload" @tap="uploadTap">重新选择</view>
			<!-- #endif -->
			<view class="getCropperImage" @tap="getCropperImage(false)">确定</view>
		</view>
	</view>
</template>
 
<script>
import WeCropper from '@/utils/weCropper.js';
export default {
	props: {
		// 裁剪矩形框的样式，其中可包含的属性为lineWidth-边框宽度(单位rpx)，color: 边框颜色，
		// mask-遮罩颜色，一般设置为一个rgba的透明度，如"rgba(0, 0, 0, 0.35)"
		boundStyle: {
			type: Object,
			default() {
				return {
					lineWidth: 4,
					borderColor: 'rgb(245, 245, 245)'
				};
			}
		},
		// 是否使用圆形裁剪
		circularCrop: {
			type: Boolean,
			default: true
		}
	},
	data() {
		return {
			// 底部导航的高度
			bottomNavHeight: 150,
			originWidth: 200,
			width: 0,
			height: 0,
			cropper: '',
			cropperOpt: {
				id: 'cropper',
				targetId: 'targetId',
				pixelRatio: 1,
				width: 0,
				height: 0,
				scale: 2.5,
				zoom: 8,
				cut: {
					x: (this.width - this.originWidth) / 2,
					y: (this.height - this.originWidth) / 2,
					width: this.originWidth,
					height: this.originWidth
				},
				boundStyle: {
					lineWidth: uni.upx2px(this.boundStyle.lineWidth)
				}
			},
			// 裁剪框和输出图片的尺寸，高度默认等于宽度
			// 输出图片宽度，单位px
			destWidth: 200,
			// 裁剪框宽度，单位px
			rectWidth: 200,
			// 输出的图片类型，如果'png'类型发现裁剪的图片太大，改成"jpg"即可
			fileType: 'png', // 改为png以支持透明背景
			src: '' // 选择的图片路径，用于在点击确定时，判断是否选择了图片
		};
	},
	onLoad(option) {
		let rectInfo = uni.getSystemInfoSync();
		this.width = rectInfo.windowWidth;
		this.height = rectInfo.windowHeight - this.bottomNavHeight;
		this.cropperOpt.width = this.width;
		this.cropperOpt.height = this.height;
		this.cropperOpt.pixelRatio = rectInfo.pixelRatio;
 
		if (option.destWidth) this.destWidth = Number(option.destWidth);
		if (option.rectWidth) {
			let rectWidth = Number(option.rectWidth);
			this.cropperOpt.cut = {
				x: (this.width - rectWidth) / 2,
				y: (this.height - rectWidth) / 2,
				width: rectWidth,
				height: rectWidth
			};
		}
		this.rectWidth = Number(option.rectWidth);
		if (option.fileType) this.fileType = option.fileType;
		
		// 圆形裁剪需要PNG格式支持透明
		if (this.circularCrop && this.fileType === 'jpg') {
			this.fileType = 'png';
		}
		
		// 设置圆形样式边界
		if (this.circularCrop) {
			this.cropperOpt.boundStyle.isCircle = true;
		}
		
		// 初始化
		this.cropper = new WeCropper(this.cropperOpt)
			.on('ready', ctx => {
				// wecropper is ready for work!
			})
			.on('beforeImageLoad', ctx => {
				// before picture loaded, i can do something
			})
			.on('imageLoad', ctx => {
				// picture loaded
			})
			.on('beforeDraw', (ctx, instance) => {
				// before canvas draw,i can do something
			});
		// 设置导航栏样式，以免用户在page.json中没有设置为黑色背景
		uni.setNavigationBarColor({
			frontColor: '#ffffff',
			backgroundColor: '#000000'
		});
		uni.chooseImage({
			count: 1, // 默认9
			sizeType: ['compressed'], // 可以指定是原图还是压缩图，默认二者都有
			sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机，默认二者都有
			success: res => {
				this.src = res.tempFilePaths[0];
				//  获取裁剪图片资源后，给data添加src属性及其值
				this.cropper.pushOrign(this.src);
			}
		});
	},
	methods: {
		touchStart(e) {
			this.cropper.touchStart(e);
		},
		touchMove(e) {
			this.cropper.touchMove(e);
		},
		touchEnd(e) {
			this.cropper.touchEnd(e);
		},
		getCropperImage(isPre = false) {
			if (!this.src) return this.$toast('请先选择图片再裁剪');
			
			// 如果是圆形裁剪，使用与 directCircleCrop 相同的方法
			if (this.circularCrop) {
				// 使用最简单直接的方式裁剪
				const size = 300;
				
				// 1. 先使用weCropper获取矩形裁剪图片
				const options = {
					destWidth: size,
					destHeight: size,
					fileType: 'png'
				};
				
				this.cropper.getCropperImage(options, (rectPath, err) => {
					if (err) {
						console.error('矩形裁剪失败:', err);
						return;
					}
					
					console.log('矩形裁剪成功，路径:', rectPath);
					
					// 2. 创建新画布进行圆形裁剪
					const ctx = uni.createCanvasContext('targetId');
					
					// 先清空画布
					ctx.clearRect(0, 0, size, size);
					
					// 设置背景为透明
					ctx.setFillStyle('rgba(0,0,0,0)');
					ctx.fillRect(0, 0, size, size);
					
					// 创建圆形裁剪区域
					ctx.save();
					ctx.beginPath();
					ctx.arc(size/2, size/2, size/2, 0, 2 * Math.PI);
					ctx.clip();
					
					// 绘制图片到圆形区域
					ctx.drawImage(rectPath, 0, 0, size, size);
					ctx.restore();
					
					// 绘制并导出
					ctx.draw(false, () => {
						setTimeout(() => {
							uni.canvasToTempFilePath({
								canvasId: 'targetId',
								x: 0,
								y: 0,
								width: size,
								height: size,
								destWidth: size,
								destHeight: size,
								fileType: 'png',
								backgroundColor: 'transparent',
								success: (res) => {
									console.log('圆形裁剪成功:', res.tempFilePath);
									if (isPre) {
										uni.previewImage({
											urls: [res.tempFilePath]
										});
									} else {
										uni.$emit('uAvatarCropper', res.tempFilePath);
										uni.navigateBack();
									}
								},
								fail: (err) => {
									console.error('圆形裁剪失败:', err);
									// 失败时使用矩形图片
									if (isPre) {
										uni.previewImage({
											urls: [rectPath]
										});
									} else {
										uni.$emit('uAvatarCropper', rectPath);
										uni.navigateBack();
									}
								}
							});
						}, 300);
					});
				});
				return;
			}
			
			// 原始矩形裁剪方法
			this.useOriginalCrop(isPre);
		},
		
		// 使用原始裁剪方法
		useOriginalCrop(isPre = false) {
			// 确保使用合适的尺寸
			const size = 300; // 增大尺寸
			
			let cropper_opt = {
				destHeight: size,
				destWidth: size,
				fileType: this.fileType
			};
			
			console.log('使用原始裁剪方法，参数:', cropper_opt);
			
			try {
				this.cropper.getCropperImage(cropper_opt, (path, err) => {
					console.log('裁剪回调被调用', path, err);
					if (err) {
						console.error('裁剪出错:', err);
						uni.showModal({
							title: '温馨提示',
							content: err.message
						});
					} else {
						console.log('裁剪成功，路径:', path);
						
						if (isPre) {
							console.log('预览图片');
							uni.previewImage({
								current: '', // 当前显示图片的 http 链接
								urls: [path] // 需要预览的图片 http 链接列表
							});
						} else {
							console.log('返回上一页');
							uni.$emit('uAvatarCropper', path);
							uni.navigateBack();
						}
					}
				});
			} catch (error) {
				console.error('调用 getCropperImage 出错:', error);
				uni.showModal({
					title: '裁剪出错',
					content: error.message || '未知错误'
				});
			}
		},
		uploadTap() {
			const self = this;
			uni.chooseImage({
				count: 1, // 默认9
				sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图，默认二者都有
				sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机，默认二者都有
				success: res => {
					self.src = res.tempFilePaths[0];
					//  获取裁剪图片资源后，给data添加src属性及其值
 
					self.cropper.pushOrign(this.src);
				}
			});
		},
	}
};
</script>
 
<style scoped lang="scss">
.content {
	background: rgba(255, 255, 255, 1);
}
 
.cropper {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	z-index: 11;
}

.cropper-circle-mask {
	position: absolute;
	border-radius: 50%;
	box-shadow: 0 0 0 999px rgba(0, 0, 0, 0.35);
	z-index: 12;
	pointer-events: none; /* Allow touches to pass through to the canvas underneath */
	box-sizing: border-box;
}
 
.cropper-buttons {
	background-color: #000000;
	color: #eee;
}
 
.cropper-wrapper {
	position: relative;
	display: flex;
	flex-direction: row;
	justify-content: space-between;
	align-items: center;
	width: 100%;
	background-color: #000;
}
 
.cropper-buttons {
	width: 100vw;
	display: flex;
	flex-direction: row;
	justify-content: space-between;
	align-items: center;
	position: fixed;
	bottom: 0;
	left: 0;
	font-size: 28rpx;
}
 
.cropper-buttons .upload,
.cropper-buttons .getCropperImage,
.cropper-buttons .test,
.cropper-buttons .test2,
.cropper-buttons .test3,
.cropper-buttons .test4 {
	width: 16.6%;
	text-align: center;
}
 
.cropper-buttons .upload {
	text-align: left;
	padding-left: 50rpx;
}

.cropper-buttons .test {
	color: #ffeb3b;
}

.cropper-buttons .test2 {
	color: #4caf50;
}

.cropper-buttons .test3 {
	color: #ff9800;
}

.cropper-buttons .test4 {
	color: #e91e63;
}
 
.cropper-buttons .getCropperImage {
	text-align: right;
	padding-right: 50rpx;
}
</style>