持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
canvas
Canvas API 提供了一个通过JavaScript 和 HTML的
<canvas>
元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。Canvas API 主要聚焦于 2D 图形。而同样使用<canvas>
元素的 WebGL API 则用于绘制硬件加速的 2D 和 3D 图形。
<canvas>
最早由 Apple 引入 WebKit,用于 Mac OS X 的 Dashboard,随后被各个浏览器实现。如今,所有主流的浏览器都支持它。
通过canvas,我们几乎可以实现任意我们能想到的形状的绘制。今天我们就借助canvas去实现一个抽奖的功能。
lucky-canvas实践
这里借助lucky-canvas插件快速实现。该插件中奖品 / 文字 / 图片 / 颜色 / 按钮均可自由配置;支持同步 / 异步抽奖;中奖概率前 / 后端可控;支持 JS / TS / JQ / Vue / React / 微信小程序 / UniApp / Taro 等;并且多端使用 / 表现形式完全一致;自动根据设备 dpr 调整清晰度;并支持使用 百分比 / rem / rpx 属性来适配移动端布局
实现转盘抽奖demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#my-lucky {
margin: 0 auto;
}
</style>
</head>
<body>
<div id="my-lucky"></div>
<script src="https://unpkg.com/lucky-canvas@1.7.24"></script>
<script>
const myLucky = new LuckyCanvas.LuckyWheel("#my-lucky", {
width: "240px",
height: "240px",
blocks: [
{ padding: "20px" },
{
padding: "20px",
imgs: [
{
src: "./background5.png",
width: "100%",
rotate: true,
},
],
},
],
prizes: [
{
range: 10,
fonts: [
{
text: "ipad",
fontSize: "10px",
},
],
},
{
range: 10,
fonts: [
{
text: "罗技键鼠一套",
fontSize: "10px",
},
],
},
{
range: 10,
fonts: [
{
text: "小米显示器",
fontSize: "10px",
},
],
},
{
range: 10,
fonts: [
{
text: "空气净化器",
fontSize: "10px",
},
],
},
{
range: 10,
fonts: [
{
text: "iPhone13",
fontSize: "10px",
},
],
},
{
range: 10,
fonts: [
{
text: "小米扫地机器人",
fontSize: "10px",
},
],
},
{
range: 10,
fonts: [
{
text: "防蓝光眼镜",
fontSize: "10px",
},
],
},
{
range: 10,
fonts: [
{
text: "switch一台",
fontSize: "10px",
},
],
},
],
defaultConfig: {
speed: 15,
},
buttons: [
{
radius: "45%",
imgs: [
{
src: "./zhizhen.png",
width: "120%",
top: "-144%",
},
],
},
],
start: function () {
// 开始游戏
myLucky.play();
// 使用定时器模拟接口
setTimeout(() => {
// 结束游戏
myLucky.stop();
}, 3000);
},
});
// 开始
// myLucky.play()
</script>
</body>
</html>
实现九宫格抽奖demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#my-lucky {
margin: 0 auto;
}
</style>
</head>
<body>
<div id="my-lucky"></div>
<script src="https://unpkg.com/lucky-canvas@1.7.24"></script>
<script>
const prizeImg = [
{
src: "./emoji (1).png",
width: "50%",
top: "25%",
},
{
src: "./emoji (2).png",
width: "50%",
top: "25%",
},
{
src: "./emoji (3).png",
width: "50%",
top: "25%",
},
{
src: "./emoji (4).png",
width: "50%",
top: "25%",
},
];
const myLucky = new LuckyCanvas.LuckyGrid("#my-lucky", {
width: "200px",
height: "200px",
blocks: [
{ padding: "10px", background: "#869cfa" },
{ padding: "10px", background: "#e9e8fe" },
],
prizes: [
{ x: 0, y: 0, imgs: [prizeImg[0]] },
{ x: 1, y: 0, imgs: [prizeImg[1]] },
{ x: 2, y: 0, imgs: [prizeImg[2]] },
{ x: 2, y: 1, imgs: [prizeImg[3]] },
{ x: 2, y: 2, imgs: [prizeImg[0]] },
{ x: 1, y: 2, imgs: [prizeImg[1]] },
{ x: 0, y: 2, imgs: [prizeImg[2]] },
{ x: 0, y: 1, imgs: [prizeImg[3]] },
],
defaultStyle: {
background: "#b8c5f2",
},
buttons: [
{
x: 1,
y: 1,
background: "rgba(0,0,0,0)",
imgs: [
{
src: "./play.png",
width: "100%",
height: "100%",
},
],
},
],
start: function () {
// 开始游戏
myLucky.play();
// 使用定时器模拟接口
setTimeout(() => {
// 结束游戏
myLucky.stop();
}, 3000);
},
});
</script>
</body>
</html>
实现老虎机抽奖demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#my-lucky {
margin: 0 auto;
}
</style>
</head>
<body>
<div id="my-lucky"></div>
<script src="https://unpkg.com/lucky-canvas@1.7.24"></script>
<script>
const myLucky = new LuckyCanvas.SlotMachine("#my-lucky", {
width: "240px",
height: "180px",
// 背景配置
blocks: [
{ padding: "10px", background: "#869cfa" },
{ padding: "10px", background: "#e9e8fe" },
],
//折这插槽转速、方向
slots: [
{ speed: 5, direction: 1 },
{ speed: 5, direction: -1 },
{ speed: 5, direction: 1 },
],
// 奖品
prizes: [
{
background: "#bac5ee",
borderRadius: "10px",
imgs: [
{
width: "60%",
top: "20%",
src: "./emoji (1).png",
},
],
},
{
background: "#bac5ee",
borderRadius: "10px",
imgs: [
{
width: "60%",
top: "20%",
src: "./emoji (2).png",
},
],
},
{
background: "#bac5ee",
borderRadius: "10px",
imgs: [
{
width: "60%",
top: "20%",
src: "./emoji (3).png",
},
],
},
{
background: "#bac5ee",
borderRadius: "10px",
imgs: [
{
width: "60%",
top: "20%",
src: "./emoji (4).png",
},
],
},
],
defaultConfig: {
rowSpacing: "10px", //行间距
colSpacing: "10px",
},
});
// 开始游戏
const playGame = () => {
myLucky.play();
setTimeout(() => {
// 假设 4 种结果
const res = [
[9, 9, 6],
[0, 0, 7],
[6, 9, 1],
[8, 2, 8],
];
// 随机取一组数据
const index = res[(Math.random() * 4) >> 0];
// 调用 stop 方法停止游戏
myLucky.stop(index);
}, 500);
};
// 循环演示
playGame();
// setInterval(() => {
// playGame()
// }, 6000)
</script>
</body>
</html>
lucky-canvas采用monorepo方式管理packages
项目使用lerna实现多包管理,主包为core目录,副包为各平台特性包,例如:react、taro、uni、vue、微信小程序包。
这里放一张monorepo和传统mutalrepo区别。
结语
该插件可配置参数还很多,可以根据你的需求实现很多我们常见的抽奖场景,官网提供了不少简单的案例,但是复杂需求就要靠自己一步步配置参数实现了。 注:示例中代码均可以在github中查看,可直接运行。