找的插件,自己写要做一堆兼容麻烦死了

使用的这个插件vue-signature-pad,看下载量很多

npm i vue-signature-pad

 

import { VueSignaturePad } from 'vue-signature-pad';

 components: {
        VueSignaturePad, UseDetailDailog
    },

 <VueSignaturePad
                    class="sign-box"
                    :width="signWidth + 'px'"
                    :height="signHeight + 'px'"
                    ref="signaturePad"
                    :options="options"
                />
  options: {
                backgroundColor: 'rgba(0,0,0,0)',
                penColor: 'rgba(0,0,0,1)',
                velocityFilterWeight: 0.7,
                onBegin: () => { (this.$refs.signaturePad as any).resizeCanvas() }, // 手动初始化
            },

 mounted() {
        this.checked = false;
        const { width, height } = document.getElementById('pad-box')?.getBoundingClientRect() as any;
        this.signWidth = width - 10;
        this.signHeight = height;
        nextTick(() => {
            (this.$refs.signaturePad as any).resizeCanvas();
            this.setSignBg();
            // this.setSignWatermark();
        })
    },

 应为要使用撤销的功能,所以水印是自己做背景做的假货,但是上传的时候需要带上水印,拿到插件给的数据是base64,所以要自己再画一遍加上水印

async setSignWatermark(base64: string) {
            const canvas = document.createElement('canvas') as HTMLCanvasElement;
            const ctx = canvas?.getContext("2d") as CanvasRenderingContext2D;//获取画笔
            canvas.width = this.signWidth;
            canvas.height = this.signHeight;
            canvas.style.display = "none";
            const width = 130;
            const height = 120;
            const numberLine = Math.ceil(this.signWidth / width) + 10;
            const numberHeight = Math.ceil(this.signHeight / height) + 10;
            ctx.font = "16px";
            ctx.fillStyle = "rgba(0,0,0,.3)";
            ctx.save();
            ctx.rotate(-0.4);
            for (let i = -10, l = numberLine; i < l; i++) {
                for (let j = -10, h = numberHeight; j < h; j++) {
                    ctx.fillText("eefit会员项目使用凭证", (200 / 6) + (i * width), (160 / 2) + (j * height));
                    ctx.translate(5, 0);
                }
            };
            ctx.restore();
            const img = await this.createImg(base64);
            ctx.drawImage(img, 0, 0, this.signWidth, this.signHeight);
            return canvas;
        },
      
createImg(url: string): Promise<any> {
            return new Promise((resolve, reject) => {
                const img = new Image();
                img.src = url;
                img.onload = () => {
                    resolve(img);
                };
                img.onerror = () => {
                    reject();
                };
            });
        },
 

最后一步,校验并提交获取url

        async upSign() {
            try {
                await this.checkedInfo();
                this.loading = true;
                const { data } = (this.$refs.signaturePad as any).saveSignature();
                const canvas = await this.setSignWatermark(data);
                const dataURL = canvas.toDataURL('image/png');
                this.ossConfig = await commonService.getOssConfig();
                this.client = new OSS({
                    accessKeyId: this.ossConfig.access_key_id,
                    accessKeySecret: this.ossConfig.access_key_secret,
                    region: this.ossConfig.region,
                    bucket: this.ossConfig.bucket,
                });
                let fileName = `${new Date().getTime()}${Math.ceil(Math.random() * 1e5)}.png`;
                const file = this.base64ToFile(dataURL, fileName);
                let url = '';
                await this.client.put(`${this.ossConfig.object}/${fileName}`, file, {
                    headers: {
                        'x-oss-security-token': this.ossConfig.security_token,
                    }
                }).then((res: any) => {
                    url = `${this.ossConfig.domain}/${this.ossConfig.object}/${fileName}`;
                }).catch((err: any) => {
                });
                console.log('url->', url);
            } catch (error) {
                ElMessage.error(this.$t('提交签名失败'))
            } finally {
                this.loading = false;
            }
        },
        base64ToFile(base64String: any, fileName: string) {
            const arr = base64String.split(',');
            const mime = arr[0].match(/:(.*?);/)[1];
            const bstr = atob(arr[1]);
            let n = bstr.length;
            const u8arr = new Uint8Array(n);

            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new File([u8arr], fileName, { type: mime });
        }

搞定,拿到url。

 成功上传。

posted on 2024-09-26 21:46  北极熊的菜  阅读(14)  评论(0编辑  收藏  举报