Vue.js學習筆記(五)抽獎組件封裝——轉盤抽獎

基于VUE2轉盤組件的開發

文章目錄

  • 基于VUE2轉盤組件的開發
  • 前言
  • 一、開發步驟
    • 1.組件布局
    • 2.布局樣式
    • 3.數據準備
  • 二、最后效果
  • 總結


前言

因為之前的轉盤功能是圖片做的,每次活動更新都要重做UI和前端,為了解決這一問題進行動態配置轉盤組件開發,可以減少一些UI和前端的工作量。


一、開發步驟

1.組件布局

 <van-row class="container"><!-- turntableBox 為整個轉盤容器,為正方形,大小由里面元素決定 --><van-col span="24" class="turntableBox"><!-- turntableMain 為轉盤底座,比里面的內容大,顯示為效果圖灰色外圈,但不是空心圓 --><div class="turntableMain" :style="`height:${window.innerWidth * 0.8}px;width:${window.innerWidth * 0.8}px;`"><!-- turntable 為轉動區域,作用是為了不讓外圈一起轉動 --><div ref="turntable" class="turntable":style="`height:${window.innerWidth * 0.8}px;width:${window.innerWidth * 0.8}px;`"><!-- Canvas 轉盤餅圖背景,具體劃分多少塊由獎項決定 --><Canvas /><!-- prizeBox 獎項,高為餅圖的半徑,寬為餅圖半徑里面有多少塊就多少分之一 --><div class="prizeBox"><div class="prizeItem" :style="`width:${perPrize.width}px;height:${perPrize.height}px;transform:translateX(-50%) rotate(-${(perPrize.degree * (index + 1)) - (perPrize.degree / 2)}deg);left:calc(50%)`"v-for="(item, index) in activeInfo.prizeList" :key="index"><p class="title">{{ item.name }}</p><p class="describe">{{ item.describe }}</p><img :src="item.img" style="width: 38%;" /></div></div></div><!-- 啟動按鈕 --><van-image class="go" fit="cover" width="42px" :src="goPointer" @click="go" /></div></van-col><!-- 結果展示列表 --><van-col span="24"><div id="result"></div></van-col></van-row>

2.布局樣式

.turntableBox {margin-top: 10%;.turntableMain {margin: 0 auto;position: relative;border: 10px solid #E5E5E5;border-radius: 100%;}.turntable {transition: all 4s;margin: 0 auto;}.go {position: absolute;top: calc(50% - 31px);left: calc(50% - 21px);}.prizeBox {position: absolute;width: 80%;top: 0;left: calc(50% - 40%);.prizeItem {text-align: center;position: absolute;top: 0;overflow: hidden;text-align: center;transform-origin: center bottom;transform: translateX(-50%);color: #2c3e50;p {margin: 0;padding: 0;}.title {font-size: 18px;margin-top: 12px;}.describe {font-size: 14px;line-height: 28px;white-space: break-spaces;}img {margin-top: 6px;}}}
}

3.數據準備

data 代碼如下:包含頁面功能所需要的變量

  data() {return {window,/** 活動設置 */activeInfo: {/** 中獎概率 */probabilities: {"一等獎": 10,"二等獎": 10,"三等獎": 10,"四等獎": 10,},/** 獎品信息 */prizeList: [{name: '一等獎',describe: '一等獎',img: 'https://img01.yzcdn.cn/vant/cat.jpeg'},{name: '未中獎',describe: '未中獎',img: 'https://img01.yzcdn.cn/vant/cat.jpeg'},{name: '二等獎',describe: '二等獎',img: 'https://img01.yzcdn.cn/vant/cat.jpeg'},{name: '未中獎',describe: '未中獎',img: 'https://img01.yzcdn.cn/vant/cat.jpeg'},{name: '三等獎',describe: '三等獎',img: 'https://img01.yzcdn.cn/vant/cat.jpeg'},{name: '四等獎',describe: '四等獎',img: 'https://img01.yzcdn.cn/vant/cat.jpeg'},]},/** 是否正在執行動畫 */isGo: false,/** 執行動畫的對象 */oTurntable: '',/** 即將旋轉的度數 */randomDeg: 0,/** 上一次旋轉的度數 */lastDeg: 0,/** 抽獎次數 */goTimes: 3,/** 獎品圖片 */perPrize: {degree: null,width: null,height: null}}} 

created 代碼如下:主要處理角度、寬、高

  created() {const params = getAllParams();if (params) {this.params = params;};/** 獎品 */const angle = (360 / this.activeInfo.prizeList.length) / 2; // 對角角度const ratio = Number(Math.sin(angle * (Math.PI * 2 / 360)).toFixed(2)); // 與半徑的比率this.perPrize = {degree: (360 / this.activeInfo.prizeList.length),width: Math.floor((window.innerWidth * ratio)) / 2,/** 高度是直徑的一半 */height: window.innerWidth * 0.8 / 2}},

mounted 代碼如下:獲取轉盤區域DOM元素,方便后面操作

  mounted() {this.oTurntable = this.$refs.turntable;},

methods 代碼如下:主要操作方法

 /** 點擊抽獎 */go() {/** 正在抽獎,未結束繼續點擊無效 */if (!this.isGo && this.goTimes > 0) {/** 獲取中獎結果,再根據結果去轉動轉盤 */const result = this.generatePrize();/** * 獲取獎項下標* 獎項名字可能會重復,所以需要找到獎項的所有下標保存到數組里* 根據下標數組隨機生成一個數字來決定選擇哪個下標成為最終結果的下標*  */const resultIndexArray = this.activeInfo.prizeList.reduce((acc, item, index) => {if (item.name === result) {acc.push(index);}return acc;}, []);const randomResultIndex = Math.floor(Math.random() * resultIndexArray.length);const index = resultIndexArray[randomResultIndex];/** 獎項總和數量 */const length = this.activeInfo.prizeList.length;/** 調用旋轉方法 */this.ratating((360 / length * index) + (360 / length / 2), result);}else if (!this.isGo && this.goTimes <= 0) {this.$toast({message: '抱歉,您的抽獎次數用完了',duration: 3000,});}else {this.$toast('請勿重復點擊')return}},/** 獲取抽獎結果 */generatePrize() {/** 生成一個 0 到 99 之間的隨機數 */const randomNum = Math.floor(Math.random() * 100);let cumulativeProbability = 0;/** 如果概率落在獎項范圍內 */for (const prize in this.activeInfo.probabilities) {cumulativeProbability += this.activeInfo.probabilities[prize];if (randomNum < cumulativeProbability) {/** 返回中獎內容 */return prize;}}// 默認返回未中獎return "未中獎";},/** 該方法能產生[n,m]之間隨機數,決定轉盤轉多少圈 */getRandom(n, m) {let result = Math.floor(Math.floor(Math.random() * (m - n + 1) + n))return result;},/** 旋轉 */ratating(deg, text) {this.goTimes--;this.isGo = true;/** 旋轉圈數 */let turnNumber = this.getRandom(3, 6);/** 記錄這次要旋轉的度數(傳來的度數+圈數) */this.randomDeg = deg + 360 * turnNumber;/*上次指針離初始狀態的度數 + 上次的度數 + 這次要旋轉的度數(這樣的目的是為了每次旋轉都從原點開始,保證數據準確)*/let realDeg = (360 - this.lastDeg % 360) + this.lastDeg + this.randomDeg;/** 為對象添加執行動畫 */this.oTurntable.style.transform = `rotate(${realDeg}deg)`;setTimeout(() => {this.isGo = false;var list = document.getElementById('result');list.innerHTML += /未中獎/.test(text) ? `<p>很遺憾,您${text}!</p>` : `<p>恭喜您,獲得${text}!</p>`;/** 把這次度數存儲起來,方便下一次獲取 */this.lastDeg = realDeg;}, 4000);}

canvas 組件代碼如下:主要使用canvas標簽根據獎項長度進行角度劃分繪畫,


<template><canvas class="canvas" id="canvasImg" :style="`width:${perimeter}px;height: ${perimeter}px;`">您的瀏覽器不支持canvas!</canvas>
</template><script>export default {name: 'Canvas',components: {},data() {return {/** 直徑 */perimeter: 320,}},created() {},mounted() {this.perimeter = window.innerWidth * 0.8;this.drawPie();},methods: {/** 畫餅圖 */drawPie() {const PI = Math.PI;/** 獲取畫布并獲取2d上下文對象 */const canvas = document.getElementById('canvasImg');const ctx = canvas.getContext('2d');/** 假設周長為500 */const perimeter = this.perimeter;/** 半徑 */const radius = perimeter * 0.5;/** 總獎品數,需要根據實際數據長度從父組件傳入 */const prizeTotal = 6;/** 每個扇形的角度=360度 / 總獎品數 */const degree = 360 / prizeTotal;/** 畫布寬高 */canvas.width = perimeter;canvas.height = perimeter;/** 根據獎品數把圓形分成等份的扇形 */for (let i = 0; i < prizeTotal; i++) {/** 奇偶顏色 */const color = i % 2 === 0 ? "#F8D383" : "#F8E2BC";/** 開始一條新路徑 */ctx.beginPath();/** 設置路徑起點 */ctx.moveTo(radius, radius);/** 填充顏色 */ ctx.fillStyle = color;/** 繪制扇形 (圓心坐標,圓心坐標,半徑,扇形起始角度,扇形終止角度) */ctx.arc(radius, radius, radius, (270 - degree  + (degree * i)) * PI / 180, (270 - degree  + degree + (degree * i)) * PI / 180);/** 自動繪制一條當前點到起點的直線,形成一個封閉圖形,省卻使用一次moveTo方法。 */ctx.closePath();/** 閉合路徑 */ctx.fill();}}},
}
</script><style lang="less"></style>

二、最后效果

在這里插入圖片描述


總結

本文僅僅簡單記錄了轉盤組件的基本實現,僅供學習參考。

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

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

相關文章

【jvm】字符串常量池問題

目錄 一、基本概念1.1 說明1.2 特點 二、存放位置2.1 JDK1.6及以前2.2 JDK1.72.3 JDK1.8及以后 三、工作原理3.1 創建字符串常量3.2 使用new關鍵字創建字符串 四、intern()方法4.1 作用 五、優點六、字節碼分析6.1 示例16.1.1 代碼示例6.1.2 字節碼6.1.3 解析 6.2 示例26.2.1 代…

STM32智能倉儲管理系統教程

目錄 引言環境準備晶智能倉儲管理系統基礎代碼實現&#xff1a;實現智能倉儲管理系統 4.1 數據采集模塊 4.2 數據處理與決策模塊 4.3 通信與網絡系統實現 4.4 用戶界面與數據可視化應用場景&#xff1a;倉儲管理與優化問題解決方案與優化收尾與總結 1. 引言 智能倉儲管理系統…

7 月12日學習打卡--棧和隊列的相互轉換

hello大家好呀&#xff0c;本博客目的在于記錄暑假學習打卡&#xff0c;后續會整理成一個專欄&#xff0c;主要打算在暑假學習完數據結構&#xff0c;因此會發一些相關的數據結構實現的博客和一些刷的題&#xff0c;個人學習使用&#xff0c;也希望大家多多支持&#xff0c;有不…

什么是STM32?嵌入式和STM32簡單介紹

1、嵌入式和STM32 1.1.什么是嵌入式 除了桌面PC之外&#xff0c;所有的控制類設備都是嵌入式 嵌入式系統的定義&#xff1a;“用于控制、監視或者輔助操作機器和設備的裝置”。 嵌入式系統是一個控制程序存儲在ROM中的嵌入式處理器控制板&#xff0c;是一種專用的計算機系統。…

初階數據結構速成

本篇文章算是對初階數據結構的總結&#xff0c;內容較多&#xff0c;請耐心觀看 基礎概念部分 順序表 線性表&#xff08; linear list &#xff09;是n個具有相同特性的數據元素的有限序列。 線性表是?種在實際中?泛使 ?的數據結構&#xff0c;常?的線性表&#xff1a;…

C語言 錯題本

C語言 錯題本 文章目錄 C語言 錯題本77月11號整數求逆--掌握 7月12號求符合給定條件的整數集水仙花數打印九九口訣表--掌握統計素數并求和--掌握 7月13號湊硬幣前n項和(一加一減)最大公約數 7月14號正序整數分解 7月17號簡單計算器 217月26號求符合給定條件的整數集水仙花數 旨…

【安全設備】上網行為管理

一、什么是上網行為管理 上網行為管理是對企業內部員工使用互聯網行為的監視和管理&#xff0c;旨在規范網絡使用者的上網行為&#xff0c;提高網絡安全性&#xff0c;保護企業信息安全&#xff0c;同時提高員工的工作效率。上網行為管理通過對員工的上網行為進行監控、記錄和…

機器學習——關于極大似然估計法的一些個人思考(通俗易懂極簡版)

最近在回顧機器學習的一些相關理論知識&#xff0c;回顧到極大似然法時&#xff0c;對于極大似然法中的一些公式有些迷糊了&#xff0c;所以本文主要想記錄并分享一下個人關于極大似然估計法的一些思考&#xff0c;如果有誤&#xff0c;請見諒&#xff0c;歡迎一起前來探討。當…

單元測試實施最佳方案(背景、實施、覆蓋率統計)

1. 什么是單元測試&#xff1f; 對于很多開發人員來說&#xff0c;單元測試一定不陌生 單元測試是白盒測試的一種形式&#xff0c;它的目標是測試軟件的最小單元——函數、方法或類。單元測試的主要目的是驗證代碼的正確性&#xff0c;以確保每個單元按照預期執行。單元測試通…

合肥高校大學智能制造實驗室數字孿生可視化系統平臺建設項目驗收

合肥高校大學智能制造實驗室近日迎來了一項重要時刻&#xff0c;數字孿生可視化系統平臺建設項目順利通過了驗收。這一項目的成功實施&#xff0c;不僅標志著合肥高校在智能制造領域取得新的突破&#xff0c;為我國智能制造技術的發展注入新活力。 合肥高校智能制造實驗室作為…

T972 切換至pdm 聲音輸入的方法

1.在hardware/amlogic/audio/audio_hal/audio_hw.c下&#xff0c;直接切換 在 static unsigned int select_port_by_device(struct aml_audio_device *adev) 中先強制切換為pdm 2.在device mk 配置文件中 #add fof fix the mic bug by jason 20230621 PRODUCT_PROPERTY_OVE…

MySQL 數據庫基礎概念

一、什么是數據庫&#xff1f; 數據庫&#xff08;Database&#xff09;是按照數據結構來組織、存儲和管理數據的倉庫。 每個數據庫都有一個或多個不同的 API 用于創建&#xff0c;訪問&#xff0c;管理&#xff0c;搜索和復制所保存的數據。 我們也可以將數據存儲在文件中&…

淺析Kafka Streams中KTable.aggregate()方法的使用

KTable.aggregate() 方法是 Apache Kafka Streams API 中用于對流數據進行狀態化聚合的核心方法之一。這個方法允許你根據一個鍵值&#xff08;通常是<K,V>類型&#xff09;的流數據&#xff0c;應用一個初始值和一個聚合函數&#xff0c;來累積和更新一個狀態&#xff0…

MSPM0G3507(三十六)——超聲波PID控制小車固定距離

效果圖&#xff1a; 波形圖軟件是VOFA&#xff0c;B站有教程 &#xff0c;雖然有缺點但是非常簡單。 視頻效果&#xff1a; PID控制距離 之前發過只有超聲波測距的代碼&#xff0c;MSPM0G3507&#xff08;三十二&#xff09;——超聲波模塊移植代碼-CSDN博客 SYSCFG配置&#…

Ubuntu下如何設置程序include搜索路徑及鏈接路徑

添加庫的include及lib路徑 linux下系統默認路徑為 /usr/include, /usr/local/include, gcc在編譯程序時會按照當前目錄路徑->系統默認路徑->系統環境變量的路徑方式去查找&#xff0c;所以當我們想調用的庫未安裝在系統默認路徑時&#xff0c;我們可以通過手動添加環境變…

數據壓縮的藝術:Kylin Cube設計中的自動壓縮特性

數據壓縮的藝術&#xff1a;Kylin Cube設計中的自動壓縮特性 在大數據的浩瀚宇宙中&#xff0c;Apache Kylin以其卓越的數據立方體&#xff08;Cube&#xff09;技術&#xff0c;為企業提供快速的多維數據分析能力。隨著數據量的不斷增長&#xff0c;存儲效率成為了一個關鍵問…

用友NC Cloud blobRefClassSearch FastJson反序列化RCE漏洞復現

0x01 產品簡介 用友 NC Cloud 是一種商業級的企業資源規劃云平臺,為企業提供全面的管理解決方案,包括財務管理、采購管理、銷售管理、人力資源管理等功能,實現企業的數字化轉型和業務流程優化。 0x02 漏洞概述 用友 NC Cloud blobRefClassSearch 接口處存在FastJson反序列…

開源PHP論壇HadSky本地部署與配置公網地址實現遠程訪問

文章目錄 前言1. 網站搭建1.1 網頁下載和安裝1.2 網頁測試1.3 cpolar的安裝和注冊 2. 本地網頁發布2.1 Cpolar臨時數據隧道2.2 Cpolar穩定隧道&#xff08;云端設置&#xff09;2.3 Cpolar穩定隧道&#xff08;本地設置&#xff09;2.4 公網訪問測試 總結 前言 今天和大家分享…

idea啟動ssm項目詳細教程

前言 今天碰到一個ssm的上古項目&#xff0c;項目沒有使用內置的tomcat作為服務器容器&#xff0c;這個時候就需要自己單獨設置tomcat容器。這讓我想起了我剛入行時被外置tomcat配置支配的恐懼。現在我打算記錄一下配置的過程&#xff0c;希望對后面的小伙伴有所幫助吧。 要求…

什么是計算機數據結構的字典

字典數據結構在計算機編程領域中是一個非常重要且常用的數據結構。它也被稱為關聯數組、哈希表或映射&#xff08;Map&#xff09;&#xff0c;在不同編程語言中有不同的實現和稱呼&#xff0c;但其核心概念和用途大致相同。 字典數據結構是一種鍵值對&#xff08;key-value p…