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

2 years ago
<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>