当前位置:首页 > 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中实现视频剪辑功能通常需要结合HTML5的<video>元素和第三方库(如FFmpeg.js或Video.js)。以下是几种常见的实现方法: 使用FFm…

vue实现全屏

vue实现全屏

Vue 实现全屏功能的方法 在 Vue 中实现全屏功能可以通过浏览器提供的 Fullscreen API 来实现。以下是几种常见的实现方式: 使用原生 Fullscreen API 通过调用 doc…

vue scrolltop 实现

vue scrolltop 实现

实现 Vue 中的 scrollTop 在 Vue 中实现滚动到顶部功能可以通过多种方式完成,包括使用原生 JavaScript、Vue 指令或第三方库。以下是几种常见的实现方法: 使用原生 Jav…

vue实现微云

vue实现微云

Vue 实现微云功能 使用 Vue 实现类似微云的网盘功能需要结合前端框架、后端存储及文件处理技术。以下是关键实现步骤和代码示例: 前端框架搭建 使用 Vue CLI 创建项目基础结构,安装必要依赖…

vue实现卡片

vue实现卡片

Vue 实现卡片组件的方法 使用 Vue 实现卡片组件可以通过多种方式完成,以下是几种常见的实现方法: 使用原生 HTML 和 CSS 在 Vue 单文件组件中,可以通过模板和样式直接实现卡片效果…

vue 实现单点登录

vue 实现单点登录

单点登录(SSO)实现原理 单点登录允许用户通过一次身份验证访问多个系统。核心原理是用户首次登录后,认证中心颁发令牌(如Token),其他系统通过验证令牌实现免登录。 Vue中实现SSO的方案 基于…