const app = new Vue({ el: '#app' , data() { return { signature: '' , // 户主签名 signaturePath: '' , // 户主签名 signDialog: false , signatureBoard: false , signatureTip: true , // 签名区提示 canvasSign: null , canvas: null , ctx: null , } }, created() { }, methods: { // 显示签名弹层 showSignPopup() { this .signatureBoard = true this .$nextTick(() => { this .initSign() }) }, // 初始化签名 initSign() { $( this .$refs.refSignature).empty() const canvasSign = $( this .$refs.refSignature).jSignature({ height: "100%" , width: "100%" }) const canvas = canvasSign.children( 'canvas' )[0] let ctx = canvas.getContext( '2d' ) ctx.fillStyle = '#fff' ctx.fillRect(0, 0, canvas.width, canvas.height) $( this .$refs.refSignature).bind( 'touchstart' , () => { this .signatureTip = false }) $( this .$refs.refSignature).bind( 'change' , () => { this .signatureTip = false }) this .signatureTip= true this .canvasSign = canvasSign this .canvas = canvas this .ctx = ctx }, // 清除签名 clearSign() { this .$dialog.confirm({ title: '清除签名' , message: '确定需要清除签名吗?' , }) .then(() => { $( this .$refs.refSignature).jSignature( "clear" ) this .ctx.fillStyle = '#fff' this .ctx.fillRect(0, 0, this .canvas.width, this .canvas.height) this .signatureTip = true }) . catch (() => { // on cancel }) }, // 提交签名 submitSignature () { const isModified = $( this .$refs.refSignature).jSignature( "isModified" ); if (!isModified) { this .$toast( "请签名后再提交!" ) return } this .saveSignature() }, // 保存签名图片 saveSignature() { let imgSignature = $( this .$refs.refSignature).jSignature( "getData" , "default" ); this .rotateBase64(imgSignature).then((img) => { imgSignature = img const fileName = this .userId + '-' + this .randomStr + '.png' let file = this .dataURLtoFile(imgSignature, fileName) let formData = new FormData() formData.append( "file" , file) formData.append( "userId" , this .userId) $.jrAjax({ url: UPLOAD_IMAGE, type: 'post' , data: formData, isShowLoader: true , contentType: false , processData: false , headers: { 'Authorization' : this .token }, success: (response) => { const { id, type, realName, path } = response if (id) { this .$nextTick(() => { this .signaturePath = path this .signature = BASE_URL + '/file/' + type + '/' + realName this .signatureBoard = false }) } else { this .$toast( '上传失败' ) } }, error: (err) => { } }) }) }, // 签名确认弹窗操作 beforeCloseDialog(action, done) { if (action === 'confirm' ) { if (! this .signature) { this .$toast( '户主未签字确认!' ) done( false ) } else { done() } } else { done() } }, // 将base64转换为文件 dataURLtoFile(dataUrl, filename) { let arr = dataUrl.split( ',' ), mime = arr[0].match(/:(.*?);/)[1], bStr = atob(arr[1]), n = bStr.length, u8arr = new Uint8Array(n) if (!filename) { filename = 'image' } while (n--) { u8arr[n] = bStr.charCodeAt(n) } return new File([u8arr], filename, { type: mime }) }, // 将base64图片旋转90度 rotateBase64 (data) { return new Promise((resolve) => { const imgView = new Image() imgView.src = data const canvas = document.createElement( 'canvas' ) const context = canvas.getContext( '2d' ) const cutCor = { sx: 0, sy: 0, ex: 0, ey: 0 } // 裁剪坐标 imgView.onload = () => { const imgW = imgView.width const imgH = imgView.height let size = imgH if (imgW > imgH) { size = imgW cutCor.ey = imgW } else { cutCor.ey = size + imgW } cutCor.sx = size cutCor.sy = size - imgW cutCor.ex = size + imgH canvas.width = size * 2 canvas.height = size * 2 context.translate(size, size) context.rotate(Math.PI / 2 * 3) context.drawImage(imgView, 0, 0) const imgData = context.getImageData(cutCor.sx, cutCor.sy, cutCor.ex, cutCor.ey) canvas.width = imgH canvas.height = imgW context.putImageData(imgData, 0, 0) resolve(canvas.toDataURL( 'image/png' )) }; }); }, } }) |