因爲這個是我的項目代碼,所以代碼複製過去也用不了,只是給各位做個參考。
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>