解决小程序原生组件层级穿透问题

文章介绍了在微信小程序中如何使用cover-view覆盖原生组件,如map、video和canvas等,以及如何处理自定义组件与cover-view的兼容性问题。当需要在canvas上显示弹窗时,可以通过改变canvas的hidden属性来控制其显隐。另外,对于canvas层级过高的问题,文章提出了一种将canvas内容转换为图片以降低层级的方法,从而实现弹窗的正常显示。
摘要由CSDN通过智能技术生成

1、cover-view

cover-view覆盖在原生组件之上的文本视图。
可覆盖的原生组件包括 map、video、canvas、camera、live-player、live-pusher
只支持嵌套 cover-view、cover-image,可在 cover-view 中使用 button。
bug: 自定义组件嵌套 cover-view 时,自定义组件的 slot 及其父节点暂不支持通过 wx:if 控制显隐,否则会导致 cover-view 不显示。(也就是说自定义组件中的cover-view是无效的,不显示。)

原生组件的层级是无法通过z-index来改变的。只有图片和文字的话可以使用cover-view和cover-image来解决。
cover-view内只支持嵌套 cover-view、cover-image,可在 cover-view 中使用 button。也就是说若cover-view内嵌套了其它类型的view,则在真机上会被忽略。
自定义组件弹窗问题解决方案

2、显示隐藏来控制原生组件

下面是以canvas示例,针对其他原生组件也可以采用这个方法。

如果弹窗有input,cover-view不止支持input,这个时候方法一就不行。这时,最好的办法是在弹窗的时候,隐藏canvas层,也就是给他加一个属性,通过改变属性值来隐藏。
具体就是:
canvas的view属性加 hidden="{{ canvasHidden }}。
弹窗打开和关闭的时候,改变canvasHidden为true或false

<view class="canvas_wrap" hidden="{{ hideCanvas }}">
  <canvas
    class="ec-canvas" 
    canvas-id="{{ canvasId }}" 
    bindinit="init" 
    bindtouchstart="{{ ec.disableTouch ? '' : 'touchStart' }}" 
    bindtouchmove="{{ ec.disableTouch ? '' : 'touchMove' }}" 
    bindtouchend="{{ ec.disableTouch ? '' : 'touchEnd' }}">
  </canvas>
</view>

3、特殊:canvas转成图片降低层级

  • 问题:组件授权登录的弹窗被canvas所覆盖。
  • 解决思路:canvas原生组件层级过高,那么就利用某个方法降低其层级。
  • 解决流程:使用CanvasContext.draw()将之前绘图上下文的描述画到canvas中,在其绘制成功的回调函数中,把生成的画布利用wx.canvasToTempFilePath()转换成图片,显示时把替换成图片。

以下代码只显示部分核心内容

//引用二维码生成库
    onLoad: function (options) {
        //条形码绘制
        wxbarcode.barcode("barcode", this.data.numCode, 680, 200,true,this,(img)=>{
            this.setData({
                barImg: img
            })
        });
        //二维码绘制
        wxbarcode.qrcode("qrcode", this.data.numCode, {
            codeSize: 420,
            color: "#000000",
            bgcolor: "#ffffff",
        },this,(img)=>{
            this.setData({
                qrImg: img
            })
        },true);
    },

二维码容器

<!-- 条形码 -->
<view class="num-code">
  <view class="barcode">
    <block wx:if="{{barImg}}" >
      <image src="{{barImg}}" class="barImg" mode=""/>
    </block>
    <block wx:else >
      <canvas canvas-id="barcode"/>
    </block>
    <text class="color_999 mg_top_20">{{numCode}}</text>
  </view>
</view>
<!-- 二维码 -->
<view class="img-code">
  <block wx:if="{{qrImg}}">
    <image src="{{qrImg}}" mode=""  class="qrImg" />
  </block>
  <block wx:else>
    <canvas canvas-id="qrcode"class="code-box1" />
  </block>
  <view class="color_333">付款时出示会员码结账</view>
</view>

index.js


/**
 *barc  生成条码
 * @param {*} id canvas 的id String  必填
 * @param {*} code  内容条码 String 必填
 * @param {*} width 条码宽度  String/Number 必填
 * @param {*} height 条码高度 String/Number  必填
 * @param {*} bgcolor 条码背景颜色  String选填
 * @param {*} color 条码颜色  String 选填
 * @param {*} padding_width  条码左右边距  String/Number 选填
 * @param {*} padding_height   条码上下边距 String/Number 选填
 * @param {boolean} convert 是否把二维码转换成图片
 * @param {function} callback 函数的回调
 */

function barc(
  id,
  code,
  width,
  height,
  convert,
  $this,
  callback,
  bgcolor,
  color,
  padding_width,
  padding_height,

) {
  barcode.code128(
    id,
    code,
    convert_length(width),
    convert_length(height),
    bgcolor,
    color,
    padding_width,
    padding_height,
    convert,
    $this,
    callback
  );
}

barcode.js核心代码

/**
 *
 * @param {*} ctx   canvas 的id
 * @param {*} text   内容条码
 * @param {*} width  条码宽度
 * @param {*} height 条码高度
 * @param {*} bgcolor  条码背景颜色
 * @param {*} color   条码颜色
 * @param {*} padding_width  条码左右边距
 * @param {*} padding_height  条码上下边距
 *
 */
exports.code128 = function (
  id,
  text,
  width,
  height,
  bgcolor,
  color,
  padding_width,
  padding_height,
  convert,
  $this,
  callback
) {
  console.log($this,callback);
  var ctx = wx.createCanvasContext(id)
  width = parseInt(width);
  padding_width = parseInt(padding_width);
  padding_height = parseInt(padding_height) || 0;

  height = parseInt(height);

  var codes = stringToCode128(text);

  var g = new Graphics(
    ctx,
    width,
    height,
    bgcolor,
    color,
    padding_width,
    padding_height,
  );
  var barWeight = g.area.width / ((codes.length - 3) * 11 + 35);

  var x = g.area.left;
  var y = g.area.top;
  for (var i = 0; i < codes.length; i++) {
    var c = codes[i];
    //two bars at a time: 1 black and 1 white
    for (var bar = 0; bar < 8; bar += 2) {
      var barW = PATTERNS[c][bar] * barWeight;
      var barH = height - y - padding_height;
      //   var barH = height - y;
      var spcW = PATTERNS[c][bar + 1] * barWeight;

      //no need to draw if 0 width
      if (barW > 0) {
        g.fillFgRect(x, y, barW, barH);
      }

      x += barW + spcW;
    }
  }
  //  false,则在本次调用绘制之前 native 层会先清空画布再继续绘制;true,则保留当前画布上的内容
  ctx.draw(false,function(){
    if (convert) {
      wx.canvasToTempFilePath({
        canvasId:id,
        success:function(res){
          console.log(res);
          request.wxUploadImage({
            tempFilePaths: res.tempFilePath,
          }).then(res=>{
            if (res.code == 200) {
              callback(res.data.picLinkUrl)
            }else{
              console.log("图片转换失败:",res.msg);
            }
          })
       
        }
      })
    }else {
      console.log("没设置二维码转图片");
    }

  });
};

语雀详细解析(仅本人使用)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值