uni-app開發(fā)的canvas簽名組件(多個簽名并處理調(diào)用接口)

1、首先把簽字板的組件放在compunents下指定位置

<template>
    <view v-if="visibleSync" class="cat-signature" :class="{'visible':show}">
        <view class="mask" @tap="close" />
        <view class="content">
            <canvas class='firstCanvas' :canvas-id="canvasId" @touchmove='move' @touchstart='start($event)' @touchend='end'
             @touchcancel='cancel' @longtap='tap' disable-scroll='true' @error='error' />
            <view class="btns">
                <button class="btn" size="mini" type="warn" @click="clear">清除</button>
                <button class="btn" size="mini" type="primary" @click="save">保存</button>
            </view>
        </view>
    </view>
</template>

<script>
    var content = null;
    var touchs = [];
    var canvasw = 0;
    var canvash = 0;
    //獲取系統(tǒng)信息
    uni.getSystemInfo({
        success: function(res) {
            canvasw = res.windowWidth;
            canvash = canvasw * 9 / 16;
        },
    })
    export default{
        props:{
            visible: {
                type: Boolean,
                default: false
            },
            canvasId:{
                type: String,
                default: 'firstCanvas'
            }
        },
        data(){
            return{
                show:false,
                visibleSync: false,
                signImage:'',
                hasDh:false,
            }
        },
        watch:{
            visible(val) {
                this.visibleSync = val;
                this.show = val;
                this.getInfo()
            }
        },
        
        created(options) {
            this.visibleSync = this.visible
            this.getInfo()
            setTimeout(() => {
                this.show = this.visible;
            }, 100)
        },
        methods:{
            getInfo(){
                //獲得Canvas的上下文
                content = uni.createCanvasContext(this.canvasId,this)
                //設(shè)置線的顏色
                content.setStrokeStyle("#000")
                //設(shè)置線的寬度
                content.setLineWidth(6)
                //設(shè)置線兩端端點(diǎn)樣式更加圓潤
                content.setLineCap('round')
                //設(shè)置兩條線連接處更加圓潤
                content.setLineJoin('round')
            },
            // 
            close() {
                this.show = false;
                this.hasDh = false;
                this.$emit('close')
            },
            // 畫布的觸摸移動開始手勢響應(yīng)
            start(e){
                let point = {
                    x: e.touches[0].x,
                    y: e.touches[0].y,
                }
                touchs.push(point);
                this.hasDh = true
            },
            // 畫布的觸摸移動手勢響應(yīng)
            move: function(e) {
                let point = {
                    x: e.touches[0].x,
                    y: e.touches[0].y
                }
                touchs.push(point)
                if (touchs.length >= 2) {
                    this.draw(touchs)
                }
            },
            
            // 畫布的觸摸移動結(jié)束手勢響應(yīng)
            end: function(e) {
                //清空軌跡數(shù)組
                for (let i = 0; i < touchs.length; i++) {
                    touchs.pop()
                }
            
            },
            
            // 畫布的觸摸取消響應(yīng)
            cancel: function(e) {
                // console.log("觸摸取消" + e)
            },
            
            // 畫布的長按手勢響應(yīng)
            tap: function(e) {
                // console.log("長按手勢" + e)
            },
            
            error: function(e) {
                // console.log("畫布觸摸錯誤" + e)
            },
            
            //繪制
            draw: function(touchs) {
                let point1 = touchs[0]
                let point2 = touchs[1]
                // console.log(JSON.stringify(touchs))
                content.moveTo(point1.x, point1.y)
                content.lineTo(point2.x, point2.y)
                content.stroke()
                content.draw(true);
                touchs.shift()
                
            },
            //清除操作
            clear: function() {
                //清除畫布
                content.clearRect(0, 0, canvasw, canvash)
                content.draw(true)
                // this.close()
                this.hasDh = false;
                this.$emit('clear')
            },
            save(){
                var that = this;
                if(!this.hasDh){
                    uni.showToast({title:'請先簽字',icon:'none'})
                    return;
                }
                uni.showLoading({title:'生成中...',mask:true})
                setTimeout(()=>{
                    uni.canvasToTempFilePath({
                        canvasId: this.canvasId,
                        success: function(res) {
                            that.signImage = res.tempFilePath;
                            that.$emit('save',res.tempFilePath);
                            uni.hideLoading()
                            that.hasDh = false;
                            that.show = false;
                        },
                        fail:function(err){
                            console.log(err)
                            uni.hideLoading()
                        }
                    },this)
                },100)
            }
        }
    }
</script>

<style lang="scss">
    .cat-signature.visible {
        visibility: visible
    }
    .cat-signature{
        display: block;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        overflow: hidden;
        z-index: 11;
        height: 100vh;
        visibility: hidden;
        .mask{
            display: block;
            opacity: 0;
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, .4);
            transition: opacity .3s;
        }
        .content{
            display: block;
            position: absolute;
            top: 0;
            left: 0;
            bottom:0;
            right: 0;
            margin: auto; 
            width:94%;
            height: 500upx;
            background: #fff;
            border-radius: 8upx;
            box-shadow: 0px 3px 3px #333;
            // canvas
            .firstCanvas {
                background-color: #fff;
                width: 100%;
                height: 400upx;
            }
            // canvas
            .btns{
                padding: 0 15px;
                height: 100upx;
                overflow: hidden;
                position: absolute;
                bottom: 10upx;
                left: 0;
                right: 0;
                margin: auto;
                display: flex;
                justify-content: space-between;
                .btn{
                    width: 40%;
                    text-align: center;
                    font-size: 28upx;
                    height:60upx;
                    line-height: 60upx;
                    color: #fff;
                    margin-top: 20upx;
                }
            }
        }
    }
    
    .visible .mask {
        display: block;
        opacity: 1
    }
</style>

頁面內(nèi)使用方法如下:

<view class="contract-page-section__input" @click="signature" id="bSign1"><image class="signature-img" :src="contractForm.bSign1" mode="heightFix"></image></view>
<view class="contract-page-section__input" @click="signature" id="bSign2"><image class="signature-img" :src="contractForm.bSign2" mode="heightFix"></image></view>
<canvas-signature :canvas-id="activeSignId" @close="canvasShow = false" @save="signatureSave" :visible="canvasShow" ></canvas-signature>

import canvasSignature from '@/components/canvas-signature/canvas-signature.vue'
components:{canvasSignature},
data() {
            return {
                oneForm:{
                    bSign1: '',
                    bSign2: ''
                },
                // 簽字?jǐn)?shù)據(jù)
                activeSignatureId:'',
                canvasShow: false
            };
        },
methods:{
            // 獲取簽字板
            signature(e){
                this.activeSignatureId = e.currentTarget.id
                this.canvasShow = true
            },
            signatureSave(val){
                this.canvasShow = false;
                this.oneForm[this.activeSignatureId] = val
            },
                        async submitHander(){
                            let submitForm = JSON.parse(JSON.stringify(this.oneForm))
                submitForm.bSign1 = await this.base64Transform('bSign1')
                            // 因?yàn)檗D(zhuǎn)base64位是異步操作擦秽,所以使用async、await去實(shí)現(xiàn)會方便虹钮,多少個簽名都可以做坝冕,本人的頁面10多個簽名
                            // 這里考慮盡量深拷貝一個新對象取操作,在返回當(dāng)前頁才不會修改submitForm里的相對路徑
                            // 然后就可以使用submitForm作為接口請求的入?yún)?                        },
                        // 簽名轉(zhuǎn)base64位文件流
            base64Transform(name){
                return new Promise((resolve, reject)=>{
                    const savedFilePath = this.oneForm[name] //相對路徑
                    const path = plus.io.convertLocalFileSystemURL(savedFilePath) //絕對路徑
                    const fileReader = new plus.io.FileReader()
                    fileReader.readAsDataURL(path)
                        fileReader.onloadend = (res) => { //讀取文件成功完成的回調(diào)函數(shù)
                            resolve(res.target.result)
                        }
                })
            }
        }

有問題請留言葬荷,有可優(yōu)化的地方也請多多指教

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市纽帖,隨后出現(xiàn)的幾起案子宠漩,更是在濱河造成了極大的恐慌,老刑警劉巖懊直,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扒吁,死亡現(xiàn)場離奇詭異,居然都是意外死亡室囊,警方通過查閱死者的電腦和手機(jī)雕崩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門魁索,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人盼铁,你說我怎么就攤上這事粗蔚。” “怎么了饶火?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵鹏控,是天一觀的道長。 經(jīng)常有香客問我肤寝,道長当辐,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任醒陆,我火速辦了婚禮瀑构,結(jié)果婚禮上裆针,老公的妹妹穿的比我還像新娘刨摩。我一直安慰自己,他們只是感情好世吨,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布澡刹。 她就那樣靜靜地躺著,像睡著了一般耘婚。 火紅的嫁衣襯著肌膚如雪罢浇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天沐祷,我揣著相機(jī)與錄音嚷闭,去河邊找鬼。 笑死赖临,一個胖子當(dāng)著我的面吹牛胞锰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播兢榨,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼嗅榕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吵聪?” 一聲冷哼從身側(cè)響起凌那,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吟逝,沒想到半個月后帽蝶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡块攒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年励稳,在試婚紗的時候發(fā)現(xiàn)自己被綠了金砍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡麦锯,死狀恐怖恕稠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扶欣,我是刑警寧澤鹅巍,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站料祠,受9級特大地震影響骆捧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜髓绽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一敛苇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧顺呕,春花似錦枫攀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至启盛,卻和暖如春蹦掐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背僵闯。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工卧抗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鳖粟。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓社裆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親牺弹。 傳聞我的和親對象是個殘疾皇子浦马,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 這是這個系列的第二篇,第一篇介紹了如何配置张漂。這一篇介紹Java與C如何相互介紹晶默。 沒有配置過的可以去看看Andro...
    arvinljw閱讀 1,265評論 0 2
  • 一、什么是webpack航攒,為什么使用它磺陡? 1.1 什么是webpack? webpack是一個模塊打包工具,在開發(fā)...
    wave浪兒閱讀 534評論 0 1
  • 前言 本文主要從webpack4.x入手币他,會對平時常用的Webpack配置一一講解坞靶,各個功能點(diǎn)都有對應(yīng)的詳細(xì)例子,...
    BetterChen閱讀 1,943評論 0 3
  • 大家好,我是小編大野宰拍冠。 大家是不是很詫異今天的作者怎么那么多尿这? 這是我們密謀了很久的一篇「會客廳」文章,特意在五...
    曹將閱讀 2,029評論 1 3
  • 文檔維護(hù)者:孫尊路 喜歡的話庆杜,記得star 一下噢射众! 適用場景 前些陣子,寫了一篇《日歷組件實(shí)現(xiàn)》的使用在線文檔晃财,...
    sunzunlu閱讀 2,459評論 0 1