当前位置:首页 > VUE

vue实现滚动抽奖

2026-01-19 07:34:15VUE

Vue 实现滚动抽奖

基本思路

滚动抽奖通常通过动态改变奖品列表的显示位置,配合动画效果实现。核心是利用 Vue 的响应式数据和 CSS 过渡动画。

实现步骤

数据准备 在 Vue 的 data 中定义奖品列表和当前选中索引:

data() {
  return {
    prizes: ['奖品1', '奖品2', '奖品3', '奖品4', '奖品5'],
    currentIndex: 0,
    isRolling: false
  }
}

模板结构 使用 v-for 渲染奖品列表,并通过样式控制显示区域:

vue实现滚动抽奖

<div class="lottery-container">
  <div class="lottery-wheel" :style="{ transform: `translateY(${-currentIndex * 100}px)` }">
    <div class="prize-item" v-for="(prize, index) in prizes" :key="index">
      {{ prize }}
    </div>
  </div>
  <button @click="startRoll" :disabled="isRolling">开始抽奖</button>
</div>

CSS 样式 设置固定高度的显示区域和滚动动画:

.lottery-container {
  height: 100px;
  overflow: hidden;
  position: relative;
}

.lottery-wheel {
  transition: transform 0.5s ease-out;
}

.prize-item {
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
}

抽奖逻辑 实现开始抽奖的方法,包含随机滚动和减速停止效果:

vue实现滚动抽奖

methods: {
  startRoll() {
    if (this.isRolling) return;
    this.isRolling = true;

    let speed = 100;
    const duration = 3000;
    const startTime = Date.now();

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

      if (progress < 1) {
        speed = 100 * (1 - progress);
        this.currentIndex = (this.currentIndex + 1) % this.prizes.length;
        setTimeout(roll, speed);
      } else {
        const finalIndex = Math.floor(Math.random() * this.prizes.length);
        this.currentIndex = finalIndex;
        this.isRolling = false;
      }
    };

    roll();
  }
}

高级优化

平滑停止 使用 easing 函数实现更自然的减速效果:

function easeOutQuart(t) {
  return 1 - Math.pow(1 - t, 4);
}

// 在roll方法中修改progress计算
const progress = easeOutQuart(elapsed / duration);

多次循环 确保奖品至少滚动完整数圈:

const minCycles = 3;
const totalItems = minCycles * this.prizes.length + finalIndex;

奖品高亮 添加当前选中奖品的样式类:

<div class="prize-item" :class="{ 'active': index === currentIndex }">

注意事项

  1. 移动端需考虑 touch 事件支持
  2. 奖品数量变化时需要重置状态
  3. 长时间滚动可能导致性能问题,应设置最大持续时间
  4. 考虑添加音效增强用户体验

完整示例

export default {
  data() {
    return {
      prizes: ['手机', '耳机', '优惠券', '谢谢参与', '积分'],
      currentIndex: 0,
      isRolling: false
    }
  },
  methods: {
    startRoll() {
      if (this.isRolling) return;

      this.isRolling = true;
      const duration = 3000;
      const startTime = Date.now();
      const finalIndex = Math.floor(Math.random() * this.prizes.length);
      const minCycles = 3;
      const totalItems = minCycles * this.prizes.length + finalIndex;

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

        this.currentIndex = Math.floor(easedProgress * totalItems) % this.prizes.length;

        if (progress < 1) {
          requestAnimationFrame(animate);
        } else {
          this.currentIndex = finalIndex;
          this.isRolling = false;
        }
      };

      requestAnimationFrame(animate);
    },
    easeOutQuart(t) {
      return 1 - Math.pow(1 - t, 4);
    }
  }
}

标签: vue
分享给朋友:

相关文章

vue实现前端分离

vue实现前端分离

Vue 实现前后端分离 前后端分离是一种架构模式,前端负责页面渲染和交互逻辑,后端提供数据接口。Vue.js 作为前端框架,非常适合实现前后端分离的开发模式。 核心实现步骤 创建 Vue 项目 使…

vue实现多层评论回复

vue实现多层评论回复

Vue 实现多层评论回复 数据结构设计 多层评论通常采用嵌套结构,每个评论对象包含子评论数组。示例数据结构如下: comments: [ { id: 1, content: '父…

vue实现文字播放栏

vue实现文字播放栏

Vue 实现文字播放栏(跑马灯效果) 方法一:使用 CSS 动画 + Vue 数据绑定 通过 CSS 的 @keyframes 实现动画效果,结合 Vue 的动态数据绑定控制内容。 <t…

vue实现字母添加排序

vue实现字母添加排序

实现字母添加排序的方法 在Vue中实现字母添加排序功能,可以通过以下步骤完成: 创建Vue实例并定义数据 new Vue({ el: '#app', data: { lette…

vue实现mvc

vue实现mvc

Vue 实现 MVC 模式 Vue 本身是一个 MVVM(Model-View-ViewModel)框架,但可以通过结构调整实现 MVC(Model-View-Controller)模式。以下是具体实…

vue datepicker 实现

vue datepicker 实现

实现 Vue Datepicker 的基本方法 在 Vue 项目中实现日期选择功能,可以使用第三方库如 vue-datepicker 或 v-calendar。以下是两种常见实现方式: 安装 vue…