Ver Fonte

添加图片裁剪

wgl há 4 anos atrás
pai
commit
0433eee582

+ 1 - 0
package.json

@@ -18,6 +18,7 @@
 		"qrcodejs2": "^0.0.2",
 		"vconsole": "^3.3.4",
 		"vue": "^2.6.11",
+		"vue-cropper": "^0.5.5",
 		"vue-directive-image-previewer": "^2.2.2",
 		"vue-router": "^3.2.0",
 		"vuex": "^3.4.0",

+ 253 - 0
src/components/Cropper.vue

@@ -0,0 +1,253 @@
+<template>
+	<div class="wrapper" v-show="visible">
+		<div class="model" v-show="model" @click="model = false">
+			<div class="model-show">
+				<img :src="modelSrc" alt="">
+			</div>
+		</div>
+		<div class="content">
+			<div class="show-info">
+				<div class="test" :style="'width:'+cwidth+'px;height:'+cheight+'px'">
+					<vueCropper ref="cropper" :img="cropper.img " :outputSize="cropper.size" :outputType="cropper.outputType" :info="cropper.info"
+					 :canScale="cropper.canScale" :autoCrop="cropper.autoCrop" :autoCropWidth="cropper.autoCropWidth" :autoCropHeight="cropper.autoCropHeight"
+					 :fixed="cropper.fixed" :fixedNumber="cropper.fixedNumber" :enlarge="4"></vueCropper>
+				</div>
+				<div style="margin-top: 10px;">
+					<button type="button" @click="cancel" class="mui-btn">取消</button>
+					<button type="button" @click="finish" class="mui-btn" style="float: right;">选取</button>
+				</div>
+				<div style="font-size: 14px;margin-top: 10px;line-height: 20px;color: red;">1.照片用于人脸识别设备,请上传清晰免冠登记照或肩部以上近照。</div>
+				<div style="font-size: 14px;margin-top: 10px;line-height: 20px;color: #888888;">2.可以拖动图片或双手指缩放图片,最好让照片填满马赛克边框。</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+	import {
+		VueCropper
+	} from 'vue-cropper'
+
+	export default {
+		name: 'TopHeader',
+		props: {
+			cropper: {
+				require: true,
+				type: Object,
+				default: () => ({
+					//img的路径自行修改
+					img: '',
+					info: true,
+					size: 0.8,
+					outputType: 'jpeg',
+					canScale: false,
+					autoCrop: true,
+					// 只有自动截图开启 宽度高度才生效
+					autoCropWidth: 250,
+					autoCropHeight: 350,
+					fixed: true,
+					// 真实的输出宽高
+					infoTrue: true,
+					fixedNumber: [5, 7]
+				})
+			},
+			visible: {
+				require: false,
+				default: false,
+			},
+			field: {
+				require: false,
+				default: 'pic'
+			},
+			cwidth: {
+				require: false,
+				default: 250
+			},
+			cheight: {
+				require: false,
+				default: 350
+			},
+		},
+		components: {
+			VueCropper,
+		},
+		created() {},
+		data() {
+			return {
+				model: false,
+				modelSrc: '',
+			}
+		},
+		methods: {
+			//点击裁剪,这一步是可以拿到处理后的地址
+			finish() {
+				this.$refs.cropper.goAutoCrop();
+				this.$refs.cropper.getCropData((data) => {
+					this.modelSrc = data
+					this.model = false;
+					//裁剪后的图片显示
+					this.cropper.img = this.modelSrc;
+					//console.log(data)
+					this.$emit('cropperFinish', {
+						field: this.field,
+						data: data
+					});
+				})
+			},
+			cancel() {
+				this.$emit('cropperCancel');
+			}
+		},
+	}
+</script>
+
+<style scoped>
+	/* * {
+		margin: 0;
+		padding: 0;
+	} */
+
+	.wrapper {
+		position: fixed;
+		width: 100%;
+		top: 0;
+		background: #f1f1f1;
+		z-index: 99;
+		height: 100%;
+	}
+
+	.content {
+		margin: auto;
+		max-width: 585px;
+		margin-bottom: 100px;
+	}
+
+	.test-button {
+		display: flex;
+		flex-wrap: wrap;
+	}
+
+	.btn {
+		display: inline-block;
+		line-height: 1;
+		white-space: nowrap;
+		cursor: pointer;
+		background: #fff;
+		border: 1px solid #c0ccda;
+		color: #1f2d3d;
+		text-align: center;
+		box-sizing: border-box;
+		outline: none;
+		margin: 20px 10px 0px 0px;
+		padding: 9px 15px;
+		font-size: 14px;
+		border-radius: 4px;
+		color: #fff;
+		background-color: #50bfff;
+		border-color: #50bfff;
+		transition: all .2s ease;
+		text-decoration: none;
+		user-select: none;
+	}
+
+	.des {
+		line-height: 30px;
+	}
+
+	code.language-html {
+		padding: 10px 20px;
+		margin: 10px 0px;
+		display: block;
+		background-color: #333;
+		color: #fff;
+		overflow-x: auto;
+		font-family: Consolas, Monaco, Droid, Sans, Mono, Source, Code, Pro, Menlo, Lucida, Sans, Type, Writer, Ubuntu, Mono;
+		border-radius: 5px;
+		white-space: pre;
+	}
+
+	.show-info {
+		margin-bottom: 50px;
+	}
+
+	.show-info h2 {
+		line-height: 50px;
+	}
+
+	.title {
+		display: block;
+		text-decoration: none;
+		text-align: center;
+		line-height: 1.5;
+		margin: 20px 0px;
+		background-image: -webkit-linear-gradient(left, #3498db, #f47920 10%, #d71345 20%, #f7acbc 30%, #ffd400 40%, #3498db 50%, #f47920 60%, #d71345 70%, #f7acbc 80%, #ffd400 90%, #3498db);
+		color: transparent;
+		-webkit-background-clip: text;
+		background-size: 200% 100%;
+		animation: slide 5s infinite linear;
+		font-size: 40px;
+	}
+
+	.test {
+		height: 285px;
+	}
+
+	.model {
+		position: fixed;
+		z-index: 10;
+		width: 100vw;
+		height: 100vh;
+		overflow: auto;
+		top: 0;
+		left: 0;
+		background: rgba(0, 0, 0, 0.8);
+	}
+
+	.model-show {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		width: 100vw;
+		height: 100vh;
+	}
+
+	.model img {
+		display: block;
+		margin: auto;
+		max-width: 80%;
+		user-select: none;
+		background-position: 0px 0px, 10px 10px;
+		background-size: 20px 20px;
+		background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%), linear-gradient(45deg, #eee 25%, white 25%, white 75%, #eee 75%, #eee 100%);
+	}
+
+	.c-item {
+		display: block;
+		padding: 10px 0;
+		user-select: none;
+	}
+
+	@keyframes slide {
+		0% {
+			background-position: 0 0;
+		}
+
+		100% {
+			background-position: -100% 0;
+		}
+	}
+
+	@media screen and (max-width: 1000px) {
+		.content {
+			max-width: 90%;
+			margin: auto;
+		}
+
+		.test {
+			margin-top: 10%;
+			width: 250px;
+			height: 350px;
+			margin: 10% auto 0 auto;
+		}
+	}
+</style>

+ 47 - 3
src/projects/business/views/HouseKeeper/Admin/Person/Add.vue

@@ -36,6 +36,11 @@
 		<div class="fyy-footer">
 			<div class="bindfyy-btn"><button type="button" class="mui-btn mui-btn-primary" @click="submit">下一步</button></div>
 		</div>
+
+		<!--图片裁剪-->
+		<cropper :cwidth="cropperWidth" :cheight="cropperHeight" :visible="cropperVisible" :field="cropperField" :cropper="cropper"
+		 @cropperFinish="cropperFinish" @cropperCancel="cropperCancel"></cropper>
+
 	</div>
 </template>
 
@@ -49,12 +54,14 @@
 	} from 'vuex'
 	import * as WxJsApi from '$project/utils/wxJsApi'
 	import * as types from '$project/store/mutation-types'
+	import Cropper from '$project/components/Cropper.vue'
 	export default {
 		name: 'HouseKeeperAdminPersonAdd',
 		components: {
 			Common,
 			Loading,
-			TopHeader
+			TopHeader,
+			Cropper
 		},
 		data() {
 			return {
@@ -68,6 +75,26 @@
 					faceImageUrl: '',
 					bindDevices: '',
 				},
+
+				cropperVisible: '',
+				cropperField: '',
+				cropperWidth: 250,
+				cropperHeight: 350,
+				cropper: {
+					img: '',
+					info: true,
+					size: 1,
+					outputType: 'jpeg',
+					canScale: false,
+					autoCrop: false,
+					// 只有自动截图开启 宽度高度才生效
+					autoCropWidth: 250,
+					autoCropHeight: 350,
+					fixed: true,
+					// 真实的输出宽高
+					infoTrue: true,
+					fixedNumber: [5, 7]
+				},
 			}
 		},
 		created() {},
@@ -84,12 +111,29 @@
 					localData = localData.replace(/\r|\n/g, '').replace('data:image/jgp', 'data:image/jpeg')
 					this.imgBase64 = localData;
 					//显示裁剪图片
-					//_this.showCropper(field);
-					this.uploadpic();
+					this.showCropper('faceImageUrl');
+					//this.uploadpic();
 				}).catch(error => {
 					mui.toast(error);
 				})
 			},
+			//显示裁剪图片
+			showCropper(field) {
+				this.cropper.img = this.imgBase64;
+				this.cropperField = field;
+				this.cropperVisible = true;
+			},
+			//裁剪图片
+			cropperFinish(obj) {
+				console.log(obj);
+				this.imgBase64 = obj.data;
+				this.uploadpic(obj.field);
+				this.cropperVisible = false;
+			},
+			//隐藏裁剪图片
+			cropperCancel() {
+				this.cropperVisible = false;
+			},
 			//上传图片
 			uploadpic() {
 				this.isLoading = true;

+ 47 - 4
src/projects/business/views/Master/EditInfo.vue

@@ -35,6 +35,10 @@
 		</div>
 
 		<loading :visible="isLoading"></loading>
+		
+		<!--图片裁剪-->
+		<cropper :cwidth="cropperWidth" :cheight="cropperHeight" :visible="cropperVisible" :field="cropperField" :cropper="cropper"
+		 @cropperFinish="cropperFinish" @cropperCancel="cropperCancel"></cropper>
 	</div>
 </template>
 
@@ -49,13 +53,15 @@
 		mapGetters,
 		mapMutations
 	} from 'vuex'
+	import Cropper from '$project/components/Cropper.vue'
 	import * as WxJsApi from '$project/utils/wxJsApi'
 	export default {
 		name: 'MasterEditInfo',
 		components: {
 			Common,
 			Loading,
-			TopHeader
+			TopHeader,
+			Cropper
 		},
 		data() {
 			return {
@@ -72,7 +78,27 @@
 					openId: '',
 				},
 
-				imgBase64: ''
+				imgBase64: '',
+				
+				cropperVisible: '',
+				cropperField: '',
+				cropperWidth: 250,
+				cropperHeight: 350,
+				cropper: {
+					img: '',
+					info: true,
+					size: 1,
+					outputType: 'jpeg',
+					canScale: false,
+					autoCrop: false,
+					// 只有自动截图开启 宽度高度才生效
+					autoCropWidth: 250,
+					autoCropHeight: 350,
+					fixed: true,
+					// 真实的输出宽高
+					infoTrue: true,
+					fixedNumber: [5, 7]
+				},
 			}
 		},
 		created() {
@@ -111,12 +137,29 @@
 					localData = localData.replace(/\r|\n/g, '').replace('data:image/jgp', 'data:image/jpeg')
 					this.imgBase64 = localData;
 					//显示裁剪图片
-					//_this.showCropper(field);
-					this.uploadpic(field);
+					this.showCropper(field);
+					//this.uploadpic(field);
 				}).catch(error => {
 					mui.toast(error);
 				})
 			},
+			//显示裁剪图片
+			showCropper(field) {
+				this.cropper.img = this.imgBase64;
+				this.cropperField = field;
+				this.cropperVisible = true;
+			},
+			//裁剪图片
+			cropperFinish(obj) {
+				console.log(obj);
+				this.imgBase64 = obj.data;
+				this.uploadpic(obj.field);
+				this.cropperVisible = false;
+			},
+			//隐藏裁剪图片
+			cropperCancel() {
+				this.cropperVisible = false;
+			},
 			//上传图片
 			uploadpic(field) {
 				this.isLoading = true;

+ 49 - 4
src/projects/home/views/UploadPhoto.vue

@@ -22,6 +22,11 @@
 		<div class="fyy-footer">
 			<div class="bindfyy-btn"><button type="submit" class="mui-btn mui-btn-primary" @click="submit">提交</button></div>
 		</div>
+
+
+		<!--图片裁剪-->
+		<cropper :cwidth="cropperWidth" :cheight="cropperHeight" :visible="cropperVisible" :field="cropperField" :cropper="cropper"
+		 @cropperFinish="cropperFinish" @cropperCancel="cropperCancel"></cropper>
 	</div>
 </template>
 
@@ -34,13 +39,15 @@
 		mapGetters,
 		mapMutations
 	} from 'vuex'
+	import Cropper from '$project/components/Cropper.vue'
 	import * as WxJsApi from '$project/utils/wxJsApi'
 	export default {
 		name: 'UploadPhoto',
 		components: {
 			Common,
 			Loading,
-			TopHeader
+			TopHeader,
+			Cropper
 		},
 		data() {
 			return {
@@ -53,6 +60,27 @@
 					openId: '',
 					faceImageUrl: ''
 				},
+
+
+				cropperVisible: '',
+				cropperField: '',
+				cropperWidth: 250,
+				cropperHeight: 350,
+				cropper: {
+					img: '',
+					info: true,
+					size: 1,
+					outputType: 'jpeg',
+					canScale: false,
+					autoCrop: false,
+					// 只有自动截图开启 宽度高度才生效
+					autoCropWidth: 250,
+					autoCropHeight: 350,
+					fixed: true,
+					// 真实的输出宽高
+					infoTrue: true,
+					fixedNumber: [5, 7]
+				},
 			}
 		},
 		created() {
@@ -71,12 +99,29 @@
 					localData = localData.replace(/\r|\n/g, '').replace('data:image/jgp', 'data:image/jpeg')
 					this.imgBase64 = localData;
 					//显示裁剪图片
-					//_this.showCropper(field);
-					this.uploadpic();
+					this.showCropper('faceImageUrl');
+					//this.uploadpic();
 				}).catch(error => {
 					mui.toast(error);
 				})
 			},
+			//显示裁剪图片
+			showCropper(field) {
+				this.cropper.img = this.imgBase64;
+				this.cropperField = field;
+				this.cropperVisible = true;
+			},
+			//裁剪图片
+			cropperFinish(obj) {
+				console.log(obj);
+				this.imgBase64 = obj.data;
+				this.uploadpic(obj.field);
+				this.cropperVisible = false;
+			},
+			//隐藏裁剪图片
+			cropperCancel() {
+				this.cropperVisible = false;
+			},
 			//上传图片
 			uploadpic() {
 				this.isLoading = true;
@@ -110,7 +155,7 @@
 					this.isLoading = true;
 					API_Person.save(this.subForm).then(response => {
 						this.isLoading = false;
-						
+
 						//场景之前选过,这里直接去选择角色
 						this.$router.push({
 							name: 'Role',

+ 5 - 0
yarn.lock

@@ -8151,6 +8151,11 @@ vm-browserify@^1.0.1:
   resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
   integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA=
 
+vue-cropper@^0.5.5:
+  version "0.5.5"
+  resolved "https://registry.yarnpkg.com/vue-cropper/-/vue-cropper-0.5.5.tgz#9bd1ba563c7faa268abd52fb2af4c6c28d33c962"
+  integrity sha512-5mGaBlS1EwLxUFwHHX2Q8zOZSiVfBUjOfolR+ZNKwu7Rh3u+GhwHYOyFkgZHhhoQBBNdyVB28O6W+MpMimhCbA==
+
 vue-directive-image-previewer@^2.2.2:
   version "2.2.2"
   resolved "https://registry.npm.taobao.org/vue-directive-image-previewer/download/vue-directive-image-previewer-2.2.2.tgz#56d74e7ab109be9b5fd399a86ff868f2e2ca754a"