!------------------------------------------------------------------------------------------vue
! 若有不太明白的地方,多看看代碼註釋。爲細節地方canvas
<div class="canva" @click="centerDialogVisible = true">
// click綁定的方法是element提供的 centerDialogVisibe=true 是點擊時彈框出現
<img :src="imgsrc" alt=""/> // src = base64 ,下面介紹到
</div>
// div是在父組件中,因此有了下面子傳給父數據
// 而後設置dialog彈框基本樣式
// title爲彈框中頭部出現的名字
// visible.sync 爲click綁定的方法同樣
// width爲整個dialog的寬度
// <sign></sign>是簽名組件,綁定的方法是自定義方法,子傳父,後面會詳細介紹
<el-dialog
title="簽名"
:visible.sync="centerDialogVisible"
width="85%"
center>
<sign @draw_save="getSignImg"></sign>
</el-dialog>
//而後在全局樣式下自定義彈框中默認的內容高度
.el-dialog {
.el-dialog__header{
height: 20px;
}
.el-dialog__body{
height: 400px;
overflow: auto; // 項目中其餘dialog須要滾動條,因此加上就會出現滾動條。簽名可忽略
}
}
.el-dialog__wrapper .el-dialog__title{
font-size: 21px;
}
複製代碼
data(){
return{
imgsrc: '', // base64編碼,保存爲圖片用到
centerDialogVisible: false //dialog彈框顯示 fales不顯示,true顯示
}
}
複製代碼
原文地址是組件下載地址,並無過多介紹 download.csdn.net/download/we…bash
<template>
<div class="sign">
<canvas id="canvas" :width="width" :height="height"></canvas>
<div>
<button type="button" @click="clear" id="clear">清空</button>
<button type="button" @click="save" id="save">保存</button>
</div>
</div>
</template>
<script>
/*
* width canvas 寬度
* height canvas 高度
* strokeStyle 線條顏色
* showUrl 是否顯示預覽圖片
* imgWidth img 寬度
* imgHeight img 高度
* draw_clear //監聽清空事件
* draw_save //監聽保存事件 返回base64 img 路徑
* */
var preHandler = function (e) { e.preventDefault() }
export default {
name: 'drawSign',
props: {
width: {
type: String,
default: '565'
},
height: {
type: String,
default: '355'
},
strokeStyle: {
type: String,
default: '#000'
},
showUrl: {
type: Boolean,
default: true
},
imgWidth: {
type: String,
default: '240'
},
imgHeight: {
type: String,
default: '106'
}
},
data () {
return {
canvas: null, // canvas
ctx: null, // ctx canvas對象
stroke_info: null, // 當前繪圖的座標
url: '' // base64 圖像
}
},
methods: {
init () {
let that = this
this.canvas = document.getElementById('canvas')
this.ctx = this.canvas.getContext('2d')
this.stroke_info = this.canvas.getBoundingClientRect()
this.canvas.addEventListener('touchstart', function (event) {
document.addEventListener('touchStart', preHandler, false)
that.darwStart(event)
})
this.canvas.addEventListener('touchend', function (event) {
document.addEventListener('touchend', preHandler, false)
that.drawEnd()
})
this.clear()
},
darwStart (e) {
let that = this
let t = e.changedTouches[0]
// console.log(t.clientX, t.clientY);
this.ctx.strokeStyle = this.strokeStyle
this.ctx.beginPath() // 清空全部繪畫路徑
this.ctx.moveTo(t.clientX - this.stroke_info.left, t.clientY - this.stroke_info.top)
this.canvas.addEventListener('touchmove', function (event) {
that.darwMove(event)
})
},
darwMove (e) {
let t = e.changedTouches[0]
this.ctx.lineTo(t.clientX - this.stroke_info.left, t.clientY - this.stroke_info.top)
this.ctx.stroke()
},
drawEnd () {
document.removeEventListener('touchstart', preHandler, false)
document.removeEventListener('touchmove', preHandler, false)
document.removeEventListener('touchend', preHandler, false)
},
clear () {
this.ctx.clearRect(0, 0, this.width, this.height)
this.url = ''
this.$emit('draw_clear')
},
save () {
console.log(this)
let data = this.canvas.toDataURL()
// let query = {url: data}
this.$emit('draw_save', data)
// $emit 傳data給父組件,當簽名簽完了以後,會保存圖片的,data是base64編碼,圖片img src直接可識別
// console.log(this.canvas);
}
},
mounted () {
this.$nextTick(_ => {
this.init()
})
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#clear,#save{
width:270px;
height:50px;
line-height:50px;
font-size:20px;
position:absolute;
}
#clear{
bottom:0;
}
#save{
bottom:0;
right:0;
}
</style>
複製代碼
// 如上標籤中加入的自定義方法
getSignImg (val) {
//val 是接收子組件的data的
this.imgsrc = val // 讓籤的名變成圖片
this.centerDialogVisible = false
}
複製代碼
this.centerDialogVisible = false
複製代碼
就能夠點擊肯定,關閉dialog彈框了app
總結:dom
</el-col>
</el-row>
<el-dialog
title="簽名"
:visible.sync="centerDialogVisible"
width="85%"
center>
<sign @draw_save="getSignImg"></sign>
</el-dialog>
</div>
複製代碼
想要點擊某個元素出現dialog彈框時,就給某個元素加上element提供的點擊事件(),而後dialog中的定義(:visible.sync)也必須一致ui
在沒有引入組件以前,是在父組件中寫js代碼,由於dialog彈框出現時,彈框裏面的dom纔會加載,js會當即執行,用了其提供的open方法也不是很理想,js代碼總會比dom先執行一步,我也放在定時器中讓js緩慢執行,而後清除定時器又成了問題,因此就放棄了這種寫法,改成組件引入。this
若是某個元素綁定了element提供的點擊事件以後,想又得綁定一個點擊事件,那麼把提供的方法寫在本身的方法中編碼
<div class="canva" @click="isShow">
methods:{
isShow(){
this.centerDialogVisible = true
//...
}
}
複製代碼
想要改變canvas寬高,畫線粗細,畫線顏色,畫線背景,必定在子組件內props中更改,自定義改會出問題,canvas描線會模糊,有鋸齒url
父組件想要子組件中的data,就利用子傳父,$emit ,父組件得用子組件的data,保存爲圖片,子組件就得傳出去spa