You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

378 lines
8.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="sign">
<view class="sign-bkg">
<view class="sign-bkg__word">
<span></span>
<span></span>
</view>
</view>
<view class="sign-pic">
<!-- <image src="/static/cloud.png" class="sign-pic__cloud" mode="widthFix"></image>-->
<image class="sign-pic__city" :src="require('@/static/city.png')" mode="widthFix" />
</view>
<view class="sign-cnv">
<l-signature disableScroll backgroundColor="#ddd" ref="signatureRef" :penColor="options.penColor"
:backgroundColor="options.backgroundColor" :penSize="options.penSize" :openSmooth="options.openSmooth">
</l-signature>
</view>
<view class="sign-btn">
<view class="sign-btn__reset" @click="$u.throttle(onClick('clear'))"></view>
<view class="sign-btn__confirm" @click="$u.throttle(onClick('save'))"></view>
</view>
</view>
</template>
<script>
import {
base64ToFile
} from '@/common/util.js'
import {
ROOTPATH
} from '@/common/config.js'
export default {
data() {
return {
url: '',
options: {
penColor: '#000',
penSize: 16,
openSmooth: true,
backgroundColor: 'rgba(0,0,0,0)'
},
}
},
methods: {
//src - 图片路径deg旋转角度
rotateBase64Img(src, edg) {
return new Promise((resolve, reject) => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
let imgW // 图片宽度
let imgH // 图片高度
let size // canvas初始大小
if (edg % 90 != 0) {
console.error('旋转角度必须是90的倍数!')
}
(edg < 0) && (edg = (edg % 360) + 360)
const quadrant = (edg / 90) % 4 // 旋转象限
const cutCoor = {
sx: 0,
sy: 0,
ex: 0,
ey: 0
} // 裁剪坐标
const image = new Image()
image.crossOrigin = 'anonymous'
image.src = src
image.onload = () => {
imgW = image.width
imgH = image.height
size = imgW > imgH ? imgW : imgH
canvas.width = size * 2
canvas.height = size * 2
switch (quadrant) {
case 0:
cutCoor.sx = size
cutCoor.sy = size
cutCoor.ex = size + imgW
cutCoor.ey = size + imgH
break
case 1:
cutCoor.sx = size - imgH
cutCoor.sy = size
cutCoor.ex = size
cutCoor.ey = size + imgW
break
case 2:
cutCoor.sx = size - imgW
cutCoor.sy = size - imgH
cutCoor.ex = size
cutCoor.ey = size
break
case 3:
cutCoor.sx = size
cutCoor.sy = size - imgW
cutCoor.ex = size + imgH
cutCoor.ey = size + imgW
break
}
ctx.translate(size, size)
ctx.rotate(edg * Math.PI / 180)
ctx.drawImage(image, 0, 0)
var imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey)
if (quadrant % 2 == 0) {
canvas.width = imgW
canvas.height = imgH
} else {
canvas.width = imgH
canvas.height = imgW
}
ctx.putImageData(imgData, 0, 0)
// 获取旋转后的base64图片
resolve(canvas.toDataURL())
}
})
},
onClick(type) {
if (type == 'openSmooth') {
this.openSmooth = !this.openSmooth
return
}
if (type == 'save') {
this.$refs.signatureRef.canvasToTempFilePath({
success: (res) => {
// 是否为空画板 无签名
if (res.isEmpty) {
uni.showToast({
title: '请签名',
icon: 'none'
})
return
}
// 生成图片的临时路径
// app | H5 | 微信小程序 生成的是base64
if (res.tempFilePath) {
//this.$u.vuex('vuex_sign_base64', res.tempFilePath)
this.rotateBase64Img(res.tempFilePath, -90).then(res => {
this.$u.vuex('vuex_sign_base64', res)
let form = new FormData()
form.append('file', base64ToFile(res, 'sign'))
form.append('active_tag', 'map_point')
form.append('activity_list_id', 7)
form.append('token',this.vuex_token)
let xhr = new XMLHttpRequest()
xhr.open('post', `${ROOTPATH}/api/mobile/upload-file`)
xhr.onreadystatechange = () => {
if (xhr.status === 200 && xhr.readyState ===
4) {
let val = JSON.parse(xhr.responseText);
console.log(val);
this.$u.api.savePoster({
upload_id: val.id,
type: 2
}).then(_ => {
uni.navigateTo({
url: `/pages/certificate/certificate`
})
})
}
}
xhr.send(form)
})
}
}
})
return
}
if (this.$refs.signatureRef)
this.$refs.signatureRef[type]()
},
},
}
</script>
<style scoped lang="scss">
@media screen and (orientation: portrait) {
.sign {
height: 100vh;
width: 100vw;
&-pic {
width: 100vh;
display: flex;
align-items: flex-end;
transform: rotate(90deg) translateX(0%) translateY(-100%);
transform-origin: 0 0;
position: absolute;
&__cloud {
flex: 1;
}
&__city {
flex: 1;
}
}
&-bkg {
background-color: #FEFAEE;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
&__word {
width: 390rpx;
font-size: 128rpx;
font-weight: 400;
color: #BBB6B2;
opacity: 0.3;
display: flex;
justify-content: space-between;
transform: rotate(90deg) translateX(-50%) translateY(calc(-100% - 426rpx));
transform-origin: 0 0;
position: absolute;
top: 50%;
}
}
&-cnv {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
&-btn {
display: flex;
transform: rotate(90deg) translateX(-50%) translateY(-100%);
transform-origin: 0% 0%;
margin-left: 112rpx;
z-index: 99999;
position: fixed;
top: 50%;
&__reset {
width: 200rpx;
height: 66rpx;
background: #FEFAEE;
border: 4rpx solid #CA3F32;
border-radius: 34rpx;
font-size: 26rpx;
font-weight: 400;
color: #B61F2E;
line-height: 58rpx;
text-align: center;
margin-right: 52rpx;
}
&__confirm {
font-size: 26rpx;
font-weight: 400;
color: #FFFFFF;
width: 200rpx;
height: 66rpx;
background: linear-gradient(0deg, #E16055, #C54439);
border-radius: 34rpx;
line-height: 66rpx;
text-align: center;
}
}
}
}
@media screen and (orientation: landscape) {
.sign {
height: 100vh;
width: 100vw;
&-pic {
width: 100vw;
display: flex;
align-items: flex-end;
position: absolute;
bottom: 0;
&__cloud {
flex: 1;
}
&__city {
flex: 1;
}
}
&-bkg {
background-color: #FEFAEE;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
&__word {
width: 18vw;
font-size: 6vw;
font-weight: 400;
color: #BBB6B2;
opacity: 0.3;
display: flex;
justify-content: space-between;
transform: translate(-50%, -50%);
position: absolute;
top: 50%;
left: 50%;
}
}
&-cnv {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
&-btn {
display: flex;
transform: translateX(-50%);
z-index: 99999;
position: fixed;
bottom: 8vh;
left: 50%;
&__reset {
width: 16.6vw;
height: 5.2vw;
background: #FEFAEE;
border: 0.4vw solid #CA3F32;
border-radius: 34rpx;
font-size: 2.6vw;
font-weight: 400;
color: #B61F2E;
text-align: center;
line-height: 5.2vw;
box-sizing: content-box;
margin-right: 48rpx;
}
&__confirm {
font-size: 2.6vw;
font-weight: 400;
color: #FFFFFF;
width: 17.4vw;
height: 6vw;
background: linear-gradient(0deg, #E16055, #C54439);
border-radius: 34rpx;
text-align: center;
line-height: 6vw;
}
}
}
}
</style>