uni-app 如何判断点击事件真的点到了图片内容上

文章讲述了作者如何将一款已在Android上的游戏通过uni-app技术集成到微信小程序和网页端,涉及使用canvas处理用户点击事件,以及在微信小程序中遇到的层级问题及其解决方案。
摘要由CSDN通过智能技术生成

        最近在移植一款游戏,这款游戏之前是我做在安卓版本上做的一个App上酒庄园,已经在Google Play Store上线了,但是苦于国内版号发放的艰难程度,一直也没办法在各大应用商店独立上架。现在想通过uni-app技术把它集成到微信小程序、网页端及我们的另一款App上酒跨境上面,上酒跨境已经在各大应用商店上架了,借它之手应该可以很快让上酒庄园与大家见面。

              

        场景是需要在首页面根据用户点击的落点来判断点击的是哪个建筑,进而进行不同的逻辑处理。做出来的效果图如图一所示,做法是将图二作为背景,然后把同宽高的几张建筑图片(图三图四等)依次叠放在背景图之上,因为建筑图片其他部分是透明的,所以图片契合度不会有什么问题。图片使用aspectFill缩放方式,保证短边完全显示,可以减少屏幕适配所需工作。

        点击事件的处理,按照安卓的做法是通过bitmap类的getPixel方法获取bitmap在当前点击落点的颜色值,为0则表示当前bitmap在此落点为透明,可以穿透到下个图层继续判断,不为0则便是此次点击确实是点到建筑了,可以进行下一步操作。

        移植到uni-app我相信也是有类似方法的,参考了很多资料发现了一个方法uni.canvasGetImageData(OBJECT,this),具体用法如下:

        1. 这个方法使用要依赖于canvas控件,所以要在template中定义canvas控件

        <canvas canvas-id="kjsc" />

        2.先下载图片,通过canvas-id获取canvas实例,然后根据下载到的临时文件路径及左、上、宽、高四个属性绘制。

                uni.downloadFile({
                    url: that.hostUrl + '/images/sjzy/kjsc.png',
                    success: function(res) {
                        const kjsc = uni.createCanvasContext('kjsc');
                        kjsc.drawImage(res.tempFilePath, that.left, that.top,
                            that.realWidth, that.realHeight);
                        kjsc.draw(true);
                    }
                });

        3.定义点击事件,点击事件只需要在最上面一个canvas定义就行了,通过$event可以获取到当前的点击详细信息,包括x、y坐标等。

        <canvas canvas-id="pty" @tap="ptyClick($event)" />

        4.在点击事件中调用canvasGetImageData方法对落点进行判断,如果是当前建筑则处理,如果不是则转到下一建筑判断。需要注意的是调用canvasGetImageData方法时width、height可以随便传,但验证时只验证返回数组的前四位。返回数组会将范围矩阵中所有像素点的rgba值依次返回,中间没有标识,我们自己将它拆成四位一组来进行判断即可。只判断前4位,如果都为0则转到下一建筑判断,有一位不为0就可以消费掉点击事件。

        
        var x = event.detail.x;
        var y = event.detail.y;

        uni.canvasGetImageData({
                    canvasId: 'pty',
                    x,
                    y,
                    width: 1,
                    height: 1,
                    success: function(res) {
                        if (res.data[0] == 0 && res.data[1] == 0 && res.data[2] == 0 && res.data[3] == 0) {
                            that.nzgcClick(e);
                        } else {
                            uni.navigateTo({
                                url: '/sjzy/pages/grapery/grapery?avatarPath=' + that.avatarPath +
                                    '&beans=' + that.beans + '&fl=' + that.fl
                            })
                        }
                    }
                }, this);

        这种做法在网页端跟app端是没有问题的,但在微信小程序上会有显示问题,因为canvas在微信小程序中为原生控件,它的层级太高了,其它放在canvas上面的控件都会被系统排挤到canvas下方,这个问题至今还没有解决,但可以通过两种方式规避。

        第一种是用cover-view与cover-image,这是微信小程序为了解决canvas等控件层级过高而退出的解决办法,弊端是没办法加载输入框、rich-text富文本等,灵活性相当低。

        第二种办法是舍弃微信小程序版本,通过微信小程序版本中的web-view访问网页版路径来实现集成。

        大家如果有其他方法欢迎留言讨论。

  • 31
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值