Web前端 lucky-canvas【大转盘 & 九宫格 & 老虎机】抽奖插件(适用JS/TS、Vue、React、微信小程序、Uniapp和Taro)

Web前端 lucky-canvas 抽奖插件(JS/TS、Vue、React、微信小程序、Uniapp和Taro)

基于 JS + Canvas 实现的【大转盘 & 九宫格 & 老虎机】抽奖,致力于为 WEB 前端提供一个功能强大且专业可靠的营销组件,只需要通过简单配置即可实现自由化定制,帮助你快速的完成产品需求

  1. 自由配置
    奖品 / 文字 / 图片 / 颜色 / 按钮均可自由配置;支持同步 / 异步抽奖;中奖概率前 / 后端可控
  2. 多端适配
    支持 JS / TS / JQ / Vue / React / 微信小程序 / UniApp / Taro 等;并且多端使用 / 表现形式完全一致
  3. 响应式
    自动根据设备 dpr 调整清晰度;并支持使用 百分比 / rem / rpx 属性来适配移动端布局

更多自定义样式:


1-1. 在JS/TS中使用:

方式1:通过 script 标签引入,CDN 链接任选一个即可

html 复制代码
<!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>
        body{
            display: flex;
            justify-content: space-evenly;
            align-items: center;
            width: 100vw;
            height: 100vh;
        }
    </style>
</head>
<body>
    <div id="my-luckyWheel"></div>
    <div id="my-luckyGrid"></div>
    <div onclick="playGame()" id="my-slotMachine"></div>
</body>
<script src="https://unpkg.com/lucky-canvas@1.7.25"></script>
<script>
    # 大转盘
    const luckyWheel = new LuckyCanvas.LuckyWheel('#my-luckyWheel', {
      width: '250px',
      height: '250px',
      blocks: [{ padding: '10px', background: '#617df2' }],
      prizes: [
        { background: '#e9e8fe', fonts: [{ text: '0' }] },
        { background: '#b8c5f2', fonts: [{ text: '1' }] },
        { background: '#e9e8fe', fonts: [{ text: '2' }] },
        { background: '#b8c5f2', fonts: [{ text: '3' }] },
        { background: '#e9e8fe', fonts: [{ text: '4' }] },
        { background: '#b8c5f2', fonts: [{ text: '5' }] },
      ],
      buttons: [{
        radius: '35%',
        background: '#8a9bf3',
        pointer: true,
        fonts: [{ text: '开始', top: '-10px' }]
      }],
      start: function () {
        // 开始游戏
        luckyWheel.play()
        // 使用定时器模拟接口
        setTimeout(() => {
          // 结束游戏
          luckyWheel.stop(0)
        }, 3000)
      }
    })


    # 九宫格
    const luckyGrid = new LuckyCanvas.LuckyGrid('#my-luckyGrid', {
    width: '200px',
    height: '200px',
    blocks: [
      { padding: '10px', background: '#869cfa' },
      { padding: '10px', background: '#e9e8fe' },
    ],
    prizes: [
      { x: 0, y: 0 },
      { x: 1, y: 0 },
      { x: 2, y: 0 },
      { x: 2, y: 1 },
      { x: 2, y: 2 },
      { x: 1, y: 2 },
      { x: 0, y: 2 },
      { x: 0, y: 1 },
    ],
    buttons: [
      {
        x: 1, y: 1,
        background: '#9c9dd8',
        fonts: [{ text: '开始', top: '25%' }],
      },
    ],
    defaultStyle: {
      background: '#b8c5f2'
    },
    start: function () {
      // 开始游戏
      luckyGrid.play()
      // 使用定时器模拟接口
      setTimeout(() => {
        // 结束游戏, 并抽第0号奖品
        luckyGrid.stop(0)
      }, 3000)
    }
  })


  # 老虎机
  const slotMachine = new LuckyCanvas.SlotMachine('#my-slotMachine', {
    width: '240px',
    height: '180px',
    blocks: [
      { padding: '10px', background: '#869cfa' },
      { padding: '10px', background: '#e9e8fe' },
    ],
    slots: [
      { order: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], direction: 1 },
      { order: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], direction: -1 },
      { order: [2, 3, 4, 5, 6, 7, 8, 9, 0, 1], direction: 1 },
    ],
    prizes: [
      { fonts: [{ text: '0', top: '15%' }] },
      { fonts: [{ text: '1', top: '15%' }] },
      { fonts: [{ text: '2', top: '15%' }] },
      { fonts: [{ text: '3', top: '15%' }] },
      { fonts: [{ text: '4', top: '15%' }] },
      { fonts: [{ text: '5', top: '15%' }] },
      { fonts: [{ text: '6', top: '15%' }] },
      { fonts: [{ text: '7', top: '15%' }] },
      { fonts: [{ text: '8', top: '15%' }] },
      { fonts: [{ text: '9', top: '15%' }] },
    ],
    defaultStyle: {
      borderRadius: Infinity,
      background: '#bac5ee',
      fontSize: '32px',
      fontColor: '#333'
    },
    defaultConfig: {
      rowSpacing: '20px',
      colSpacing: '10px'
    },
    end (prize) {
      // console.log(prize)
    }
  })
  // 开始游戏
  const playGame = () => {
    slotMachine.play()
    setTimeout(() => {
      // 假设 4 种结果
      const res = [
        [9, 9, 6],
        [0, 0, 7],
        [6, 6, 6],
        [8, 8, 8]
      ]
      // 随机取一组数据
      const index = res[Math.random() * 4 >> 0]
      // 调用 stop 方法停止游戏
      slotMachine.stop(index)
    }, 500);
  }
  </script>
  
</html>

方式 2:通过 import 引入

html 复制代码
# npm 安装
npm install lucky-canvas@latest

# 或者 yarn 安装
yarn add lucky-canvas@latest
html 复制代码
<div id="my-luckyWheel"></div>
<div id="my-luckyGrid"></div>
<div onclick="playGame()" id="my-slotMachine"></div>

<script>
import { LuckyWheel,LuckyGrid,SlotMachine } from 'lucky-canvas'

# 大转盘
 const myLucky = new LuckyWheel('#my-luckyWheel', {
   width: '200px',
   height: '200px',
   blocks: [{ padding: '13px', background: '#617df2' }],
   prizes: [
     { fonts: [{ text: '0', top: '10%' }], background: '#e9e8fe' },
     { fonts: [{ text: '1', top: '10%' }], background: '#b8c5f2' },
     { fonts: [{ text: '2', top: '10%' }], background: '#e9e8fe' },
     { fonts: [{ text: '3', top: '10%' }], background: '#b8c5f2' },
     { fonts: [{ text: '4', top: '10%' }], background: '#e9e8fe' },
     { fonts: [{ text: '5', top: '10%' }], background: '#b8c5f2' },
   ],
 })

# 九宫格
 const luckyGrid = new LuckyGrid('#my-luckyGrid', {
    width: '200px',
    height: '200px',
    blocks: [
      { padding: '10px', background: '#869cfa' },
      { padding: '10px', background: '#e9e8fe' },
    ],
    prizes: [
      { x: 0, y: 0 },
      { x: 1, y: 0 },
      { x: 2, y: 0 },
      { x: 2, y: 1 },
      { x: 2, y: 2 },
      { x: 1, y: 2 },
      { x: 0, y: 2 },
      { x: 0, y: 1 },
    ],
    buttons: [
      {
        x: 1, y: 1,
        background: '#9c9dd8',
        fonts: [{ text: '开始', top: '25%' }],
      },
    ],
    defaultStyle: {
      background: '#b8c5f2'
    },
    start: function () {
      // 开始游戏
      luckyGrid.play()
      // 使用定时器模拟接口
      setTimeout(() => {
        // 结束游戏, 并抽第0号奖品
        luckyGrid.stop(0)
      }, 3000)
    }
  })

# 老虎机
  const slotMachine = new SlotMachine('#my-slotMachine', {
    width: '240px',
    height: '180px',
    blocks: [
      { padding: '10px', background: '#869cfa' },
      { padding: '10px', background: '#e9e8fe' },
    ],
    slots: [
      { order: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], direction: 1 },
      { order: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], direction: -1 },
      { order: [2, 3, 4, 5, 6, 7, 8, 9, 0, 1], direction: 1 },
    ],
    prizes: [
      { fonts: [{ text: '0', top: '15%' }] },
      { fonts: [{ text: '1', top: '15%' }] },
      { fonts: [{ text: '2', top: '15%' }] },
      { fonts: [{ text: '3', top: '15%' }] },
      { fonts: [{ text: '4', top: '15%' }] },
      { fonts: [{ text: '5', top: '15%' }] },
      { fonts: [{ text: '6', top: '15%' }] },
      { fonts: [{ text: '7', top: '15%' }] },
      { fonts: [{ text: '8', top: '15%' }] },
      { fonts: [{ text: '9', top: '15%' }] },
    ],
    defaultStyle: {
      borderRadius: Infinity,
      background: '#bac5ee',
      fontSize: '32px',
      fontColor: '#333'
    },
    defaultConfig: {
      rowSpacing: '20px',
      colSpacing: '10px'
    },
    end (prize) {
      // console.log(prize)
    }
  })
  // 开始游戏
  const playGame = () => {
    slotMachine.play()
    setTimeout(() => {
      // 假设 4 种结果
      const res = [
        [9, 9, 6],
        [0, 0, 7],
        [6, 6, 6],
        [8, 8, 8]
      ]
      // 随机取一组数据
      const index = res[Math.random() * 4 >> 0]
      // 调用 stop 方法停止游戏
      slotMachine.stop(index)
    }, 500);
  }
</script>
1-2. 在Vue中使用:

方式 1:通过 import 引入

1.首先安装插件

html 复制代码
# npm 安装
npm install @lucky-canvas/vue@latest

# 或者 yarn 安装
yarn add @lucky-canvas/vue@latest

2.在main.js 引入插件

javascript 复制代码
# Vue2
import VueLuckyCanvas from '@lucky-canvas/vue'
Vue.use(VueLuckyCanvas)

# Vue3
import VueLuckyCanvas from '@lucky-canvas/vue'
createApp(App).use(VueLuckyCanvas).mount('#app')

3.在组件上使用

Vue2 :

html 复制代码
<template>
  <LuckyWheel
    ref="myLuckyWheel"
    width="250px"
    height="250px"
    :prizes="myLuckyWheel.prizes"
    :blocks="myLuckyWheel.blocks"
    :buttons="myLuckyWheel.buttons"
    @start="startLuckyWheel"
    @end="endLuckyWheel"
  />
  <LuckyGrid
    ref="myLuckyGrid"
    width="200px"
    height="200px"
    :prizes="myLuckyGrid.prizes"
    :blocks="myLuckyGrid.blocks"
    :buttons="myLuckyGrid.buttons"
    :defaultStyle="myLuckyGrid.defaultStyle"
    @start="startLuckyGrid"
    @end="endLuckyGrid"
  />

  <SlotMachine
    ref="mySlotMachine"
    width="240px"
    height="180px"
    :blocks="mySlotMachine.blocks"
    :slots="mySlotMachine.slots"
    :prizes="mySlotMachine.prizes"
    :defaultStyle="mySlotMachine.defaultStyle"
    :defaultConfig="mySlotMachine.defaultConfig"
    @click="startSlotMachine"
    @end="endSlotMachine"
  />
</template>

<script>
export default {
  data() {
    return {
      // 大转盘
      myLuckyWheel: {
        blocks: [{ padding: "13px", background: "#617df2" }],
        prizes: [
          { fonts: [{ text: "0", top: "10%" }], background: "#e9e8fe" },
          { fonts: [{ text: "1", top: "10%" }], background: "#b8c5f2" },
          { fonts: [{ text: "2", top: "10%" }], background: "#e9e8fe" },
          { fonts: [{ text: "3", top: "10%" }], background: "#b8c5f2" },
          { fonts: [{ text: "4", top: "10%" }], background: "#e9e8fe" },
          { fonts: [{ text: "5", top: "10%" }], background: "#b8c5f2" },
        ],
        buttons: [
          {
            radius: "35%",
            background: "#8a9bf3",
            pointer: true,
            fonts: [{ text: "开始", top: "-10px" }],
          },
        ],
      },

	  // 九宫格
      myLuckyGrid: {
        blocks: [
          { padding: "10px", background: "#869cfa" },
          { padding: "10px", background: "#e9e8fe" },
        ],
        prizes: [
          { x: 0, y: 0 },
          { x: 1, y: 0 },
          { x: 2, y: 0 },
          { x: 2, y: 1 },
          { x: 2, y: 2 },
          { x: 1, y: 2 },
          { x: 0, y: 2 },
          { x: 0, y: 1 },
        ],
        buttons: [
          {
            x: 1,
            y: 1,
            background: "#9c9dd8",
            fonts: [{ text: "开始", top: "25%" }],
          },
        ],
        defaultStyle: {
          background: "#b8c5f2",
        },
      },

	  // 老虎机
      mySlotMachine: {
        blocks: [
          { padding: "10px", background: "#869cfa" },
          { padding: "10px", background: "#e9e8fe" },
        ],
        slots: [
          { order: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], direction: 1 },
          { order: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], direction: -1 },
          { order: [2, 3, 4, 5, 6, 7, 8, 9, 0, 1], direction: 1 },
        ],
        prizes: [
          { fonts: [{ text: "0", top: "15%" }] },
          { fonts: [{ text: "1", top: "15%" }] },
          { fonts: [{ text: "2", top: "15%" }] },
          { fonts: [{ text: "3", top: "15%" }] },
          { fonts: [{ text: "4", top: "15%" }] },
          { fonts: [{ text: "5", top: "15%" }] },
          { fonts: [{ text: "6", top: "15%" }] },
          { fonts: [{ text: "7", top: "15%" }] },
          { fonts: [{ text: "8", top: "15%" }] },
          { fonts: [{ text: "9", top: "15%" }] },
        ],
        defaultStyle: {
          borderRadius: Infinity,
          background: "#bac5ee",
          fontSize: "32px",
          fontColor: "#333",
        },
        defaultConfig: {
          rowSpacing: "20px",
          colSpacing: "10px",
        },
      },
    };
  },
  methods: {
    // 大转盘
    startLuckyWheel() {
      this.$refs.myLuckyWheel.play();
      setTimeout(() => {
        const index = 0;
        this.$refs.myLuckyWheel.stop(index);
      }, 3000);
    },
    endLuckyWheel(prize) {
      console.log(prize);
    },

    // 九宫格
    startLuckyGrid() {
      this.$refs.myLuckyGrid.play();
      setTimeout(() => {
        this.$refs.myLuckyGrid.stop(0);
      }, 3000);
    },
    endLuckyGrid(prize) {
      console.log(prize);
    },

    // 老虎机
    startSlotMachine() {
      this.$refs.mySlotMachine.play();
      setTimeout(() => {
        // 假设 4 种结果
        const res = [
          [9, 9, 6],
          [0, 0, 7],
          [6, 6, 6],
          [8, 8, 8],
        ];
        // 随机取一组数据
        const index = res[(Math.random() * 4) >> 0];
        // 调用 stop 方法停止游戏
        this.$refs.mySlotMachine.stop(index);
      }, 500);
    },
    endSlotMachine(prize) {
      console.log(prize);
    },
  },
};
</script>

Vue3 版本:

html 复制代码
<template>
  <LuckyWheel
    ref="myLuckyWheel"
    width="250px"
    height="250px"
    :prizes="myLuckyWheel.prizes"
    :blocks="myLuckyWheel.blocks"
    :buttons="myLuckyWheel.buttons"
    @start="startLuckyWheel"
    @end="endLuckyWheel"
  />
  <LuckyGrid
    ref="myLuckyGrid"
    width="200px"
    height="200px"
    :prizes="myLuckyGrid.prizes"
    :blocks="myLuckyGrid.blocks"
    :buttons="myLuckyGrid.buttons"
    :defaultStyle="myLuckyGrid.defaultStyle"
    @start="startLuckyGrid"
    @end="endLuckyGrid"
  />

  <SlotMachine
    ref="mySlotMachine"
    width="240px"
    height="180px"
    :blocks="mySlotMachine.blocks"
    :slots="mySlotMachine.slots"
    :prizes="mySlotMachine.prizes"
    :defaultStyle="mySlotMachine.defaultStyle"
    :defaultConfig="mySlotMachine.defaultConfig"
    @click="startSlotMachine"
    @end="endSlotMachine"
  />
</template>

<script setup>
import { ref } from "vue";

// 大转盘
const myLuckyWheel = ref({
  blocks: [{ padding: "13px", background: "#617df2" }],
  prizes: [
    { fonts: [{ text: "0", top: "10%" }], background: "#e9e8fe" },
    { fonts: [{ text: "1", top: "10%" }], background: "#b8c5f2" },
    { fonts: [{ text: "2", top: "10%" }], background: "#e9e8fe" },
    { fonts: [{ text: "3", top: "10%" }], background: "#b8c5f2" },
    { fonts: [{ text: "4", top: "10%" }], background: "#e9e8fe" },
    { fonts: [{ text: "5", top: "10%" }], background: "#b8c5f2" },
  ],
  buttons: [
    {
      radius: "35%",
      background: "#8a9bf3",
      pointer: true,
      fonts: [{ text: "开始", top: "-10px" }],
    },
  ],
});
const startLuckyWheel = () => {
  // 调用抽奖组件的play方法开始游戏
  myLuckyWheel.value.play();
  // 模拟调用接口异步抽奖
  setTimeout(() => {
    // 假设后端返回的中奖索引是0
    const index = 0;
    // 调用stop停止旋转并传递中奖索引
    myLuckyWheel.value.stop(index);
  }, 3000);
};
const endLuckyWheel = (prize) => {
  console.log(prize);
};

// 九宫格
const myLuckyGrid = ref({
  blocks: [
    { padding: "10px", background: "#869cfa" },
    { padding: "10px", background: "#e9e8fe" },
  ],
  prizes: [
    { x: 0, y: 0 },
    { x: 1, y: 0 },
    { x: 2, y: 0 },
    { x: 2, y: 1 },
    { x: 2, y: 2 },
    { x: 1, y: 2 },
    { x: 0, y: 2 },
    { x: 0, y: 1 },
  ],
  buttons: [
    {
      x: 1,
      y: 1,
      background: "#9c9dd8",
      fonts: [{ text: "开始", top: "25%" }],
    },
  ],
  defaultStyle: {
    background: "#b8c5f2",
  },
});
const startLuckyGrid = () => {
  myLuckyGrid.value.play();
  setTimeout(() => {
    myLuckyGrid.value.stop(0);
  }, 3000);
};
const endLuckyGrid = (prize) => {
  console.log(prize);
};

// 老虎机
const mySlotMachine = ref({
  blocks: [
    { padding: "10px", background: "#869cfa" },
    { padding: "10px", background: "#e9e8fe" },
  ],
  slots: [
    { order: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], direction: 1 },
    { order: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], direction: -1 },
    { order: [2, 3, 4, 5, 6, 7, 8, 9, 0, 1], direction: 1 },
  ],
  prizes: [
    { fonts: [{ text: "0", top: "15%" }] },
    { fonts: [{ text: "1", top: "15%" }] },
    { fonts: [{ text: "2", top: "15%" }] },
    { fonts: [{ text: "3", top: "15%" }] },
    { fonts: [{ text: "4", top: "15%" }] },
    { fonts: [{ text: "5", top: "15%" }] },
    { fonts: [{ text: "6", top: "15%" }] },
    { fonts: [{ text: "7", top: "15%" }] },
    { fonts: [{ text: "8", top: "15%" }] },
    { fonts: [{ text: "9", top: "15%" }] },
  ],
  defaultStyle: {
    borderRadius: Infinity,
    background: "#bac5ee",
    fontSize: "32px",
    fontColor: "#333",
  },
  defaultConfig: {
    rowSpacing: "20px",
    colSpacing: "10px",
  },
});
const startSlotMachine = () => {
  mySlotMachine.value.play();
  setTimeout(() => {
    // 假设 4 种结果
    const res = [
      [9, 9, 6],
      [0, 0, 7],
      [6, 6, 6],
      [8, 8, 8],
    ];
    // 随机取一组数据
    const index = res[(Math.random() * 4) >> 0];
    // 调用 stop 方法停止游戏
    mySlotMachine.value.stop(index);
  }, 500);
};
const endSlotMachine = (prize) => {
  console.log(prize);
};
</script>

对于出现安装/打包失败 https://github.com/buuing/lucky-canvas/issues/258(opens new window)

可能是依赖安装问题导致的, 建议切换 node@12.22.7

然后删除 node_modules 和 **-lock.json 这两个文件

再次尝试 npm install 安装所有依赖

如果还是无法使用, 你可以直接跳转 ->【在 JS / TS 中使用】并查看方式2(这个包不会出现依赖问题, 因为他没有任何依赖)

1-3. 在React中使用(示例:LuckyWheel ):

1.首先安装插件

html 复制代码
# npm 安装:
npm install @lucky-canvas/react@latest

# yarn 安装:
yarn add @lucky-canvas/react@latest

2.在组件中使用

javascript 复制代码
import React, { useState, useRef } from 'react'
import { LuckyWheel,LuckyGrid,SlotMachine } from '@lucky-canvas/react'

export default function App() {
  const [blocks] = useState([
    { padding: '10px', background: '#869cfa' }
  ])
  const [prizes] = useState([
    { background: '#e9e8fe', fonts: [{ text: '0' }] },
    { background: '#b8c5f2', fonts: [{ text: '1' }] },
    { background: '#e9e8fe', fonts: [{ text: '2' }] },
    { background: '#b8c5f2', fonts: [{ text: '3' }] },
    { background: '#e9e8fe', fonts: [{ text: '4' }] },
    { background: '#b8c5f2', fonts: [{ text: '5' }] },
  ])
  const [buttons] = useState([
    { radius: '40%', background: '#617df2' },
    { radius: '35%', background: '#afc8ff' },
    {
      radius: '30%', background: '#869cfa',
      pointer: true,
      fonts: [{ text: '开始', top: '-10px' }]
    }
  ])
  const myLucky = useRef()
  return <div>
    <LuckyWheel
      ref={myLucky}
      width="300px"
      height="300px"
      blocks={blocks}
      prizes={prizes}
      buttons={buttons}
      onStart={() => { // 点击抽奖按钮会触发star回调
        myLucky.current.play()
        setTimeout(() => {
          const index = Math.random() * 6 >> 0
          myLucky.current.stop(index)
        }, 2500)
      }}
      onEnd={prize => { // 抽奖结束会触发end回调
        alert('恭喜你抽到 ' + prize.fonts[0].text + ' 号奖品')
      }}
    />
  </div>
}
1-4. 在微信小程序中使用(示例:LuckyWheel ):

1.查看小程序项目根目录下是否有package.json文件,没有再执行下面的命令来创建该文件

javascript 复制代码
npm init -y

2.安装 npm 包

javascript 复制代码
npm install @lucky-canvas/mini@latest

3.构建 npm

  • 微信开发者工具 -> 找到左上角
  • 点击 -> 工具
  • 点击 -> 构建 npm 弹窗提示 构建成功 即可!

4.引入自定义组件

json文件:

javascript 复制代码
{
  ...
  "usingComponents": {
     "lucky-wheel": "/miniprogram_npm/@lucky-canvas/mini/lucky-wheel/index",
    "lucky-grid": "/miniprogram_npm/@lucky-canvas/mini/lucky-grid/index"
    "slot-machine": "/miniprogram_npm/@lucky-canvas/mini/slot-machine/index"
  }
  ...
}

wxml文件:

javascript 复制代码
<view>
  <lucky-wheel
    id="myLucky"
    width="600rpx"
    height="600rpx"
    blocks="{{blocks}}"
    prizes="{{prizes}}"
    buttons="{{buttons}}"
    bindstart="start"
    bindend="end"
  />
</view>

js文件:

javascript 复制代码
const app = getApp()
Page({
  data: {
    blocks: [{ padding: '13px', background: '#617df2' }],
    prizes: [
      { fonts: [{ text: '0', top: '10%' }], background: '#e9e8fe' },
      { fonts: [{ text: '1', top: '10%' }], background: '#b8c5f2' },
      { fonts: [{ text: '2', top: '10%' }], background: '#e9e8fe' },
      { fonts: [{ text: '3', top: '10%' }], background: '#b8c5f2' },
      { fonts: [{ text: '4', top: '10%' }], background: '#e9e8fe' },
      { fonts: [{ text: '5', top: '10%' }], background: '#b8c5f2' },
    ],
    buttons: [
      { radius: '50px', background: '#617df2' },
      { radius: '45px', background: '#afc8ff' },
      {
        radius: '40px', background: '#869cfa',
        pointer: true,
        fonts: [{ text: '开始\n抽奖', top: '-20px' }]
      },
    ],
  },
  start () {
    // 获取抽奖组件实例
    const child = this.selectComponent('#myLucky')
    // 调用play方法开始旋转
    child.lucky.play()
    // 用定时器模拟请求接口
    setTimeout(() => {
      // 3s 后得到中奖索引 (假设抽到第0个奖品)
      const index = 0
      // 调用stop方法然后缓慢停止
      child.lucky.stop(index)
    }, 3000)
  },
  end (event) {
    // 中奖奖品详情
    console.log(event.detail)
  }
})
1-5. 在UniApp中使用(示例:LuckyWheel ):

1.安装插件

javascript 复制代码
# npm 安装:
npm install @lucky-canvas/uni@latest

# yarn 安装:
yarn add @lucky-canvas/uni@latest

2.引入并使用

html 复制代码
<template>
  <view>
    <LuckyWheel
      ref="myLucky"
      width="600rpx"
      height="600rpx"
      :blocks="blocks"
      :prizes="prizes"
      :buttons="buttons"
      :defaultStyle="defaultStyle"
      @start="startCallBack"
      @end="endCallBack"
    />
  </view>
</template>

<script>
 // npm 下载会默认到 node_modules 里面,直接引入包名即可
  import LuckyWheel from '@lucky-canvas/uni/lucky-wheel' // 大转盘
  import LuckyGrid from '@lucky-canvas/uni/lucky-grid' // 九宫格
  import SlotMachine from '@lucky-canvas/uni/slot-machine' // 老虎机

  // 如果你是通过 HBuilderX 导入插件,那你需要指定一下路径
  // import LuckyWheel from '@/components/@lucky-canvas/uni/lucky-wheel' // 大转盘
  // import LuckyGrid from '@/components/@lucky-canvas/uni/lucky-grid' // 九宫格
  // import SlotMachine from '@/components/@lucky-canvas/uni/slot-machin' // 老虎机

  export default {
    components: { LuckyWheel, LuckyGrid, SlotMachine },
    data () {
      return {
        blocks: [{ padding: '13px', background: '#617df2' }],
        prizes: [
          { fonts: [{ text: '0', top: '10%' }], background: '#e9e8fe' },
          { fonts: [{ text: '1', top: '10%' }], background: '#b8c5f2' },
          { fonts: [{ text: '2', top: '10%' }], background: '#e9e8fe' },
          { fonts: [{ text: '3', top: '10%' }], background: '#b8c5f2' },
          { fonts: [{ text: '4', top: '10%' }], background: '#e9e8fe' },
          { fonts: [{ text: '5', top: '10%' }], background: '#b8c5f2' },
        ],
        buttons: [
          { radius: '50px', background: '#617df2' },
          { radius: '45px', background: '#afc8ff' },
          {
            radius: '40px', background: '#869cfa',
            pointer: true,
            fonts: [{ text: '开始\n抽奖', top: '-20px' }]
          },
        ],
      }
    },
    methods: {
      // 点击抽奖按钮触发回调
      startCallBack () {
        // 先开始旋转
        this.$refs.myLucky.play()
        // 使用定时器来模拟请求接口
        setTimeout(() => {
          // 假设后端返回的中奖索引是0
          const index = 0
          // 调用stop停止旋转并传递中奖索引
          this.$refs.myLucky.stop(index)
        }, 3000)
      },
      // 抽奖结束触发回调
      endCallBack (prize) {
        // 奖品详情
        console.log(prize)
      }
    }
  }
</script>
1-6. 在 Taro 中使用(示例:LuckyWheel ):

1.安装

javascript 复制代码
# npm 安装:
npm install @lucky-canvas/taro@latest

# yarn 安装:
yarn add @lucky-canvas/taro@latest

2.使用

html 复制代码
# Taro-vue2
<template>
  <view>
    <LuckyWheel
      ref="myLucky"
      width="600rpx"
      height="600rpx"
      :prizes="prizes"
      :blocks="blocks"
      :buttons="buttons"
      @start="startCallback"
      @end="endCallback"
    ></LuckyWheel>
  </view>
</template>

<script>
import { LuckyWheel } from '@lucky-canvas/taro/vue'
export default {
  components: { LuckyWheel },
  data () {
    return {
      blocks: [{ padding: '13px', background: '#617df2' }],
      prizes: [
        { fonts: [{ text: '0', top: '10%' }], background: '#e9e8fe' },
        { fonts: [{ text: '1', top: '10%' }], background: '#b8c5f2' },
        { fonts: [{ text: '2', top: '10%' }], background: '#e9e8fe' },
        { fonts: [{ text: '3', top: '10%' }], background: '#b8c5f2' },
        { fonts: [{ text: '4', top: '10%' }], background: '#e9e8fe' },
        { fonts: [{ text: '5', top: '10%' }], background: '#b8c5f2' },
      ],
      buttons: [
        { radius: '50px', background: '#617df2' },
        { radius: '45px', background: '#afc8ff' },
        {
          radius: '40px', background: '#869cfa',
          pointer: true,
          fonts: [{ text: '开始\n抽奖', top: '-20px' }]
        },
      ],
    }
  },
  methods: {
    // 点击抽奖按钮会触发star回调
    startCallback () {
      // 调用抽奖组件的play方法开始游戏
      this.$refs.myLucky.play()
      // 模拟调用接口异步抽奖
      setTimeout(() => {
        // 假设后端返回的中奖索引是0
        const index = 0
        // 调用stop停止旋转并传递中奖索引
        this.$refs.myLucky.stop(index)
      }, 3000)
    },
    // 抽奖结束会触发end回调
    endCallback (prize) {
      console.log(prize)
    },
  }
}
</script>

# Taro-vue3
<template>
  <view>
    <LuckyWheel
      ref="myLucky"
      width="600rpx"
      height="600rpx"
      :prizes="prizes"
      :blocks="blocks"
      :buttons="buttons"
      @start="startCallback"
      @end="endCallback"
    ></LuckyWheel>
  </view>
</template>

<script>
import { ref, reactive, toRefs } from 'vue'
import { LuckyWheel } from '@lucky-canvas/taro/vue'
export default {
  components: { LuckyWheel },
  setup () {
    const myLucky = ref(null)
    const state = reactive({
      blocks: [{ padding: '13px', background: '#617df2' }],
      prizes: [
        { fonts: [{ text: '0', top: '10%' }], background: '#e9e8fe' },
        { fonts: [{ text: '1', top: '10%' }], background: '#b8c5f2' },
        { fonts: [{ text: '2', top: '10%' }], background: '#e9e8fe' },
        { fonts: [{ text: '3', top: '10%' }], background: '#b8c5f2' },
        { fonts: [{ text: '4', top: '10%' }], background: '#e9e8fe' },
        { fonts: [{ text: '5', top: '10%' }], background: '#b8c5f2' },
      ],
      buttons: [
        { radius: '50px', background: '#617df2' },
        { radius: '45px', background: '#afc8ff' },
        {
          radius: '40px', background: '#869cfa',
          pointer: true,
          fonts: [{ text: '开始\n抽奖', top: '-20px' }]
        },
      ],
    })
    // 点击抽奖按钮会触发star回调
    function startCallback () {
      // 调用抽奖组件的play方法开始游戏
      myLucky.value.play()
      // 模拟调用接口异步抽奖
      setTimeout(() => {
        // 假设后端返回的中奖索引是0
        const index = 0
        // 调用stop停止旋转并传递中奖索引
        myLucky.value.stop(index)
      }, 3000)
    }
    // 抽奖结束会触发end回调
    function endCallback (prize) {
      console.log(prize)
    }
    return {
      ...toRefs(state),
      startCallback,
      endCallback,
      myLucky
    }
  }
}
</script>

# Taro-react
import React from 'react'
import { LuckyWheel } from '@lucky-canvas/taro/react'

export default class Index extends React.Component {
  constructor () {
    super()
    this.myLucky = React.createRef()
    this.state = {
      blocks: [{ padding: '13px', background: '#617df2' }],
      prizes: [
        { fonts: [{ text: '0', top: '10%' }], background: '#e9e8fe' },
        { fonts: [{ text: '1', top: '10%' }], background: '#b8c5f2' },
        { fonts: [{ text: '2', top: '10%' }], background: '#e9e8fe' },
        { fonts: [{ text: '3', top: '10%' }], background: '#b8c5f2' },
        { fonts: [{ text: '4', top: '10%' }], background: '#e9e8fe' },
        { fonts: [{ text: '5', top: '10%' }], background: '#b8c5f2' },
      ],
      buttons: [
        { radius: '50px', background: '#617df2' },
        { radius: '45px', background: '#afc8ff' },
        {
          radius: '40px', background: '#869cfa',
          pointer: true,
          fonts: [{ text: '开始\n抽奖', top: '-20px' }]
        },
      ],
    }
  }
  render () {
    return <LuckyWheel
      ref={this.myLucky}
      width='300px'
      height='300px'
      blocks={this.state.blocks}
      prizes={this.state.prizes}
      buttons={this.state.buttons}
      onStart={() => { // 点击抽奖按钮会触发star回调
        // 调用抽奖组件的play方法开始游戏
        this.myLucky.current.play()
        // 模拟调用接口异步抽奖
        setTimeout(() => {
          // 假设后端返回的中奖索引是0
          const index = 0
          // 调用stop停止旋转并传递中奖索引
          this.myLucky.current.stop(index)
        }, 2500)
      }}
      onEnd={prize => { // 抽奖结束会触发end回调
        console.log(prize)
      }}
    ></LuckyWheel>
  }
}

大转盘 < LuckyWheel /> 参数介绍:

九宫格 < LuckyGrid /> 参数介绍:

老虎机 < SlotMachine /> 参数介绍:

以上便是对 lucky-canvas 抽奖插件的具体介绍和简易Dome,有常用问题我们可以通过lucky-canvas官方文档去了解解决,而这个高度自定义的插件组件适合我们做活动项目中的抽奖组件,有兴趣的小伙伴们可以了解并学习下!

lucky-canvas 官网:https://100px.net/

lucky-canvas 中文文档:https://100px.net/docs/wheel.html

lucky-canvas github地址:https://github.com/buuing/lucky-canvas

相关推荐
Pedantic1 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘1 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆2 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师3 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆3 小时前
VSCode自动格式化三要素
前端
爱勇宝3 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
kyriewen4 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
user20585561518136 小时前
Windows 项目安装时报 `node-sass` 错误,如何快速处理
前端
LiaCode6 小时前
Redis 在生产项目的使用
前端·后端