从零配置lucky-canvas九宫格抽奖:微信小程序兼容性踩坑指南
最近在做一个微信小程序营销活动,产品经理甩过来一个需求,要做一个九宫格抽奖功能,要求动画流畅、样式精美,还得适配不同尺寸的屏幕。我第一反应就是想到了lucky-canvas这个开源组件,毕竟它在GitHub上有8.7k的star,社区口碑一直不错。但真正上手之后才发现,在微信小程序环境下,特别是结合Taro框架使用时,会遇到不少官方文档没详细说明的坑。
这篇文章就是我在实际项目中趟过的路,从环境搭建到最终上线,把那些让人头疼的兼容性问题一个个解决掉的过程记录下来。如果你也在用Taro开发微信小程序,并且需要集成lucky-canvas的九宫格抽奖功能,那这篇文章应该能帮你省下不少调试时间。
1. 环境准备与基础配置
1.1 项目初始化与依赖安装
首先,确保你已经有一个基于Taro 3.x的微信小程序项目。如果没有,可以通过以下命令快速创建一个:
# 使用Taro CLI创建项目
taro init my-lucky-app
# 进入项目目录
cd my-lucky-app
# 安装lucky-canvas的Taro版本
npm install @lucky-canvas/taro --save
这里有个细节需要注意:一定要确认安装的是Taro专用版本。lucky-canvas提供了多个平台的适配包,如果你不小心安装了@lucky-canvas/vue或者@lucky-canvas/react,在小程序里是跑不起来的。我刚开始就犯了这个错误,调试了半天才发现包不对。
安装完成后,检查一下package.json里的依赖版本。我当前项目使用的是:
{
"dependencies": {
"@lucky-canvas/taro": "^0.1.13",
"@tarojs/taro": "^3.6.0",
"@tarojs/components": "^3.6.0"
}
}
1.2 基础组件引入与配置
在需要使用九宫格抽奖的页面中,引入LuckyGrid组件。这里有个Taro特有的写法需要注意:
// pages/lottery/index.jsx
import { Component } from 'react'
import { View } from '@tarojs/components'
import LuckyGrid from '@lucky-canvas/taro/lucky-grid'
class LotteryPage extends Component {
constructor(props) {
super(props)
this.state = {
blocks: [
{ padding: '10px', background: '#ff6b6b' }
],
prizes: [
{
x: 0, y: 0,
fonts: [{ text: 'iPhone 14', top: '30%' }],
imgs: [{ src: '/assets/prize1.png', width: '40px', height: '40px' }],
background: '#ffd166'
},
// 其他8个奖品配置...
],
buttons: [
{
x: 1, y: 1,
imgs: [{ src: '/assets/button.png' }]
}
]
}
}
render() {
return (
<View className='lottery-container'>
<LuckyGrid
width='600rpx'
height='600rpx'
blocks={this.state.blocks}
prizes={this.state.prizes}
buttons={this.state.buttons}
onStart={this.handleStart}
onEnd={this.handleEnd}
/>
</View>
)
}
}
注意:在微信小程序中,图片路径需要使用绝对路径。如果你把图片放在
src/assets目录下,需要确保构建时能正确复制到小程序目录。我建议在config/index.js中配置copy选项:
// config/index.js
const config = {
// ...其他配置
copy: {
patterns: [
{ from: 'src/assets/', to: 'dist/assets/' }
]
}
}
2. Canvas层级问题与解决方案
2.1 微信小程序Canvas的原生组件特性
这是我在开发过程中遇到的第一个大坑。在微信小程序里,Canvas是原生组件,它的层级是最高的,会覆盖在所有普通组件之上。这意味着如果你在抽奖组件上方有弹窗、Toast或者Modal,它们都会被Canvas挡住。
官方文档虽然提到了这个问题,但解决方案比较简略。我实际测试发现,即使在lucky-canvas内部做了优化(游戏结束后切换成图片显示),但在游戏进行中,Canvas仍然会处于顶层。
2.2 实战中的层级处理技巧
经过多次尝试,我总结出几种可行的解决方案:
方案一:使用cover-view和cover-image
这是微信小程序官方推荐的解决方案。cover-view和cover-image是专门用来覆盖在原生组件上的组件。
// 在页面中使用cover-view包裹需要覆盖的内容
<View>
<LuckyGrid
width='600rpx'
height='600rpx'
// ...其他配置
/>
{/* 使用cover-view实现弹窗 */}
<CoverView className='modal-container' hidden={!showModal}>
<CoverView className='modal-content'>
<CoverImage src='/assets/close.png' onClick={this.closeModal} />
<CoverView className='modal-text'>恭喜中奖!</CoverView>
</CoverView>
</CoverView>
</View>
对应的样式需要注意:
.modal-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
width: 80%;
background: white;
border-radius: 16rpx;
padding: 40rpx;
position: relative;
}
方案二:动态控制Canvas显示时机
另一种思路是在需要显示弹窗时,暂时隐藏Canvas组件。lucky-canvas提供了init方法,可以在隐藏后重新初始化:
class LotteryPage extends Component {
state = {
showCanvas: true,
showModal: false
}
// 显示弹窗前隐藏Canvas
showPrizeModal = () => {
this.setState({ showCanvas: false }, () => {
setTimeout(() => {
this.setState({ showModal: true })
}, 100)
})
}
// 关闭弹窗后重新显示Canvas
clo


2万+

被折叠的 条评论
为什么被折叠?



