当前位置:首页 > 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 渲染奖品列表,并通过样式控制显示区域:

<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;
}

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

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;

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

vue实现滚动抽奖

<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 alert实现

vue alert实现

使用 Vue 实现 Alert 组件 在 Vue 中实现 Alert 组件可以通过自定义组件或结合第三方库完成。以下是几种常见方法: 自定义 Alert 组件 创建一个可复用的 Alert 组件,通…

vue实现曲线

vue实现曲线

Vue 实现曲线的方法 在 Vue 中实现曲线可以通过多种方式,包括使用 SVG、Canvas 或第三方库如 D3.js、ECharts 等。以下是几种常见的方法: 使用 SVG 绘制曲线 SVG…

vue实现swipe

vue实现swipe

Vue实现Swipe功能的方法 使用第三方库(推荐) Vue生态中有多个成熟的轮播/滑动组件库,例如vue-awesome-swiper或swiper/vue。以下是基于swiper/vue的实现示例…

vue实现curd

vue实现curd

Vue实现CRUD操作 初始化Vue项目 使用Vue CLI创建新项目,安装必要依赖如axios用于HTTP请求 vue create crud-demo cd crud-demo npm inst…

vue实现列表

vue实现列表

Vue 实现列表的方法 在 Vue 中实现列表渲染通常使用 v-for 指令,可以动态生成多个元素。以下是几种常见的实现方式: 基础列表渲染 使用 v-for 遍历数组,生成列表项。v-for 需要…

vue实现webshell

vue实现webshell

Vue 实现 WebShell 使用 Vue 实现 WebShell 需要结合前端与后端的交互,通常通过 WebSocket 或 HTTP 协议与服务器通信。以下是一个基于 Vue 和 WebSock…