| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 | <!DOCTYPE html><html lang="en"><head>    <meta charset="utf-8">    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">    <meta http-equiv="x-ua-compatible" content="ie=edge">    <title>签字-计量支付</title>    <style>        #app {            position: absolute;            top: 0;            left: 0;            right: 0;            bottom: 0;            font-family: 'Avenir', Helvetica, Arial, sans-serif;            -webkit-font-smoothing: antialiased;            -moz-osx-font-smoothing: grayscale;            text-align: center;            color: #2c3e50;        }        .container {            width: 100%;            height: 100%;        }        #canvasBox {            display: flex;            flex-direction: column;            height: 100%;            align-items: center; /*定义body的元素垂直居中*/            justify-content: center; /*定义body的里的元素水平居中*/        }        .greet {            padding: 20px;            font-size: 20px;            user-select: none;        }        input {            font-size: 20px;        }        .greet select {            font-size: 18px;        }        canvas {            flex: 1;            cursor: crosshair;            border:2px dashed #007bff;        }        .image-box {            width: 100%;            height: 100%;        }        .image-box header{            font-size: 18px;        }        .image-box img {            max-width: 80%;            max-height: 80%;            margin-top: 50px;            border: 1px solid gray;        }    </style></head><body><div id="app">    <% if (error !== undefined && error) { %>    <div>token已更新,请重新登录并再次扫码。</div>    <% } else { %>    <div class="container">        <div id="canvasBox" :style="getHorizontalStyle" v-show="!showBox">            <div class="greet">                <span>{{msg}}</span>                <input type="button" value="清空" @touchstart="clear" @mousedown="clear"/>                <input type="button" value="下一步 生成签名图" @touchstart="savePNG" @mousedown="savePNG"/>            </div>            <canvas></canvas>        </div>        <div class="image-box" v-show="showBox">            <header>                <input type="button" value="返回" @click="showBox = false"/>                <input type="button" value="上传" @click="upload" :disabled="showSuccess"/>                <span v-show="showSuccess">已成功上传,请刷新电脑页面查看签名效果吧。</span>            </header>            <img :src="signImage">        </div>    </div>    <% } %></div><% if (error === false) { %><script type="text/javascript" src="/public/js/vue/vue.js"></script><script type="text/javascript" src="/public/js/draw.js"></script><script>    const id = '<%- id %>';    const name = '<%- name %>';    const from = '<%- from %>';    const csrf = '<%= ctx.csrf %>';    new Vue({        el: '#app',        data() {            return {                msg: '您好,' + name + ',请在虚线框内手写您的签名。',                degree: 90, // 屏幕整体旋转的角度, 可取 -90,90,180等值                signImage: null,                showBox: false,                showSuccess: false            };        },        components: {            Draw,        },        beforeCreate() {            // document.title = '手写签名';        },        mounted() {            this.canvasBox = document.getElementById('canvasBox');            this.initCanvas();        },        computed: {            getHorizontalStyle() {                const d = document;                const w = window.innerWidth || d.documentElement.clientWidth || d.body.clientWidth;                const h = window.innerHeight || d.documentElement.clientHeight || d.body.clientHeight;                let length = (h - w) / 2;                let width = w;                let height = h;                switch (this.degree) {                    case -90:                        length = -length;                    case 90:                        width = h;                        height = w;                        break;                    default:                        length = 0;                }                if (this.canvasBox) {                    this.canvasBox.removeChild(document.querySelector('canvas'));                    this.canvasBox.appendChild(document.createElement('canvas'));                    setTimeout(() => {                        this.initCanvas();                    }, 200);                }                return {                    transform: `rotate(${this.degree}deg) translate(${length}px,${length}px)`,                    width: `${width}px`,                    height: `${height}px`,                    transformOrigin: 'center center',                };            },        },        methods: {            initCanvas() {                const canvas = document.querySelector('canvas');                this.draw = new Draw(canvas, -this.degree);            },            clear() {                this.draw.clear();            },            download() {                this.draw.downloadPNGImage(this.draw.getPNGImage());            },            savePNG() {                this.signImage = this.draw.getPNGImage();                this.showBox = true;                this.showSuccess = false;            },            upload() {                if (!this.showSuccess) {                    const image = this.draw.getPNGImage();                    const blob = this.draw.dataURLtoBlob(image);                    const successCallback = (response) => {                        // console.log(response);                        if (JSON.parse(response).err === 0) {                            this.showSuccess = true;                        } else {                            this.showSuccess = false;                        }                    };                    const failureCallback = (error) => {                        // console.log(error);                        this.showSuccess = false;                    };                    const url = '/sign/save';                    if (from === 'netcasign') {                        this.blobToBase64(blob).then(res => {                            this.draw.uploadBase64(res.split(',')[1], url, successCallback, failureCallback);                        });                    } else {                        this.draw.upload(blob, url, successCallback, failureCallback);                    }                }            },            blobToBase64(blob) {                return new Promise((resolve, reject) => {                    const fileReader = new FileReader();                    fileReader.onload = (e) => {                        resolve(e.target.result);                    };                    // readAsDataURL                    fileReader.readAsDataURL(blob);                    fileReader.onerror = () => {                        reject(new Error('文件流异常'));                    };                });            }        },    });</script><% } %></body></html>
 |