微信小程序 canvas层级过高覆盖原生组件
一、背景
微信小程序中使用signature第三方插件完成签名效果,但真机调试时发现canvas层级过高遮挡了按钮
二、具体问题
问题原因:签名后点击按钮无法生效
问题代码:
<template>
<view class="sign_page" v-cloak>
<view class="sign_body">
<view class="cover">
<view class="cover_text"
:style="'transform: rotate( '+ rotate + 'deg);text-shadow: 10rpx 10rpx 5rpx ' + font_color+ ';'">{{uname}}
</view>
</view>
<canvas class="sign_canvas" disable-scroll="true" canvas-id="handWriting"
:style="bgImg ? 'background: url(' + bgImg + ');background-size:100% 100%;' : ''"
@touchstart.stop="handWritingStart" @touchmove.stop="handWritingMove" @touchend.stop="handWritingEnd"></canvas>
</view>
<view class="sign_footer" :class="{'rotate': rotate == 90}">
<view class="btn" @click="retDraw">清除</view>
<view class="btn" @click="exportImg">确认</view>
</view>
</view>
</template>
真机调试效果:
说明:
canvas层级过高,遮住了按钮,签字后点击确认或清除按钮都无法触发选中事件
三、问题分析
在小程序中,canvas组件是由客户端创建的原生组件,原生组件层级是最高的。所以在页面中即使将 Z-index 设置很高都无法盖在canvas组件上
四、解决方法
该问题我想到了两种解决方法
方法1:将画布和按钮按需分配视图比例
原代码画布和按钮的宽度都为100%,将画布和按钮按需分配视图比例,如画布占页面的75%,按钮占页面的25%,解决画布遮挡按钮问题
方法2:使用 cover-view 实现覆盖
将需要覆盖在 Canvas 上的元素使用 cover-view 组件包裹起来,cover-view 可以覆盖在 Canvas 上方显示。
cover-view 可覆盖的原生组件包括 map、video、canvas、camera、live-player、live-pusher
小程序官方文档地址:cover-view | 微信开放文档
改造代码:
<template>
<view class="sign_page" v-cloak>
<view class="sign_body">
<view class="cover">
<view class="cover_text"
:style="'transform: rotate( '+ rotate + 'deg);text-shadow: 10rpx 10rpx 5rpx ' + font_color+ ';'">{{uname}}
</view>
</view>
<canvas class="sign_canvas" disable-scroll="true" canvas-id="handWriting"
:style="bgImg ? 'background: url(' + bgImg + ');background-size:100% 100%;' : ''"
@touchstart.stop="handWritingStart" @touchmove.stop="handWritingMove" @touchend.stop="handWritingEnd"></canvas>
</view>
<cover-view class="sign_footer" :class="{'rotate': rotate == 90}">
<cover-view class="btn" @click="retDraw">清除</cover-view>
<cover-view class="btn" @click="exportImg">确认</cover-view>
</cover-view>
</view>
</template>
css样式增加z-index解决兼容安卓机失效问题
.sign_footer {
flex-shrink: 0;
width: 100%;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
bottom: 30rpx;
left: 0;
height: 170rpx;
line-height: 170rpx;
z-index: 999;
&.rotate {
transform: rotate(90deg);
bottom: 200rpx;
left: -124rpx;
width: 400rpx;
}
.btn {
width: 150rpx;
background: #0eb543;
border-radius: 30rpx;
text-align: center;
color: #fff;
padding: 25rpx 0;
&:nth-child(1) {
background-color: #c3c3c3;
color: #000000;
}
}
}
最终实现效果:无论签名文字书写的有多长,按钮都是在画布之上,签名完可以点击按钮触发事件
最后:👏👏😊😊😊👍👍