123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
- <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>
|