当前位置:首页 > 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);
}

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

// 在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);
  }
}

移动端适配方案

添加触摸事件支持:

<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播放倍速的方法 在Vue中实现播放倍速功能通常涉及HTML5的<video>元素或第三方播放器库。以下是几种常见实现方式: 使用原生HTML5 video元素 通过ref获取v…

vue设计与实现下载

vue设计与实现下载

vue设计与实现电子书下载 《Vue.js设计与实现》是一本深入解析Vue.js框架原理的书籍,由霍春阳(HcySunYang)撰写。以下是获取该资源的常见途径: 正版购买渠道 京东、…

vue实现轮询

vue实现轮询

实现轮询的基本方法 在Vue中实现轮询可以通过setInterval或setTimeout配合递归调用完成。轮询通常用于定期向服务器请求数据更新。 使用setInterval的简单示例: da…

vue实现递归

vue实现递归

Vue 实现递归组件的方法 在 Vue 中实现递归组件通常用于处理树形结构数据(如菜单、评论列表、文件目录等)。以下是具体实现方法: 定义递归组件 通过 name 选项让组件可以递归调用自身:…

vue实现帖子

vue实现帖子

Vue 实现帖子功能 使用 Vue 实现帖子功能需要结合前端框架和后端数据交互,以下是实现的关键步骤和代码示例。 帖子列表展示 创建帖子列表组件,使用 v-for 渲染帖子数据,通过 axios…

jq 实现 vue

jq 实现 vue

jq 实现 Vue 的核心功能 jq 是一个轻量级的 JavaScript 库,主要用于 DOM 操作和事件处理。虽然它不能完全替代 Vue,但可以通过一些技巧模拟 Vue 的核心功能,如数据绑定、事…