| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- <template>
- <div class="signature">
- <div class="inputs" v-if="!popup">
- <div class="label" :class="required?'labelqr':''">{{label}}</div>
- <div>
- <div v-if="value" class="images">
- <image @tap="toImg" class="images" mode="aspectFit" :src="value"></image>
- <view v-if="!readonly" @click="toDeleteImg" class="icons">
- <view class="Deletes">×</view>
- </view>
- </div>
- <div v-if="!value && !readonly" class="explain" @click="toPop">
- {{placeholder?placeholder:'点击签名'}}
- </div>
- </div>
- </div>
- <view class="bottomPopup" v-if="showPopup" @touchmove.stop.prevent="moveHandle">
- <transition name="slide-up" appear>
- <view class="popup-content">
- <view class="popup">
- <div class="hader" v-if="!isHeight">
- <div @click="toclear">取消</div>
- <div class="text">{{label}}</div>
- <div @click="isEmpty">确定</div>
- </div>
- <div :class="isHeight?'wgSignatureq':'wgSignature'">
- <div v-if="isHeight" key="999" style="width: 750rpx ;height: 100vh;">
- <jp-signature :beforeDelay="200" :landscape="true" disableScroll ref="signatureRef" :openSmooth="openSmooth" :penSize="6" :bounding-box="boundingBox"></jp-signature>
- </div>
- <div v-else key="888" style="width: 750rpx ;height: 35vh;">
- <jp-signature :beforeDelay="200" disableScroll ref="signatureRef" :openSmooth="openSmooth" :bounding-box="boundingBox" :penSize="3"></jp-signature>
- </div>
- <div v-if="!isHeight" class="appBut" >
- <div class="buts" @click="undo" >撤销</div>
- <div class="buts" @click="deleteImg" >清除</div>
- <div class="buts" style="background-color: #55aaff;color: #fff;" @click="Tomagnify" >全屏</div>
- </div>
- <div v-else class="appBut" style="height: 80px;">
- <div class="butx" @click="undo" >撤销</div>
- <div class="butx" @click="deleteImg">清除</div>
- <div class="butx" style="background-color: #55aaff;color: #fff;" @click="Tomagnify" >小屏</div>
- <div class="butx" @click="toclear">取消</div>
- <div class="butx" style="background-color: #E59C36;color: #fff;" @click="isEmpty">完成</div>
- </div>
- </div>
- </view>
- </view>
- </transition>
- </view>
-
- </div>
- </template>
- <!-- 有项目需要开发的请联系 扣 - 371524845 -->
- <script>
- /**
- * 手写签名组件
- * 用于手写签名(弹框签名支持小屏和全屏)
- *
- *********参数********
- * label 选项名称
- * value 初始值String(支持bas64,url 等图片显示)
- * required 是否显示必填
- * placeholder 默认值
- * readonly 是否只读
- *
- * *********回调********
- * @input(e) 点击确认 e生成的图片数据(bas64)
- *
- *********方法********
- * isEmpty() 生成图片
- * deleteImg() 删除图片
- */
- export default {
- props: {
- popup: {
- type: [Boolean, String],
- default: false,
- },
- label: {
- type: String,
- default: '手写签名',
- },
- value: {
- type: String,
- default: '',
- },
- required: {
- type: [Boolean, String],
- default: false,
- },
- placeholder: {
- type: String,
- default: '点击签名',
- },
- readonly: {
- type: [Boolean, String],
- default: false,
- },
- openSmooth: {
- type: [Boolean, String],
- default: true,
- },
- boundingBox: {
- type: [Boolean, String],
- default: true,
- },
- },
- data() {
- return {
- showPopup: false,
- isHeight: false,
- height1: uni.getSystemInfoSync().windowWidth / 2,
- width: uni.getSystemInfoSync().windowWidth, //实时屏幕宽度
- height: uni.getSystemInfoSync().windowHeight, //实时屏幕高度
- showPicker: false
- }
- },
- methods: {
- moveHandle(){
-
- },
- toImg(){
- this.$emit('toImg',this.value)
- },
- undo() {
- this.$refs.signatureRef.undo()
- },
- toPop() {
- this.showPopup = true
- },
- toDeleteImg() {
- // #ifndef VUE3
- this.$emit('input','')
- // #endif
- // #ifdef VUE3
- this.$emit('update:value','')
- // #endif
- },
- toclear() {
- this.isHeight = false
- this.showPopup = false
- },
- close() {
- this.isHeight = false
- this.showPopup = false
- const {signatureRef} = this.$refs
- signatureRef.clear()
- },
- deleteImg() {
- const {signatureRef} = this.$refs
- signatureRef.clear()
- },
- toDataURL(url) {
- // #ifndef VUE3
- this.$emit('input',url)
- // #endif
- // #ifdef VUE3
- this.$emit('update:value',url)
- // #endif
- this.showPicker = false
- },
- Tomagnify() {
- this.isHeight = !this.isHeight
- const {signatureRef} = this.$refs
- signatureRef.clear()
- },
- isEmpty() {
- const {signatureRef} = this.$refs
- signatureRef.canvasToTempFilePath({
- quality: 0.8,
- success: (res) => {
- if (this.required) {
- if (!res.isEmpty) {
- // #ifndef VUE3
- this.$emit('input', res.tempFilePath)
- // #endif
- // #ifdef VUE3
- this.$emit('update:value',res.tempFilePath)
- // #endif
- this.$emit('change', res.tempFilePath)
- this.isHeight = false
- this.showPopup = false
- } else {
- uni.showToast({
- title: '请先签名',
- icon: 'none'
- });
- }
- } else {
- // #ifndef VUE3
- this.$emit('input', res.tempFilePath)
- // #endif
- // #ifdef VUE3
- this.$emit('update:value',res.tempFilePath)
- // #endif
- this.$emit('change', res.tempFilePath)
- this.isHeight = false
- this.showPopup = false
- }
- }
- })
- },
- },
- beforeCreate() {},
- created() {}
- }
- </script>
- <style scoped lang="scss">
- .wgSignatureq{
-
- }
- .appBut{
- display: flex;justify-content: flex-start;align-items: center;text-align: center;height: 50px;line-height: 35px;
- .buts{
- color: #333;flex: 1;margin: 0 15px;background-color: #ccc;border-radius: 5px;height: 35px;
- }
- .butx{
- color: #333;flex: 1;margin: 0 5px;background-color: #ccc;border-radius: 5px;height: 35px;
- transform: rotate(90deg);
- }
- }
-
- .bottomPopup {
- position: fixed;
- left: 0;
- top: 0;
- bottom: 0;
- right: 0;
- z-index: 999;
- background-color: rgba(0, 0, 0, 0.5);
- .popup-content {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- // top: 0;
- background-color: #ffffff;
- }
- .slide-up-enter-active,
- .slide-up-leave-active {
- transition: all .3s ease;
- }
- .slide-up-enter,
- .slide-up-leave-to {
- transform: translateY(100%);
- }
- }
- .signature {
- .inputs {
- background-color: #fff;
- padding: 10px 16px;
- .label {
- line-height: 35px;
- position: relative;
- }
- .labelqr:before {
- content: "*";
- color: #f00;
- }
- .explain {
- width: 100%;
- background-color: #f1f1f1;
- text-align: center;
- line-height: 40px;
- border: 1px dotted #ccc;
- color: #999;
- }
- .Deletes {
- border: 1px solid #f00;
- width: 30rpx;
- height: 30rpx;
- border-radius: 50%;
- color: #f00;
- text-align: center;
- font-size: 30rpx;
- line-height: 30rpx;
- }
- }
- .images {
- width: 300rpx;
- height: 150rpx;
- position: relative;
- .icons {
- position: absolute;
- top: 0;
- right: 0;
- }
- }
- }
- .popup {
- background-color: #fff;
- }
- .hader {
- display: flex;
- justify-content: center;
- text-align: center;
- height: 45px;
- border-bottom: 1px solid #f5f5f5;
- align-items: center;
- div {
- text-align: center;
- width: 80px;
- color: #E59C36;
- }
- .text {
- color: #333;
- flex: 1;
- }
- }
-
-
- </style>
|