所用插件:lime-signature
使用到 CSS 特性
- 绝对定位
- transform 旋转
- transform-origin transform 原点
复习一下定位元素(相对定位、绝对定位、粘性定位)
代码#
<template>
<view class="signature-page">
<view class="operate-box">
<button @click="handleSignatureClick('back')">
{{ $t("common.back") }}
</button>
<button @click="handleSignatureClick('clear')">
{{ $t("maintenance.signatureBtns[0]") }}
</button>
<button @click="handleSignatureClick('undo')">
{{ $t("maintenance.signatureBtns[1]") }}
</button>
<button @click="handleSignatureClick('save')">
{{ $t("maintenance.signatureBtns[2]") }}
</button>
</view>
<view class="canvas-box">
<l-signature
disableScroll
backgroundColor="#fff"
ref="signatureRef"
:penColor="penColor"
:penSize="penSize"
:openSmooth="openSmooth"
:landscape="IsLandscape"
></l-signature>
</view>
</view>
</template>
<script>
/**
* 签名-横屏
* @author demon3443002624@outlook.com
* @version 1.0.0
*/
import { dataURLtoFile, changeUrl } from "@/common/utils.js";
const UPLOAD_FILE_URL_MAINTENANCE5 =
changeUrl("/Lease/UploadLeaseMaintenanceNewV2File") + "?type=5";
export default {
data() {
return {
type: null,
penColor: "#000",
penSize: 5,
openSmooth: true,
IsLandscape: false,
};
},
onLoad(params) {
const _this = this;
const eventChannel = this.getOpenerEventChannel();
// 监听acceptData事件,获取上一页通过eventChannel传送到当前页面的数据
eventChannel.on("acceptData", function (data) {
_this.type = data.type;
});
// 横屏签名
this.IsLandscape = true;
// #ifdef APP-PLUS
// this.IsLandscape = true
// plus.screen.lockOrientation('landscape-primary') // App 屏幕旋转
// #endif
},
onUnload() {
// #ifdef APP-PLUS
// plus.screen.lockOrientation('portrait-primary') // App 屏幕旋转
// #endif
},
methods: {
handleSignatureClick(type) {
if (type == "back") {
uni.navigateBack();
return;
}
if (type == "openSmooth") {
this.openSmooth = !this.openSmooth;
return;
}
const signatureRefStr = "signatureRef";
if (type == "save") {
this.$refs[signatureRefStr].canvasToTempFilePath({
success: (res) => {
// App 生成的图片路径, H5 生成的base64 处理方式不同
const commonHandler = (resultInner) => {
if (resultInner.statusCode === 200) {
const responseDataJson = resultInner.data;
if (responseDataJson) {
const responseData = JSON.parse(responseDataJson);
const eventChannel = this.getOpenerEventChannel();
// 向上一页通过事件传递数据
eventChannel.emit("editData", {
type: this.type,
url: responseData.Data,
});
uni.navigateBack();
}
}
};
// #ifdef H5
uni.uploadFile({
url: UPLOAD_FILE_URL_MAINTENANCE5,
file: dataURLtoFile(res.tempFilePath, "file.png"), // ** 没有文件名,后台出错
name: "file",
success: (result) => {
commonHandler(result);
},
fail: (err) => {},
});
// #endif
// #ifdef APP
uni.uploadFile({
url: UPLOAD_FILE_URL_MAINTENANCE5,
filePath: res.tempFilePath,
name: "file",
success: (result) => {
commonHandler(result);
},
fail: (err) => {},
});
// #endif
},
});
return;
}
if (this.$refs[signatureRefStr]) this.$refs[signatureRefStr][type]();
},
},
};
</script>
<style lang="scss">
$operate-btn-width: 100rpx;
.signature-page {
margin-top: var(--status-bar-height);
height: calc(
100vh - var(--window-top) - var(--status-bar-height) - var(--window-bottom)
);
width: 100%;
position: relative;
.canvas-box {
height: 100%;
margin-left: $operate-btn-width;
}
.operate-box {
position: absolute;
display: flex;
transform: rotate(90deg);
transform-origin: top left;
height: $operate-btn-width;
width: calc(
100vh - var(--window-top) - var(--status-bar-height) -
var(--window-bottom)
);
top: 0;
left: $operate-btn-width;
z-index: 1;
uni-button {
flex: 1;
margin: 5rpx 10rpx;
}
}
}
</style>
结果