vue項目中使用canvas,設置canvas背景圖,疊加圖片,實現鼠標拖動 , 截圖保存等功能

因爲這個是我的項目代碼,所以代碼複製過去也用不了,只是給各位做個參考。

canvas背景圖,鼠標拖動圖片,獲取圖片在canvas的位置,截圖保存等功能

<template>
	<div>
		<div class="clearfix">
			<div class="leftdiv">
				<canvas id="mycanvas" width="600" height="820" @mousedown="touchmove" @mousemove="move" @mouseleave="leave" @mouseup="up" ref="canvas"></canvas>
				<img :src="bgimg" id="bgimg" ref="bgimg" />
				<img src="@/assets/images/zang.png" id="img" ref="img" />
				<div id="testdiv"></div>
			</div>
			<div class="rightdiv">
				<p style="color: #00BCD4;font-weight: 700;font-size: 20px;text-align: left;margin-bottom: 20px;">印章簽署信息</p>
				<el-form :label-position="labelPosition" label-width="150px" :model="formLabelAlign" :rules="rules">
					<el-form-item label="類型" prop="type">
						<el-radio-group v-model="formLabelAlign.type">
							<el-radio :label="0" value="0">個人</el-radio>
							<el-radio :label="1" value="1">企業</el-radio>
						</el-radio-group>
					</el-form-item>
					<el-form-item label="企業印章ID">
						<el-select v-model="region" @change="changeSelect">
							<el-option v-for="(item,index) in seallist" :key="index" :label="item.name" :value="item.id"></el-option>
						</el-select>
					</el-form-item>
					<el-form-item label="頁碼信息">
						<el-select v-model="formLabelAlign.pos_page"  @change="changePage">
							<el-option v-for="(item,index) in pagelist" :key="index"  :label="item" :value="index+1"></el-option>
						</el-select>
					</el-form-item>
					<el-form-item label="X軸座標">
						<el-input v-model="formLabelAlign.pos_x" onkeyup="this.value=this.value.replace(/[^\d.]/g,'');"></el-input>
						<p style="font-size: 12px;text-align: left;"><span style="color: #ccc;">印章寬度 :</span> {{sealwidth}}</p>
					</el-form-item>
					<el-form-item label="Y軸座標">
						<el-input v-model="formLabelAlign.pos" onkeyup="this.value=this.value.replace(/[^\d.]/g,'');"></el-input>
						<p style="font-size: 12px;text-align: left;"><span style="color: #ccc;">印章高度 :</span> {{sealheight}}</p>
					</el-form-item>
					<el-form-item label="簽署區順序">
						<el-input v-model="formLabelAlign.signSort" onkeyup="this.value=this.value.replace(/[^\d.]/g,'');"></el-input>
					</el-form-item>
					<el-form-item label="是否添加簽署時間戳">
						<el-select v-model="formLabelAlign.add_sign_time">
							<el-option label="是" value="0"></el-option>
							<el-option label="否" value="1"></el-option>
						</el-select>
					</el-form-item>
					<el-form-item label="第三方業務流水號">
						<el-input v-model="formLabelAlign.third_order_no" placeholder="請輸入業務流水號"></el-input>
					</el-form-item>
				</el-form>
				<el-button type="primary" @click="onSubmit">編輯印章區域</el-button>
			</div>
		</div>
	</div>
</template>
<script>
	import http from "../../config/http";
	export default {
		data() {
			return {
				region:'',
				ismove: false,
				selectVal:'',
				seallist:[],
				bgimg:require('@/assets/images/1589190467(1).jpg'),
				labelPosition: 'right',
				formLabelAlign: {
					type: 0,
					reigon: '',
					pos_page: '1',
					pos_x: '',
					pos: '',
					signSort: '1',
					add_sign_time: '1',
					third_order_no: '',
					width: '',
					height: ''
				},
				rules: {
					type: [{
						required: true,
						message: '請選擇類型',
						trigger: 'blur'
					}],
				},
				// 印章大小
				sealwidth: 120,  //選擇印章的時候 獲取大小
				sealheight: 120,
				// 印章位置
				OssUrl : JSON.parse(sessionStorage.getItem("state")).OssUrl,
				// 印章列表數據
				res_seal:{},
				//當前左側canvas要顯示的印章數據
				now_seal:{},
				//頁碼
				pagelist:[],
				//切換左側背景圖的資源
				imgData:[]
			};
		},
		components: {},

		computed: {},
		
		created() {
			http.post({
				url: 'contract_template/read',
				// data: {id:this.$route.query.id},
				data: {id:54},
			}).then(res => {
				console.log('IDres',res)
				let a = res.data[0].images.split(',');
				
				this.imgData = [];
				for(let i in a){
					this.pagelist.push( Number(i)+1)   //獲取頁碼
					this.imgData.push( this.OssUrl + '/' + a[i])
				}
				
				this.bgimg = `${this.OssUrl}/${a[0]}`
				let img = new Image();
				img.src = this.bgimg;
				img.id = 'testimg';
				img.style.display = 'none';
				document.getElementById('testdiv').innerHTML = '';
				document.getElementById('testdiv').append(img);
				let that = this;
				setTimeout(function(){
					that.canvas()
				},300)
			})
			
			if(this.$route.query.template_id != undefined){
				//url上有模版ID ---- 編輯狀態
				http.post({
					url: 'contract_template_sign_field/read',
					data: {template_id:this.$route.template_id,id:this.$route.query.id},
				}).then(res => {
					console.log("編輯RES",res)
					this.formLabelAlign = {
						type: 0, //缺少這條數據,峯哥說後臺暫時不保存這條
						// reigon: res.data[0].seal_id,
						reigon: "05f96838-04e3-40a5-89b7-d68b178c2d68",
						pos_page: res.data[0].pos_page,
						pos_x:  res.data[0].pos_x,
						pos:  res.data[0].pos,
						signSort: res.data[0].order,
						add_sign_time: res.data[0].add_sign_time,
						third_order_no: res.data[0].third_order_no,
					}
				})
			}
				
			// 獲取印章ID
			http.post({
				url: 'contract_seal/read',
				data:{}
			}).then(res2 => {
				console.log('印章',res2)
				this.res_seal = res2.data;
				for(let i in res2.data){
					this.seallist.push({name: res2.data[i].alias, id:res2.data[i].seal_id,width:res2.data[i].width,height:res2.data[i].height})
				}
				this.now_seal = '';
				for(let i in res2.data){
					if(this.formLabelAlign.reigon == res2.data[i].seal_id){
						this.selectVal = this.region = res2.data[i].seal_id
						this.formLabelAlign.width =  res2.data[i].width;
						this.formLabelAlign.height =  res2.data[i].height;
						
						this.now_seal = res2.data[i];
					}
				}
				var that = this;
				setTimeout(function(){
					if(that.$route.query.template_id){
						that.setImg(that.formLabelAlign.pos_x ,that.formLabelAlign.pos)
					}
				},2000)
			})
		},
		mounted() {
			
		},
		methods: {
			onSubmit() {
				this.formLabelAlign.reigon = this.region;
				console.log(this.formLabelAlign)
				
				http.post({
					url: 'contract_template_sign_field/save',
					data: this.formLabelAlign,
				}).then(res => {
					console.log("res",res)
				})
			},
			canvas() {
				//  獲取canvas
				var canvas = this.$refs.canvas;
				if (!canvas) {
					return false;
				} else {
					// 設置canvas的背景圖
					var context = canvas.getContext("2d");
					var width = canvas.width; //使圖片大笑與畫布大小一致
					var height = canvas.height; //使圖片大笑與畫布大小一致
					// var bgimg = this.$refs.bgimg;
					var bgimg = document.getElementById('testimg');
					bgimg.style.width = width;
					bgimg.style.height = height;
					var pattern =  context.createPattern(bgimg,"no-repeat");
					context.fillStyle= pattern;
					context.fillRect(0,0,width,height);
				}

			},
			//控制鼠標拖動,並確保不會出canvas範圍
			touchmove(e) {
				this.ismove = true;
			},
			move(e) {
				var canvas = this.$refs.canvas;
				var context = canvas.getContext("2d");
				var width = canvas.width;
				var height = canvas.height;
				if (this.ismove === true && this.selectVal !== '' && e.layerX > this.sealwidth / 2 && e.layerY > this.sealheight / 2 && e.layerX < (width - this.sealwidth/2) && e.layerY < height - this.sealheight/2) {
					context.clearRect(0, 0, width, height);
					this.canvas(); //背景圖
					let a = e.layerX - this.sealwidth / 2;
					let b = e.layerY - this.sealheight / 2;
					this.setImg(a,b); //印章
					
					//以印章左下角到整個canvas左下角的距離爲標準
					this.formLabelAlign.pos_x = e.layerX ;
					this.formLabelAlign.pos = height - e.layerY;
				}
			},
			leave() {
				this.ismove = false
			},
			up() {
				this.ismove = false;
			},
			
			
			//截圖功能
			// 現在我這裏的圖片是從oss服務器獲取的 跨域截圖是不被允許的 所以用不了(如果你不需要從oss服務器獲取圖片,那隨便用)
			// 網上有一些解決跨域截圖的方式,我就沒嘗試了,因爲這個功能並不在需求裏,只是之前做demo弄來玩的
			// getImg(){
			// 	var canvas = this.$refs.canvas;
			// 	var context = canvas.getContext("2d");
			// 	// 截圖功能 把整個canvas截圖
			// 	var image = new Image();
			// 	image.src = canvas.toDataURL("image/png");							
			// 	var test = document.getElementById("test");
			// 	test.appendChild(image)
			// 	console.log("image",image.src)
			// },
			changePage(val){
				console.log(val);
				let img = document.getElementById('testimg');
				let bgimg = this.imgData[Number(val)-1]
				img.src = bgimg;
				
				var that = this;
				setTimeout(function(){
					// console.log(that.formLabelAlign.pos_x,that.formLabelAlign.pos)
					
					if(that.$route.query.template_id || that.now_seal){
						that.setImg(that.formLabelAlign.pos_x ,that.formLabelAlign.pos)
					}
					that.canvas();
				},1000)
				
			},
			changeSelect(val){
				if(val){
					this.selectVal = val;  //當前選擇的這個印章的id
					//選擇時加載對應章 顯示在canvas
					for(let i in this.res_seal){
						if(val == this.res_seal[i].seal_id){
							this.now_seal = this.res_seal[i]
							console.log('當前印章',this.res_seal[i])
							this.sealwidth = this.res_seal[i].width;
							this.sealheight = this.res_seal[i].height
							
							this.setImg(0,0);
						}
					}
					
				}
			},
			setImg(X,Y){
				var canvas = this.$refs.canvas;
				var context = canvas.getContext("2d");
				this.canvas(); 
				let a = this.sealwidth;
				let b = this.sealheight;
				//  加載圖片
				var img = this.$refs.img;
				img.src = this.OssUrl + '/' + this.now_seal.url;
				img.onload = function() {
					// console.log(img)
					//  繪製圖片
					context.drawImage(img, X, Y, a, b);
				};
				img.onload();
			}
		}
	};
</script>
<style lang='scss' scoped>
	.leftdiv {
		padding-top: 20px;
		float: left;
		width: 50%;
		height: 880px;
		box-sizing: border-box;
		background-color: #fff;
		/* border-right: 1px solid #ccc; */
	}

	.rightdiv {
		float: left;
		padding: 15px;
		height: 880px;
		width: 50%;
		box-sizing: border-box;
		background-color: #fff;
	}

	.el-select {
		float: left;
		width: 100%;
	}

	#mycanvas {
		border: 1px solid rgb(199, 198, 198);
	}

	#img,
	#bgimg {
		display: none;
	}
</style>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章