前言
最近在公司项目原生小程序开发中遇到UI给出的一张不规则图形需要增加点击事件,产品需求是除在这张图片点击触发事件,不包含透明区域,也是头次遇见这个需求,但这个问题也是前端开发中经常会出现和遇到的问题,可能之前做B端项目很少有遇到,此篇文章主要记录该需求的解决方案,废话不多说上方案和代码
方案一:给图片对应区域增加点击热点
这个方案实现起来很简单,就是在对应区域增加一个块级标签,定位到图片对应区域,给该块级标签增加点击事件触发相应操作,代码如下
<view class="box-img-wrapper">
<image class="box-img" src="https://assets.xxxx.com/assets/xxx.png" />
<view class="hot-deal-img-top" catchtap="handle">
</view>
<view class="hot-deal-img-bottom"catchtap="handle">
</view>
</view>
.box-img-wrapper {
position: relative;
.box-img {
width: 300rpx;
height: 464rpx;
margin: 0 auto;
display: block;
}
.hot-deal-img-top {
position: absolute;
top: 0;
left: 50%;
width: 188rpx;
height: 45rpx;
}
.hot-deal-img-bottom {
position: absolute;
top: 45rpx;
left: 50%;
transform: translateX(-150rpx);
width: 300rpx;
height: 350rpx;
}
}
handle() {
//Todo 对应事件操作
console.log(22222)
}
- 优点:简单易实现,完全靠css来实现
- 缺点:仍然会存在盲区,多一点区域或者少一点
方案二:类似方案一,将图片分块切然后拼接,不推荐该方案
方案三:借助convas来绘制该张图片,获取到具体rgba值后对透明度为0的区域直接return,代码如下
<view class="container" bindtap="handleTap">
<canvas id="myCanvas" type="2d"></canvas>
</view>
Page({
data: {
},
onLoad: function () {
const imageSrc = 'https://assets.xxxx.com/assets/xxx.png';
wx.getImageInfo({
src: imageSrc,
success: res => {
const width = res.width;
const height = res.height;
this.createConvasImage(imageSrc,width,height)
}
})
},
createConvasImage(imgUrl,imgW,imgH) {
wx.createSelectorQuery()
.select('#myCanvas') // 在 WXML 中填入的 id
.node(({
node: canvas
}) => {
const context = canvas.getContext('2d')
const image = canvas.createImage()
image.onload = () => {
context.drawImage(
image,
0,
0,
imgW,
imgH
)
}
image.src = imgUrl
})
.exec()
},
onReady() {
// 获取系统信息
wx.getSystemInfo({
success: res => {
console.log(res);
this.setData({
windowWidth: res.windowWidth,
windowHeight: res.windowHeight,
});
this.setData({
// 屏幕宽度 375px = 750rpx,1px=2rpx
// 1px = (750 / 屏幕宽度)rpx;
// 1rpx = (屏幕宽度 / 750)px;
ratio: 750 / this.data.windowWidth
});
}
});
},
handleTap: function (event) {
const x = event.detail.x;
const y = event.detail.y;
wx.createSelectorQuery()
.select('#myCanvas') // 在 WXML 中填入的 id
.node(({
node: canvas
}) => {
const context = canvas.getContext('2d')
const imageData = context.getImageData(x, y, 1, 1)
console.log(imageData)
if(imageData.data[3] === 0) {
return
}
// todo 对应操作
})
.exec()
}
});
- 优点:无盲区,就是完全符合产品的需求的实现方案
- 缺点:方案较复杂,还要考虑兼容问题,不适用于首页等页面,体验感会不乐观