uni-app 大转盘抽奖插件需求

发布于 1周前 作者 caililin 来自 Uni-App

uni-app 大转盘抽奖插件需求

想有一个大转盘抽奖的插件,可以控制抽奖概率,转盘格数可以动态设置;因为项目里面经常会遇到这个需求,

3 回复

谢谢,很不错,我看了

针对您提出的uni-app大转盘抽奖插件需求,以下是一个基本的实现思路和代码示例。这个示例将展示如何使用Canvas绘制大转盘,并通过简单的逻辑实现抽奖功能。

实现思路

  1. 绘制大转盘:使用Canvas绘制大转盘的背景、分隔线、奖品项等。
  2. 实现旋转动画:通过逐渐改变Canvas绘制的起始角度,模拟大转盘的旋转效果。
  3. 确定抽奖结果:在旋转动画结束时,根据当前的角度确定落在哪个奖品区域。

代码示例

1. 绘制大转盘

// 在页面的onLoad或mounted生命周期中初始化Canvas
const canvas = uni.createCanvasContext('myCanvas');
const items = ['奖品1', '奖品2', '奖品3', '奖品4', '谢谢参与']; // 奖品列表
const angleStep = 360 / items.length; // 每个奖品占用的角度

// 绘制背景、分隔线、奖品项等
function drawWheel() {
  canvas.setFillStyle('#f0f0f0');
  canvas.fillRect(0, 0, 300, 300); // 背景矩形

  for (let i = 0; i < items.length; i++) {
    const angle = i * angleStep - 90; // 转换为Canvas坐标系
    const x = 150 + 120 * Math.cos(angle * Math.PI / 180);
    const y = 150 + 120 * Math.sin(angle * Math.PI / 180);
    canvas.setFillStyle('#000');
    canvas.fillText(items[i], x - 30, y + 10); // 绘制奖品项
  }

  // 绘制分隔线(可选)
  for (let i = 1; i < items.length; i++) {
    const angle = i * angleStep - 90;
    const startX = 150 + 140 * Math.cos(angle * Math.PI / 180);
    const startY = 150 + 140 * Math.sin(angle * Math.PI / 180);
    const endX = 150;
    const endY = 150;
    canvas.beginPath();
    canvas.moveTo(startX, startY);
    canvas.lineTo(endX, endY);
    canvas.setStrokeStyle('#ccc');
    canvas.stroke();
  }

  canvas.draw();
}
drawWheel();

2. 实现旋转动画和抽奖结果

let currentAngle = 0;
let rotationSpeed = 5; // 旋转速度,可调整
let isRotating = false;

function startRotation() {
  isRotating = true;
  let timer = setInterval(() => {
    if (isRotating) {
      currentAngle += rotationSpeed;
      if (currentAngle >= 360) {
        currentAngle %= 360;
      }
      drawWheelWithRotation(); // 绘制旋转后的大转盘
    } else {
      clearInterval(timer);
      determineResult(); // 确定抽奖结果
    }
  }, 30); // 调整此值以改变旋转的平滑度
}

function drawWheelWithRotation() {
  // 在drawWheel函数的基础上,添加旋转变换
  canvas.save();
  canvas.translate(150, 150); // 移动到圆心
  canvas.rotate(currentAngle * Math.PI / 180); // 旋转Canvas
  // 反向移动回原位置,以便绘制背景等不受旋转影响的部分(如果需要)
  // ...(绘制背景等代码,与drawWheel中相同)
  // 然后绘制受旋转影响的奖品项等
  for (let i = 0; i < items.length; i++) {
    const angle = i * angleStep; // 注意这里不使用-90,因为已经在Canvas坐标系中旋转了
    const x = 120 * Math.cos(angle * Math.PI / 180);
    const y = 120 * Math.sin(angle * Math.PI / 180);
    // ...(绘制奖品项的代码,与drawWheel中相同,但使用x, y)
  }
  canvas.restore();
  canvas.draw();
}

function determineResult() {
  const finalIndex = Math.floor((currentAngle + angleStep / 2) / angleStep) % items.length;
  uni.showToast({ title: `你抽中了:${items[finalIndex]}`, icon: 'success' });
}

// 触发旋转(例如按钮点击事件)
uni.createSelectorQuery().select('#rotateButton').boundingClientRect(rect => {
  startRotation(); // 示例中直接开始旋转,实际应用中可能需要在一定时间后停止旋转
}).exec();

请注意,此代码为简化示例,未包含完整的用户交互逻辑和错误处理。在实际应用中,您可能需要进一步优化动画效果、添加用户交互逻辑(如点击停止旋转)、处理边界情况等。

回到顶部