From f26f29d84e0a68831a6af14dab3eec5500496d2e Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期三, 28 五月 2025 16:48:52 +0800
Subject: [PATCH] 初始化项目

---
 uview-ui/components/u-avatar-cropper/u-avatar-cropper.vue |  290 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 290 insertions(+), 0 deletions(-)

diff --git a/uview-ui/components/u-avatar-cropper/u-avatar-cropper.vue b/uview-ui/components/u-avatar-cropper/u-avatar-cropper.vue
new file mode 100644
index 0000000..a48dd54
--- /dev/null
+++ b/uview-ui/components/u-avatar-cropper/u-avatar-cropper.vue
@@ -0,0 +1,290 @@
+<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, backgroundColor: 'rgba(0, 0, 0, 0.8)' }"
+				canvas-id="cropper"
+				id="cropper"
+			></canvas>
+			<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 './weCropper.js';
+export default {
+	props: {
+		// 瑁佸壀鐭╁舰妗嗙殑鏍峰紡锛屽叾涓彲鍖呭惈鐨勫睘鎬т负lineWidth-杈规瀹藉害(鍗曚綅rpx)锛宑olor: 杈规棰滆壊锛�
+		// mask-閬僵棰滆壊锛屼竴鑸缃负涓�涓猺gba鐨勯�忔槑搴︼紝濡�"rgba(0, 0, 0, 0.35)"
+		boundStyle: {
+			type: Object,
+			default() {
+				return {
+					lineWidth: 4,
+					borderColor: 'rgb(245, 245, 245)',
+					mask: 'rgba(0, 0, 0, 0.35)'
+				};
+			}
+		}
+		// // 瑁佸壀妗嗗搴︼紝鍗曚綅rpx
+		// rectWidth: {
+		// 	type: [String, Number],
+		// 	default: 400
+		// },
+		// // 瑁佸壀妗嗛珮搴︼紝鍗曚綅rpx
+		// rectHeight: {
+		// 	type: [String, Number],
+		// 	default: 400
+		// },
+		// // 杈撳嚭鍥剧墖瀹藉害锛屽崟浣峳px
+		// destWidth: {
+		// 	type: [String, Number],
+		// 	default: 400
+		// },
+		// // 杈撳嚭鍥剧墖楂樺害锛屽崟浣峳px
+		// destHeight: {
+		// 	type: [String, Number],
+		// 	default: 400
+		// },
+		// // 杈撳嚭鐨勫浘鐗囩被鍨嬶紝濡傛灉鍙戠幇瑁佸壀鐨勫浘鐗囧緢澶э紝鍙兘鏄洜涓鸿缃负浜�"png"锛屾敼鎴�"jpg"鍗冲彲
+		// fileType: {
+		// 	type: String,
+		// 	default: 'jpg',
+		// },
+		// // 鐢熸垚鐨勫浘鐗囪川閲�
+		// // H5涓婃棤鏁堬紝鐩墠涓嶈�冭檻浣跨敤姝ゅ弬鏁�
+		// quality: {
+		// 	type: [Number, String],
+		// 	default: 1
+		// }
+	},
+	data() {
+		return {
+			// 搴曢儴瀵艰埅鐨勯珮搴�
+			bottomNavHeight: 50,
+			originWidth: 200,
+			width: 0,
+			height: 0,
+			cropperOpt: {
+				id: 'cropper',
+				targetId: 'targetCropper',
+				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),
+					mask: this.boundStyle.mask,
+					color: this.boundStyle.borderColor
+				}
+			},
+			// 瑁佸壀妗嗗拰杈撳嚭鍥剧墖鐨勫昂瀵革紝楂樺害榛樿绛変簬瀹藉害
+			// 杈撳嚭鍥剧墖瀹藉害锛屽崟浣峱x
+			destWidth: 200,
+			// 瑁佸壀妗嗗搴︼紝鍗曚綅px
+			rectWidth: 200,
+			// 杈撳嚭鐨勫浘鐗囩被鍨嬶紝濡傛灉'png'绫诲瀷鍙戠幇瑁佸壀鐨勫浘鐗囧お澶э紝鏀规垚"jpg"鍗冲彲
+			fileType: 'jpg',
+			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 = 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 = option.rectWidth;
+		if (option.fileType) this.fileType = option.fileType;
+		// 鍒濆鍖�
+		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
+			});
+		// 璁剧疆瀵艰埅鏍忔牱寮忥紝浠ュ厤鐢ㄦ埛鍦╬age.json涓病鏈夎缃负榛戣壊鑳屾櫙
+		uni.setNavigationBarColor({
+			frontColor: '#ffffff',
+			backgroundColor: '#000000'
+		});
+		uni.chooseImage({
+			count: 1, // 榛樿9
+			sizeType: ['compressed'], // 鍙互鎸囧畾鏄師鍥捐繕鏄帇缂╁浘锛岄粯璁や簩鑰呴兘鏈�
+			sourceType: ['album', 'camera'], // 鍙互鎸囧畾鏉ユ簮鏄浉鍐岃繕鏄浉鏈猴紝榛樿浜岃�呴兘鏈�
+			success: res => {
+				this.src = res.tempFilePaths[0];
+				//  鑾峰彇瑁佸壀鍥剧墖璧勬簮鍚庯紝缁檇ata娣诲姞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.$u.toast('璇峰厛閫夋嫨鍥剧墖鍐嶈鍓�');
+
+			let cropper_opt = {
+				destHeight: Number(this.destWidth), // uni.canvasToTempFilePath瑕佹眰杩欎簺鍙傛暟涓烘暟鍊�
+				destWidth: Number(this.destWidth),
+				fileType: this.fileType
+			};
+			this.cropper.getCropperImage(cropper_opt, (path, err) => {
+				if (err) {
+					uni.showModal({
+						title: '娓╅Θ鎻愮ず',
+						content: err.message
+					});
+				} else {
+					if (isPre) {
+						uni.previewImage({
+							current: '', // 褰撳墠鏄剧ず鍥剧墖鐨� http 閾炬帴
+							urls: [path] // 闇�瑕侀瑙堢殑鍥剧墖 http 閾炬帴鍒楄〃
+						});
+					} else {
+						uni.$emit('uAvatarCropper', path);
+						this.$u.route({
+							type: 'back'
+						});
+					}
+				}
+			});
+		},
+		uploadTap() {
+			const self = this;
+			uni.chooseImage({
+				count: 1, // 榛樿9
+				sizeType: ['original', 'compressed'], // 鍙互鎸囧畾鏄師鍥捐繕鏄帇缂╁浘锛岄粯璁や簩鑰呴兘鏈�
+				sourceType: ['album', 'camera'], // 鍙互鎸囧畾鏉ユ簮鏄浉鍐岃繕鏄浉鏈猴紝榛樿浜岃�呴兘鏈�
+				success: (res) => {
+					self.src = res.tempFilePaths[0];
+					//  鑾峰彇瑁佸壀鍥剧墖璧勬簮鍚庯紝缁檇ata娣诲姞src灞炴�у強鍏跺��
+
+					self.cropper.pushOrign(this.src);
+				}
+			});
+		}
+	}
+};
+</script>
+
+<style scoped lang="scss">
+@import '../../libs/css/style.components.scss';
+
+.content {
+	background: rgba(255, 255, 255, 1);
+}
+
+.cropper {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	z-index: 11;
+}
+
+.cropper-buttons {
+	background-color: #000000;
+	color: #eee;
+}
+
+.cropper-wrapper {
+	position: relative;
+	@include vue-flex;
+	flex-direction: row;
+	justify-content: space-between;
+	align-items: center;
+	width: 100%;
+	background-color: #000;
+}
+
+.cropper-buttons {
+	width: 100vw;
+	@include vue-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 {
+	width: 50%;
+	text-align: center;
+}
+
+.cropper-buttons .upload {
+	text-align: left;
+	padding-left: 50rpx;
+}
+
+.cropper-buttons .getCropperImage {
+	text-align: right;
+	padding-right: 50rpx;
+}
+</style>

--
Gitblit v1.9.3