当前位置:首页 > VUE

vue实现人员滚动抽奖

2026-01-21 20:29:29VUE

实现人员滚动抽奖的Vue方案

核心思路
通过Vue的数据绑定和动画特性,结合JavaScript定时器实现随机滚动效果,最终停在获奖人员位置。

基础实现代码

<template>
  <div class="lottery-container">
    <div class="lottery-wheel" :style="{ transform: `translateY(${currentPosition}px)` }">
      <div v-for="(person, index) in personList" :key="index" class="person-item">
        {{ person.name }}
      </div>
    </div>
    <button @click="startLottery" :disabled="isRolling">开始抽奖</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      personList: [
        { name: '张三' },
        { name: '李四' },
        // 更多人员...
      ],
      currentPosition: 0,
      isRolling: false,
      rollSpeed: 50,
      targetIndex: 0
    }
  },
  methods: {
    startLottery() {
      if (this.isRolling) return;

      this.isRolling = true;
      const duration = 3000 + Math.random() * 2000;
      const startTime = Date.now();

      const roll = () => {
        const elapsed = Date.now() - startTime;
        const progress = Math.min(elapsed / duration, 1);

        // 减速效果
        this.rollSpeed = 50 * (1 - progress * 0.9);
        this.currentPosition -= this.rollSpeed;

        // 循环滚动
        if (-this.currentPosition > this.personList.length * 60) {
          this.currentPosition = 0;
        }

        if (progress < 1) {
          requestAnimationFrame(roll);
        } else {
          this.stopRolling();
        }
      };

      roll();
    },
    stopRolling() {
      this.targetIndex = Math.floor(Math.random() * this.personList.length);
      const targetPosition = -this.targetIndex * 60;

      // 精确对齐目标位置
      const align = () => {
        const diff = targetPosition - this.currentPosition;
        if (Math.abs(diff) < 1) {
          this.currentPosition = targetPosition;
          this.isRolling = false;
          alert(`中奖者: ${this.personList[this.targetIndex].name}`);
        } else {
          this.currentPosition += diff * 0.2;
          requestAnimationFrame(align);
        }
      };

      align();
    }
  }
}
</script>

<style scoped>
.lottery-container {
  height: 300px;
  overflow: hidden;
  position: relative;
}

.lottery-wheel {
  transition: transform 0.1s linear;
}

.person-item {
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid #eee;
}
</style>

进阶优化方案

添加视觉效果
增加CSS动画使滚动更平滑:

.lottery-wheel {
  transition: transform 0.1s cubic-bezier(0.17, 0.67, 0.21, 0.99);
}

音效增强
添加滚动和停止音效:

vue实现人员滚动抽奖

// 在methods中添加
playSound(type) {
  const audio = new Audio(`/sounds/${type}.mp3`);
  audio.play();
}

// 在startLottery和stopRolling中调用
this.playSound('rolling');
this.playSound('stop');

服务端数据集成

从API获取人员名单:

async created() {
  try {
    const response = await axios.get('/api/lottery/persons');
    this.personList = response.data;
  } catch (error) {
    console.error('获取人员列表失败', error);
  }
}

移动端适配方案

添加触摸事件支持:

vue实现人员滚动抽奖

<div 
  class="lottery-wheel"
  @touchstart="handleTouchStart"
  @touchmove="handleTouchMove"
  @touchend="handleTouchEnd"
>
methods: {
  handleTouchStart(e) {
    this.touchStartY = e.touches[0].clientY;
  },
  handleTouchMove(e) {
    if (!this.isRolling) {
      const deltaY = e.touches[0].clientY - this.touchStartY;
      this.currentPosition += deltaY;
      this.touchStartY = e.touches[0].clientY;
    }
  },
  handleTouchEnd() {
    // 惯性滚动逻辑
  }
}

性能优化建议

  1. 使用will-change提升动画性能:

    .lottery-wheel {
    will-change: transform;
    }
  2. 虚拟滚动技术处理超长列表:

    // 只渲染可视区域内的项目
    visibleItems() {
    const startIdx = Math.floor(-this.currentPosition / 60);
    return this.personList.slice(startIdx, startIdx + 10);
    }
  3. 使用Web Worker处理复杂计算避免主线程阻塞

标签: 人员vue
分享给朋友:

相关文章

vue实现添加用户

vue实现添加用户

Vue 实现添加用户功能 数据绑定与表单设计 在 Vue 中实现添加用户功能,首先需要设计一个表单,用于收集用户输入的数据。通过 v-model 实现双向数据绑定,确保表单数据与 Vue 实例中的数据…

vue搜索过后实现分页

vue搜索过后实现分页

Vue 实现搜索后分页功能 数据绑定与搜索逻辑 在 Vue 组件中定义必要的数据属性: data() { return { searchQuery: '', currentPa…

vue登录业务的实现

vue登录业务的实现

实现登录业务的基本流程 在Vue中实现登录业务通常涉及前端界面设计、表单验证、API请求交互、状态管理以及路由控制等环节。以下是核心实现步骤: 登录表单设计与验证 创建包含用户名和密码输入框的登录…

vue按钮实现截屏

vue按钮实现截屏

Vue 按钮实现截屏的方法 在 Vue 项目中实现截屏功能可以通过多种方式完成,以下是几种常见的方法: 使用 html2canvas 库 安装 html2canvas 库: npm ins…

vue实现全局遮罩层

vue实现全局遮罩层

实现全局遮罩层的方法 在Vue中实现全局遮罩层可以通过多种方式完成,以下是几种常见的实现方法: 使用Vue组件创建遮罩层 创建一个遮罩层组件,通过全局注册或动态挂载的方式实现全局调用。以下是一个简…

vue实现右下角弹框

vue实现右下角弹框

实现右下角弹框的基本思路 在Vue中实现右下角弹框,通常需要结合CSS定位和Vue的组件化特性。弹框可以通过绝对定位固定在右下角,并通过Vue控制其显示与隐藏。 创建弹框组件 新建一个Vue组件(如…