vue實現大轉盤抽獎

用vue實現一個簡單的大轉盤抽獎案例

大轉盤

一 轉盤布局

<div class="lucky-wheel-content"><div class="lucky-wheel-prize" :style="wheelStyle" :class="isStart ? 'animated-icon' : ''"@transitionend="onWheelTransitionEnd"><div class="lucky-wheel-prize-item" v-for="(item, index) in prize" :key="item.id":style="{ transform: 'rotate(' + (index * 36) + 'deg)' }"><span>{{ item.reward }}</span><img :src="item.img" alt=""></div></div><div class="lucky-wheel-btn" @click="spinWheel">RODAR</div><img class="lucky-wheel-poiner" src="/img/activity/zphd_zz_s1.avif" /></div>

1.1 :style=“{ transform: ‘rotate(’ + (index * 36) + ‘deg)’ }”

  1. v-for=“(item, index) in prize”:這表示你正在循環渲染 prize 數組中的每個項目,每個項目都有一個
    item 和其在數組中的 index。這個 index 就是每個獎品項的位置。
  2. index * 36:每個項目的旋轉角度是基于其索引計算的。這里每個項目的旋轉角度是 36 度(360 ÷ 10 = 36),因為假設轉盤有 10 項。通過將 index 乘以 36,每個項目將被均勻地分布在轉盤上。
  3. :style=“{ transform: ‘rotate(’ + (index * 36) + ‘deg)’ }”:這段代碼為每個
    lucky-wheel-prize-item 動態添加一個內聯的 style 屬性,指定它的 transform CSS 樣式。這個
    transform 樣式使用 rotate() 函數來旋轉每個獎品項。
  4. rotate(index * 36):基于 index 計算出每個項目的旋轉角度。比如:
  • 對于第一個項目(index = 0),旋轉角度是 0deg。
  • 對于第二個項目(index = 1),旋轉角度是 36deg。
  • 對于第三個項目(index = 2),旋轉角度是 72deg,以此類推。
    效果:通過這種方式,每個 lucky-wheel-prize-item 將會根據它在轉盤上的位置進行旋轉,使它們均勻分布在 360 度的轉盤上。這樣,整個轉盤就呈現出一個環形布局,每個項按順序排列。

在這里插入圖片描述

計算轉盤旋轉的樣式

通過計算屬性

const wheelStyle = computed(() => {return {transform: `rotate(${rotationAngle.value}deg)`,}
});
  • rotationAngle 是某個響應式變量(可能是通過其他邏輯計算出來的旋轉角度),它的值決定了轉盤旋轉的角度。
  • 當 rotationAngle.value 發生變化時,computed 屬性會自動重新計算并返回新的樣式對象,其中
    rotate(${rotationAngle.value}deg) 的角度會根據最新的 rotationAngle.value 動態更新。
  • 然后,這個 wheelStyle 對象可以應用到某個 DOM 元素上,通常是一個轉盤的 style 屬性,以便旋轉轉盤。
<div :style="wheelStyle"><!-- 轉盤內容 -->
</div>

二 轉盤邏輯

2.1 這里最重要的是轉盤總的旋轉角度的設置

  spins.value += 5;  // 開始的旋轉圈數// 后端返回中獎項的邏輯  隨機數winningIndex.value = Math.floor(Math.random() * totalItems.value);console.log("中獎項:" + winningIndex.value);const anglePerItem = 360 / totalItems.value;let randomAngle = 360 - (winningIndex.value * anglePerItem); // 計算旋轉到中獎的那一項let totalAngle = spins.value * 360 + randomAngle; // 總的旋轉角度console.log("總的旋轉角度:" + totalAngle);// 設置旋轉角度rotationAngle.value = totalAngle;
  • let randomAngle = 360 - (winningIndex.value * anglePerItem);
    randomAngle 是根據中獎項索引計算出的角度。winningIndex.value 乘以 anglePerItem 得到當前中獎項相對于起始位置的角度,360 - … 計算出從當前起始位置到中獎項的逆時針旋轉角度。

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

2.2 在請求后端獲取數據時,保持轉動效果

  • :class=“isStart ? ‘animated-icon’ : ‘’”
    主要是通過加上這個類名來保持這個效果
  spins.value += 5;isStart.value = trueapi.getRandom().then(res => {console.log(res);isStart.value = falsewinningIndex.value = res.data// 每個獎品的角度const anglePerItem = 360 / totalItems.value;// 計算中獎項的角度let randomAngle = 360 - (winningIndex.value * anglePerItem);let totalAngle = spins.value * 360 + randomAngle; // 總的旋轉角度// 設置旋轉角度rotationAngle.value = totalAngle;}).finally(() => {console.log('中獎項是:' + prize[winningIndex.value].reward);isSpinning.value = falseisStart.value = false})

api.getRandom()這個是我本地java寫的一個接口,模擬返回一個中獎的索引,同時該接口延遲5s返回數據

   @GetMapping("/random")public Result<Integer> getRandom(){try {// 延遲5秒Thread.sleep(5000);} catch (InterruptedException e) {// 處理異常e.printStackTrace();}Random random = new Random();Integer integer = random.nextInt(10); // 生成0到10之間的隨機整數return Result.success(integer); // 返回成功結果}

大轉盤1

三 完整代碼

 <div class="lucky-wheel-content"><div class="lucky-wheel-prize" :style="wheelStyle" :class="isStart ? 'animated-icon' : ''"@transitionend="onWheelTransitionEnd"><div class="lucky-wheel-prize-item" v-for="(item, index) in prize" :key="item.id":style="{ transform: 'rotate(' + (index * 36) + 'deg)' }"><span>{{ item.reward }}</span><img :src="item.img" alt=""></div></div><div class="lucky-wheel-btn" @click="spinWheel">RODAR</div><img class="lucky-wheel-poiner" src="/img/activity/zphd_zz_s1.avif" /></div>
const prize = [{id: 1,reward: '0,05',img: '/img/activity/img_zphdjp_s1.png'}, {id: 2,reward: '1,00',img: '/img/activity/img_zphdjp_s1.png'}, {id: 3,reward: '2,00',img: '/img/activity/img_zphdjp_s1.png'}, {id: 4,reward: '3,00',img: '/img/activity/img_zphdjp_s1.png'}, {id: 5,reward: '4,00',img: '/img/activity/img_zphdjp_s1.png'}, {id: 6,reward: '5,00',img: '/img/activity/img_zphdjp_s1.png'}, {id: 7,reward: '15,00',img: '/img/activity/img_zphdjp_s1.png'}, {id: 8,reward: '25,00',img: '/img/activity/img_zphdjp_s1.png'}, {id: 9,reward: '35,00',img: '/img/activity/img_zphdjp_s1.png'}, {id: 10,reward: '75,00',img: '/img/activity/img_zphdjp_s1.png'}
]
const totalItems = ref(prize.length); // 總共有多少個項
const winningIndex = ref(0); // 假設中獎項的索引(從0開始)
const rotationAngle = ref(0); // 當前旋轉角度
const isSpinning = ref(false)
const spins = ref(0) //轉盤轉5圈
const winner = ref(null); // 中獎項
const number = ref(0)  //記錄抽獎次數
const isFirst = ref(0)
const isStart = ref(false)
// 計算轉盤旋轉的樣式
const wheelStyle = computed(() => {return {transform: `rotate(${rotationAngle.value}deg)`,}});// 執行旋轉轉盤的操作
const spinWheel = () => {if (isSpinning.value) {return}number.value++;isStart.value = trueconsole.log("當前抽獎次數:" + number.value);isSpinning.value = true; // 開始旋轉winner.value = null; // 重置中獎項winningIndex.value = 0; // 重置中獎索引rotationAngle.value = 0; // 重置旋轉角度spins.value += 5;// api.getRandom().then(res => {//   console.log(res);//     isStart.value = false//   winningIndex.value = res.data//   // 每個獎品的角度//   const anglePerItem = 360 / totalItems.value;//   // 計算中獎項的角度//   let randomAngle = 360 - (winningIndex.value * anglePerItem);//   let totalAngle = spins.value * 360 + randomAngle; // 總的旋轉角度//   // 設置旋轉角度//   rotationAngle.value = totalAngle;// }).finally(()=>{//   // console.log('中獎項是:'+prize[winningIndex.value].reward );//   isSpinning.value=false// })// 后端返回中獎項的邏輯  隨機數winningIndex.value = Math.floor(Math.random() * totalItems.value);// 假設每次轉盤轉5圈// spins.value += 5;setTimeout(()=>{isStart.value = falseisSpinning.value=falseconsole.log('中獎項是:'+prize[winningIndex.value].reward );},2000)// 每個獎品的角度const anglePerItem = 360 / totalItems.value;// 計算中獎項的角度let randomAngle = 360 - (winningIndex.value * anglePerItem);let totalAngle = spins.value * 360 + randomAngle; // 總的旋轉角度// 設置旋轉角度rotationAngle.value = totalAngle;
};// 監聽轉盤動畫結束事件
const onWheelTransitionEnd = () => {isSpinning.value = false; // 旋轉結束// rotationAngle.value=0winner.value = winningIndex.value; // 顯示中獎項// console.log(winner.value, '123');// console.log(rotationAngle.value, '旋轉角度');console.log('中獎項是:'+prize[winner.value].reward );};
.lucky-wheel {.lucky-wheel-content {width: 15rem;height: 15rem;background-image: url('/img/activity/zphd_bj_s1.avif');background-size: 100% 100%;margin: .4rem auto .4rem auto;position: relative;transition: transform 5s ease-in-out;.lucky-wheel-prize {position: absolute;top: 0;right: 0;bottom: 0;left: 0;transition: transform 4s ease-out;/* 控制旋轉動畫 */.lucky-wheel-prize-item {position: absolute;top: 0;right: 0;bottom: 0;left: 0;z-index: 10;width: 2rem;margin: auto;height: 100%;color: #ffff;font-size: .22rem;text-align: center;display: flex;align-items: center;flex-direction: column;&>img {width: 2rem;height: 2rem;}&>span {display: -webkit-box;overflow: hidden;text-overflow: ellipsis;vertical-align: middle;-webkit-line-clamp: 2;-webkit-box-orient: vertical;font-size: .6rem;word-break: break-all;height: 2.8rem;line-height: 2.8rem;}}}@keyframes spin {0% {transform: rotate(0deg);/* 開始時從0度 */}100% {transform: rotate(360deg);/* 結束時旋轉一圈 */}}/* 應用動畫 */.animated-icon {display: inline-block;animation: spin 1s linear infinite;/* 1秒旋轉一圈,永遠循環 */}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/75902.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/75902.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/75902.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Docker 核心組件

一、前言 Docker 已成為現代 DevOps 和微服務架構中的核心工具。為了更深入地理解它的工作機制&#xff0c;本文將系統介紹 Docker 的核心組件&#xff0c;配合結構圖直觀展示架構&#xff0c;同時拓展高級用法&#xff0c;幫助讀者全面掌握容器化技術的內核。 二、Docker 核心…

ModuleNotFoundError: No module named ‘pandas‘

在使用Python繪制散點圖表的時候&#xff0c;運行程序報錯&#xff0c;如圖&#xff1a; 報錯顯示Python 環境中可能沒有安裝 pandas 庫&#xff0c;執行pip list命令查看&#xff0c;果然沒有安裝pandas 庫&#xff0c;如圖&#xff1a; 執行命令&#xff1a;python -m pip in…

(51單片機)矩陣按鍵密碼鎖表白(C語言代碼編撰)(矩陣按鍵教程)(LCD1602淺教程)

目錄 源代碼 main.c MatrixKey.c MatrixKey.h LCD1602.c LCD1602.h Delay.c Delay.h 運行效果圖&#xff1a; 第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a; 第四步&#xff1a; 代碼解析與教程&#xff1a; 延時函數Delay LCD1602 MatrixKey模塊 源代…

檢測手機插入USB后,自動啟動scrcpy的程序

博主寫了一個小工具scrcpyAuto&#xff0c;檢測手機插入電腦USB后&#xff0c;自動啟動scrcpy。 這樣只要程序運行&#xff0c;手機接入主機就會有scrcpy大屏出現&#xff0c;方便了很多。 1、程序會最小化到系統托盤中。 2、博主沒有設計得太復雜&#xff0c;所以程序開機啟動…

使用Scade實現神經網絡算法

在ERTS2022中&#xff0c;ANSYS 發表了使用Scade實現神經網絡AI算法的相關工作。論文題目為《Programming Neural Networks Inference in a Safety-Critical Simulation-based Framework》 背景與挑戰 神經網絡在安全關鍵系統中的應用&#xff1a;隨著嵌入式系統中自主性的引入…

Next.js + SQLite 項目 Docker 生產環境部署方案

以下是完整的 Next.js SQLite 項目 Docker 生產環境部署方案&#xff1a; 1. 項目結構準備 your-project/ ├── prisma/ │ ├── schema.prisma │ └── migrations/ ├── app/ ├── lib/ ├── Dockerfile ├── docker-compose.yml ├── .dockerignore └…

MCU軟件開發使用指針有哪些坑?

目錄 1、空指針訪問 2、野指針&#xff08;未初始化的指針&#xff09; 3、指針越界 4、內存泄漏 5、懸空指針 6、指針類型不匹配 7、多任務環境中的指針訪問 8、對齊問題 在MCU軟件開發中&#xff0c;使用指針雖然可以提高程序的靈活性和性能&#xff0c;但也存在許多…

【SPSS/EXCEl】主成分分析構建__綜合評價指數

學習過程中實驗操作的記錄 1.數據準備和標準化&#xff1a; (1)區分正負相關性:判斷每個因子是正向指標還是負向指標,計算每個的最大值和最小值 (2) 標準化: Min-Max標準化 Min-Max標準化&#xff08;最大最小值法&#xff09;&#xff1a; 將數據映射到指定的區間&#xff…

selenium安裝,以及瀏覽器驅動下載詳細步驟

1.下載谷歌瀏覽器Chromedriver 查看谷歌瀏覽器版本 2.去官網下載Chromedriver 114之前的版本鏈接chromedriver.storage.googleapis.com/index.html 選擇和瀏覽器版本較接近的點擊進行下載 125之后的版本鏈接Chrome for Testing availability (googlechromelabs.github.io)&a…

LabVIEW 油井動液面在線監測系統?

項目背景 傳統油井動液面測量依賴人工現場操作&#xff0c;面臨成本高、效率低、安全風險大等問題。尤其在偏遠地區或復雜工況下&#xff0c;測量準確性與時效性難以保障。本系統通過LabVIEW虛擬儀器技術實現硬件與軟件深度融合&#xff0c;為油田智能化轉型提供實時連續監測解…

C++標準庫 —— round 函數用法詳解

round 是 C/C 標準庫中的一個數學函數&#xff0c;用于對浮點數進行四舍五入取整。以下是它的詳細用法說明&#xff1a; 目錄 1. 基本語法 2. 功能描述 3. 使用示例 示例1&#xff1a;基本用法 示例2&#xff1a;保留小數位 4. 相關函數對比 5. 注意事項 6. 實際應用場景…

嵌入式C語言11(宏/程序的編譯過程)

宏 ? 基本概念 C語言中可以利用宏定義實現文本的快速替換&#xff0c;注意&#xff1a;宏定義是單純的文本替換&#xff0c;不檢查語法是否合法。 C語言標準中提供了很多的預處理指令&#xff0c;比如#include、#pragma…以#開頭的都屬于預處理指令。 預處理指令指的是在…

【湖南大學】2025我們該如何看待DeepSeek

大家好&#xff0c;我是櫻木。 DeepSeek 官方網站&#xff1a;https://www.deepseek.com/ 一、DeepSeek 到底是什么&#xff1f; TA 到底厲害在哪里&#xff1f; 故事從 ChatGPT 說起 去年我們看到 Open AI 發布ChatGPT 后&#xff0c;全球的注意力到了 AI 身上。 我們來拆…

【區塊鏈安全 | 第三十三篇】備忘單

文章目錄 備忘單操作符優先級備忘單ABI 編碼和解碼函數bytes 和 string 的成員Address 的成員區塊與交易屬性校驗和斷言數學和加密函數合約相關類型信息函數可見性說明符修飾符備忘單 操作符優先級備忘單 以下是操作符的優先級順序,按評估順序列出: 優先級描述操作符1后綴遞…

Python----計算機視覺處理(Opencv:道路檢測之車道線顯示)

完整版&#xff1a;Python----計算機視覺處理&#xff08;Opencv:道路檢測完整版&#xff1a;透視變換&#xff0c;提取車道線&#xff0c;車道線擬合&#xff0c;車道線顯示&#xff09; 一、透視變換 將透視變換之后的圖像再繼續透視變換為原圖像 可參考Python----計算機視…

26屆Java暑期實習面經,騰訊視頻一面

短鏈接的生成原理 如何解決短鏈接生成的哈希沖突問題 如何加快從短鏈接到原鏈接的重定向過程 TCP 和 UDP 協議 如何理解 TCP 是面向連接的 為什么 TCP 的握手是 3 次 IO 模式 是否有真正寫過一個底層的 Socket 通信 MySQL 的事務隔離級別 MVCC 機制 什么叫服務的并行 為什么能基…

Windows注冊鼠標鉤子,獲取用戶選中的文本

注冊鼠標鉤子 // 注冊鼠標鉤子 HHOOK hMouseHook; hMouseHook SetWindowsHookEx(WH_MOUSE_LL, MouseProc, GetModuleHandle(NULL), 0);// 取消鼠標鉤子 UnhookWindowsHookEx(hMouseHook); hMouseHook nullptr; 上述代碼中MouseProc方法用于處理系統的鼠標消息 處理鼠標消息…

flink cdc的source數據流如何配置事件時間,如何設置時間語義,分配時間戳并生成水位線

在 Flink CDC 中為 Source 數據流配置事件時間需要結合時間語義設置、時間戳分配和水位線生成三個核心步驟。以下是具體配置方法及注意事項&#xff1a; 1. 設置時間語義 Flink 默認使用處理時間&#xff08;Processing Time&#xff09;&#xff0c;需顯式指定事件時間語義&a…

C++ 指針類型轉換全面解析與最佳實踐

文章目錄 C 指針類型轉換全面解析與最佳實踐1. 隱式轉換基類和派生類指針 2. 顯式轉換(1) static_cast(2) dynamic_cast(3) reinterpret_cast(4) const_cast 3. C 風格轉換4. 常見問題與注意事項5. 總結最佳實踐 C 指針類型轉換全面解析與最佳實踐 在 C 中&#xff0c;指針類型…

批量將 txt/html/json/xml/csv 等文本拆分成多個文件

我們的文本文件太大的時候&#xff0c;我們通常需要對文本文件進行拆分&#xff0c;比如按多少行一個文件將一個大的文本文件拆分成多個小的文本文件。這樣我們在打開或者傳輸的時候都比較方便。今天就給大家介紹一種同時對多個文本文件進行批量拆分的方法&#xff0c;可以快速…