小程序實現電子簽名(wepy@1.7)

公司業務須要實現電子簽名功能,當前我使用的是wepy框架。html

htmlredux

<template>
    <view class="wrap">
        <view class="content-wrap" id="content">
            <canvas class='myCanvas' canvas-id="myCanvas" @touchmove='move' @touchstart='start' @touchend='end' @touchcancel='cancel' @longtap='tap' disable-scroll='true' @error='error'></canvas>
        </view>
        <view class="bottom-wrap">
            <view class="delete-btn" @tap="clearClick">清除</view>
            <view class="paint-brush">
                <view class="thickness">
                    <repeat for="{{thicknessArr}}" index="index" item="item">
                        <text class="{{item}} {{activeIndex == index ? 'active':''}}" @tap="thicknessChange({{item}}, {{index}})"></text>
                    </repeat>
                </view>
                <view class="paint-color">
                    <repeat for="{{paintColorArr}}" index="index" item="item">
                        <text class="{{item.className}}" @tap="selectColor({{item.color}})"></text>
                    </repeat>
                </view>
                <view class="done" @tap="saveClick">完成</view>
            </view>
        </view>
    </view>
</template>

lesscanvas

page {
    width: 100%;
    height: 100%;
    background: #fff;
}

.wrap {
    width: 100%;
    height: 100%;
    border-top: 1px solid #d5d5d5;
    box-sizing: border-box;
}

.content-wrap {
    width: 100%;
    height: calc(100% - 84rpx);
    .myCanvas {
        width: 100%;
        height: 100%;
    }
}

.bottom-wrap {
    width: 100%;
    height: 80rpx;
    overflow: hidden;
    color: #333;
    border-top: 1px solid #0068b1;
    .delete-btn {
        float: left;
        height: 80rpx;
        line-height: 80rpx;
        padding: 0 15rpx;
        font-size: 28rpx;
    }
    .paint-brush {
        float: right;
        height: 80rpx;
        line-height: 80rpx;
        overflow: hidden;
        .thickness {
            float: left;
            height: 80rpx;
            line-height: 80rpx;
            margin-right: 25rpx;
            text {
                display: inline-block;
                border: 1px solid #333;
                border-radius: 50%;
                margin: 0 15rpx;
                vertical-align: middle;
            }
            .small {
                width: 14rpx;
                height: 14rpx;
            }
            .medium {
                width: 22rpx;
                height: 22rpx;
            }
            .large {
                width: 30rpx;
                height: 30rpx;
            }
            .active {
                background: blue;
            }
        }
        .paint-color {
            float: left;
            text {
                display: inline-block;
                width: 54rpx;
                height: 54rpx;
                border-radius: 12rpx;
                margin: 12rpx 15rpx;
            }
            .red {
                background: red;
            }
            .blue {
                background: blue;
            }
            .black {
                background: #333;
            }
        }
        .done {
            float: left;
            height: 80rpx;
            line-height: 80rpx;
            padding: 0 15rpx;
            font-size: 28rpx;
        }
    }
}

ts數組

import wepy from 'wepy';
import { connect } from 'wepy-redux';
import { uploadSignature } from '@/store/actions/index';

@connect({
    userMeta: (state) => state.globle.userMeta,                    // 用戶數據
    signInfo: (state) => state.seals.signInfo,                     // 上傳返回的簽章信息
}, {
    uploadSignature,                                               // 上傳簽章
})

export default class ElectronicSignature extends wepy.page {

    config = {
        navigationBarTitleText: '手寫簽名',
        pageOrientation: 'landscape',                             // 手機橫屏展現
    };

    data = {
        thicknessArr: ['small', 'medium', 'large'],                // 畫筆粗細
        activeIndex: 0,                                            // 畫筆當前粗細的key
        paintColorArr: [                                           // 畫筆顏色數組
            { className: 'red', color: '#ff0000' },
            { className: 'blue', color: '#0c00ff' },
            { className: 'black', color: '#000000' },
        ],
        signImage: '',                                              // 生成的圖片地址
        canvasContent: null,                                        // 畫布
        canvasw: 0,                                                 // 畫布的寬
        canvash: 0,                                                 // 畫布的高
        touchs: [],                                                 // 全部座標位置
    };

    methods = {
        uploadSignature,
        // 畫布觸摸開始觸發
        start: (event) => {
            // 獲取觸摸開始的 x,y
            this.touchs.push({
                x: event.changedTouches[0].x,
                y: event.changedTouches[0].y,
            });
        },
        // 畫布的觸摸移動手勢響應
        move: (event) => {
            this.touchs.push({
                x: event.touches[0].x,
                y: event.touches[0].y,
            });
            if (this.touchs.length >= 2) {
                this.methods.draw(this.touchs);
            }
        },
        draw: (touchs) => {
            const point1 = touchs[0];
            const point2 = touchs[1];
            touchs.shift();
            this.canvasContent.moveTo(point1.x, point1.y);
            this.canvasContent.lineTo(point2.x, point2.y);
            this.canvasContent.stroke();
            this.canvasContent.draw(true);
        },
        // 選擇筆的粗細
        thicknessChange: (type, index) => {
            this.activeIndex = index;
            this.methods.clearClick();  // 清除畫布
            switch (type) {
                case 'small':
                    this.canvasContent.setLineWidth(2);
                    break;
                case 'medium':
                    this.canvasContent.setLineWidth(4);
                    break;
                case 'large':
                    this.canvasContent.setLineWidth(6);
                    break;
            }
        },
        // 選擇畫筆顏色
        selectColor: (color) => {
            this.methods.clearClick();  // 清除畫布
            this.canvasContent.setStrokeStyle(color);
        },
        clearClick: () => {
            // 清除畫布
            this.canvasContent.clearRect(0, 0, this.canvasw, this.canvash);
            this.canvasContent.draw(true);
        },
        async saveClick() {
            wepy.showLoading({title: '上傳中...'});
            // 把當前畫布指定區域的內容導出生成指定大小的圖片
            const imgResult = await wepy.canvasToTempFilePath({ canvasId: 'myCanvas' });
            const imgPath = imgResult.tempFilePath;
            // 獲取生成的圖片大小
            const fileInfo = await wepy.getFileInfo({ filePath: imgPath });
            const imgSize = fileInfo.size;
            // 上傳
            this.methods.uploadSignature({
                path: imgPath,
                keyName: 'signature_file',
                params: { fileLength: imgSize, userId: this.userMeta.uuid },
            });
        },
        backPrevPage: () => {
            wepy.navigateBack({
                delta: 1,
            });
        },
        // 畫布的觸摸取消響應
        cancel: (event) => {
            // console.log('觸摸取消' + event);
        },
        // 畫布的長按手勢響應
        tap: (event) => {
            // console.log('長按手勢' + event);
        },
        error: (event) => {
            // console.log('畫布觸摸錯誤' + event);
        },
        // 畫布的觸摸移動結束手勢響應
        end: (event) => {
            // 清空軌跡數組
            for (const item of this.touchs) {
                this.touchs.pop();
            }
        },
    };

    onLoad() {
        // 得到Canvas的上下文
        this.canvasContent = wepy.createCanvasContext('myCanvas');
        // console.log(this.canvasContent);
        // 設置線的顏色
        this.canvasContent.setStrokeStyle('#000000');
        // 設置線的寬度
        this.canvasContent.setLineWidth(2);
        // 設置線兩端端點樣式更加圓潤
        this.canvasContent.setLineCap('round');
        // 設置兩條線鏈接處更加圓潤
        this.canvasContent.setLineJoin('round');
        // 獲取畫布寬高
        const self = this;
        const query = wx.createSelectorQuery();
        query.select('#content').boundingClientRect(res => {
          self.canvasw = res.width;
          self.canvash = res.height;
        }).exec();
    }

    watch = {
        signInfo(val) {
            val && wepy.showToast({title: '保存簽名成功!', icon: 'success'});
        },
    };
}
相關文章
相關標籤/搜索