当前位置:首页 > 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 提供了多种方式实现页面布局,可以通过组件化、CSS 框架或自定义样式完成。以下是几种常见方法: 使用 CSS Flexbox 或 Grid 通过 Vue 单文件组件结合…

vue实现双向

vue实现双向

Vue 实现双向绑定的方法 Vue 的双向绑定主要通过 v-model 指令实现,它结合了数据绑定和事件监听,适用于表单元素(如 input、select、textarea 等)。以下是几种常见的实现…

vue实现hovuer

vue实现hovuer

Vue 实现 Hover 效果 在 Vue 中实现 hover 效果可以通过多种方式完成,以下是几种常见的方法: 使用 CSS 直接控制 通过 :hover 伪类实现,无需额外的 JavaScrip…

vue实现拖拉

vue实现拖拉

实现拖拽功能的基本步骤 在Vue中实现拖拽功能可以通过原生HTML5的拖放API或第三方库如vuedraggable完成。以下是两种方法的详细说明。 使用HTML5原生拖放API HTML5提供了原…

vue 实现templateurl

vue 实现templateurl

在 Vue 中,templateUrl 是 Angular 中的一个概念,用于指定外部 HTML 文件作为模板。Vue 本身不直接支持 templateUrl,但可以通过以下方法实现类似功能: 使用…

vue递归实现

vue递归实现

vue递归实现方法 在Vue中实现递归组件通常用于树形结构、嵌套菜单等场景。以下是具体实现方式: 使用组件name属性递归 定义一个组件时,通过name属性让组件可以在自身模板中调用自己:…