【小程序】微信小程序九宮格抽獎動畫(完整版)

這是一個微信小程序九宮格抽獎頁面的完整代碼,包括 WXML、WXSS、JS 和 JSON。

效果

九宮格抽獎

功能說明:

  1. 靜態頁面布局: 3x3 九宮格,中間是“立即抽獎”按鈕,周圍是獎品金額。
  2. 抽獎動畫: 點擊“立即抽獎”后,九宮格會動態跑馬燈式高亮顯示,最終停留在中獎項。
  3. 中獎提示: 抽獎結束后彈出中獎結果。

1. lottery.json (頁面配置)

{"navigationBarTitleText": "九宮格抽獎","usingComponents": {}
}

2. lottery.wxml (頁面結構)

<view class="container"><view class="lottery-grid"><block wx:for="{{gridItems}}" wx:key="id"><viewclass="lottery-item {{item.isButton ? 'lottery-btn' : ''}} {{item.active ? 'active' : ''}}"data-index="{{item.id}}"bindtap="{{item.isButton ? 'startLottery' : ''}}"><text>{{item.text}}</text></view></block></view>
</view>

3. lottery.wxss (頁面樣式)

/* container */
.container {display: flex;justify-content: center;align-items: center;min-height: 100vh; /* 撐滿整個屏幕高度 */background-color: #f8f8f8;padding: 20rpx;box-sizing: border-box;
}/* 九宮格容器 */
.lottery-grid {display: grid;grid-template-columns: repeat(3, 1fr); /* 3列,每列等寬 */gap: 15rpx; /* 格子之間的間距 */width: 700rpx; /* 九宮格總寬度 */background-color: #fff;border-radius: 20rpx;padding: 15rpx;box-shadow: 0 5rpx 20rpx rgba(0, 0, 0, 0.1);
}/* 抽獎格子公共樣式 */
.lottery-item {width: 100%; /* 充滿父容器的寬度 */height: 200rpx; /* 高度 */display: flex;justify-content: center;align-items: center;background-color: #fdfdfd;border: 4rpx solid #ffd700; /* 金色邊框 */border-radius: 15rpx;font-size: 36rpx;font-weight: bold;color: #333;transition: all 0.1s ease; /* 動畫過渡效果 */box-sizing: border-box; /* 邊框和內邊距不撐大元素 */
}/* 中間抽獎按鈕樣式 */
.lottery-btn {background-color: #ffda47; /* 醒目的黃色 */color: #d84e27; /* 紅色字體 */font-size: 40rpx;border-color: #f77026; /* 橙色邊框 */box-shadow: 0 4rpx 8rpx rgba(255, 165, 0, 0.4);cursor: pointer;
}/* 激活(高亮)狀態樣式 */
.lottery-item.active {background-color: #ff4d4f; /* 紅色高亮 */color: #fff;border-color: #ff0000;transform: scale(1.03); /* 稍微放大 */box-shadow: 0 0 20rpx rgba(255, 77, 79, 0.8);
}/* 按鈕禁用狀態(抽獎進行中) */
.lottery-btn[disabled] {opacity: 0.7;cursor: not-allowed;background-color: #ccc;border-color: #aaa;
}

4. lottery.js (頁面邏輯)

Page({data: {// 九宮格數據// id: 格子索引 (0-8)// text: 顯示的文本// isButton: 是否是抽獎按鈕 (中間格子)// active: 是否是當前高亮格子gridItems: [],// 抽獎相關狀態currentIndex: -1,     // 當前高亮的格子索引isDrawing: false,     // 是否正在抽獎timer: null,          // 抽獎定時器speed: 200,           // 初始轉動速度 (ms)minSpeed: 50,         // 最快轉動速度 (ms)drawCount: 0,         // 已經轉動的次數totalRounds: 3,       // 至少轉動多少圈 (影響動畫時長)finalPrizeIndex: -1,  // 最終中獎的格子索引accelerateSteps: 10,  // 加速階段的步數decelerateSteps: 10,  // 減速階段的步數// 抽獎路徑 (按順時針方向,跳過中間按鈕4)// 0 1 2// 7 X 3  (X是中間按鈕4)// 6 5 4lotteryPath: [0, 1, 2, 5, 8, 7, 6, 3],},onLoad: function () {this.initGridItems();},/*** 初始化九宮格數據*/initGridItems: function () {const initialGridData = [{ id: 0, text: '5元' },{ id: 1, text: '8元' },{ id: 2, text: '10元' },{ id: 3, text: '90元' }, // 注意這個位置,對應抽獎路徑{ id: 4, text: '立即抽獎', isButton: true }, // 中間按鈕{ id: 5, text: '20元' }, // 注意這個位置,對應抽獎路徑{ id: 6, text: '50元' },{ id: 7, text: '40元' },{ id: 8, text: '30元' }];const gridItems = initialGridData.map(item => ({...item,active: false,isButton: item.isButton || false // 確保 isButton 屬性存在}));this.setData({gridItems: gridItems});},/*** 獲取下一個高亮的格子索引*/getNextLotteryIndex: function (currentPathIndex) {const { lotteryPath } = this.data;return (currentPathIndex + 1) % lotteryPath.length;},/*** 開始抽獎*/startLottery: function () {if (this.data.isDrawing) {wx.showToast({title: '正在抽獎中...',icon: 'none'});return;}this.setData({isDrawing: true,drawCount: 0,speed: 200, // 恢復初始速度});// 清除上次的定時器,避免重復if (this.data.timer) {clearTimeout(this.data.timer);}// 模擬抽獎結果,這里排除中間按鈕(index 4)const prizePoolIndexes = this.data.lotteryPath; // 只有周圍的8個格子能中獎const randomIndexInPool = Math.floor(Math.random() * prizePoolIndexes.length);const finalPrizeIndex = prizePoolIndexes[randomIndexInPool];console.log("最終中獎格子索引 (在 lotteryPath 中的位置):", randomIndexInPool);console.log("最終中獎格子在 gridItems 中的實際ID:", finalPrizeIndex);this.setData({finalPrizeIndex: finalPrizeIndex,currentIndex: this.data.lotteryPath[0] // 初始從第一個格子開始}, () => {// 確保 finalPrizeIndex 設置后再啟動動畫this.runLottery();});},/*** 運行抽獎動畫*/runLottery: function () {let { gridItems, currentIndex, drawCount, speed, minSpeed,finalPrizeIndex, lotteryPath, totalRounds, accelerateSteps, decelerateSteps } = this.data;// 清除上一個高亮if (currentIndex !== -1) {let oldGridItems = gridItems;const oldIndexInPath = lotteryPath.indexOf(currentIndex);oldGridItems[lotteryPath[oldIndexInPath]].active = false;this.setData({ gridItems: oldGridItems });}// 計算下一個高亮索引const currentPathIndex = lotteryPath.indexOf(currentIndex);const nextPathIndex = this.getNextLotteryIndex(currentPathIndex);const nextActualIndex = lotteryPath[nextPathIndex];// 更新高亮gridItems[nextActualIndex].active = true;this.setData({gridItems: gridItems,currentIndex: nextActualIndex,drawCount: drawCount + 1});// 計算總的轉動步數,確保至少轉totalRounds圈 + 停到中獎位置// 假設 finalPrizeIndex 是在 lotteryPath 中的實際索引const prizePathIndex = lotteryPath.indexOf(finalPrizeIndex);const minRunSteps = lotteryPath.length * totalRounds + prizePathIndex + 1; // 至少轉的步數// 速度控制let newSpeed = speed;if (drawCount < accelerateSteps) { // 加速階段newSpeed = Math.max(minSpeed, speed - (speed - minSpeed) / accelerateSteps * drawCount);} else if (drawCount >= minRunSteps - decelerateSteps && drawCount < minRunSteps) { // 減速階段newSpeed = Math.min(200, speed + (200 - minSpeed) / decelerateSteps);} else if (drawCount >= minRunSteps) { // 減速到最終結果,確保最終速度不會太快newSpeed = Math.min(newSpeed + 30, 400); // 逐漸變慢}// 檢查是否停止const isStop = drawCount >= minRunSteps && currentIndex === finalPrizeIndex;if (isStop) {clearTimeout(this.data.timer);this.setData({isDrawing: false,timer: null});wx.showModal({title: '恭喜!',content: '您抽中了' + gridItems[finalPrizeIndex].text + '!',showCancel: false,confirmText: '確定'});} else {this.setData({ speed: newSpeed });this.data.timer = setTimeout(() => this.runLottery(), newSpeed);}},onUnload: function() {// 頁面卸載時清除定時器,避免內存泄漏if (this.data.timer) {clearTimeout(this.data.timer);this.setData({ timer: null });}}
});

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

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

相關文章

java類沖突

一、為什么會發生類沖突&#xff1f; 在 Java 的類加載機制中&#xff0c;類的唯一性是由“類加載器類的全限定名”共同決定的。當你的項目依賴了多個 jar 包&#xff0c;這些 jar 包里有同名的類&#xff08;包名和類名完全一樣&#xff09;&#xff0c;但實現卻不同。類加載器…

GIT客戶端配置支持中文

環境&#xff1a;windows10、Git-2.42.0.2-64-bit.exe1. 問題描述客戶端安裝后&#xff0c;默認是不支持中文顯示的&#xff0c;中文名的文件顯示亂碼&#xff0c;提交時打的標簽內容也不支持中文顯示。2. 解決新建Git全局配置文件&#xff0c;文件名為.gitconfig&#xff0c;內…

Teable vs NocoDB 開源、在線協同 多維表格大PK

文章目錄 Teable 簡介 特性 docker-compose部署 功能截圖 NocoDB 簡介 docker-compose部署 功能截圖 總結 Teable 簡介 Teable 是一款企業級高性能多維表格解決方案,通過無代碼方式快速構建業務管理系統,支持私有部署和精細權限管理。 官方文檔 特性 ?? 卓越性能 輕松處…

SQL專家云能做哪些事兒?

背景數據庫是信息化的基石&#xff0c;支撐著整個業務系統&#xff0c;發揮著非常重要的作用&#xff0c;被喻為“IT的心臟”。因此&#xff0c;讓數據庫安全、穩定、高效地運行已經成為IT管理者必須要面對的問題。但是很多組織沒有專業的DBA&#xff0c;數據庫運維面臨著極大的…

Python 高效實現 Word 轉 PDF:告別 Office 依賴

在工作中&#xff0c;經常會遇到需要把 Word 文檔轉換成 PDF 的情況。比如生成報表、分發文檔、或者做歸檔保存&#xff0c;PDF 格式在排版和跨平臺顯示上更穩定。傳統的做法往往依賴 Microsoft Office 或 LibreOffice 等軟件來完成轉換&#xff0c;但在自動化環境&#xff08;…

SQL優化簡單思路

1. 背景 在實際生產中&#xff0c;因為SQL較慢、SQL關聯不合理、不了解索引的性質、不熟悉mysql執行計劃分析&#xff0c;可能會出現一些生產事故&#xff0c;本文會簡單說明SQL通常的優化分析思路。 基本的優化原則&#xff1a; 先優化SQL再優化mysql server最后優化硬件 2. 優…

軟考 系統架構設計師系列知識點之雜項集萃(144)

接前一篇文章:軟考 系統架構設計師系列知識點之雜項集萃(143) 第268題 甲、乙、丙、丁4人加工A、B、C、D四種工件所需工時如下表所示。指派每人加工一種工件,四人加工四種工件其總工時最短的最優方案中,工件B應由()加工。 A B C D 甲

P1168 中位數

題目描述給定一個長度為 N 的非負整數序列 A&#xff0c;對于前奇數項求中位數。輸入格式第一行一個正整數 N。第二行 N 個正整數 A1…N?。輸出格式共 ?2N1?? 行&#xff0c;第 i 行為 A1…2i?1? 的中位數。輸入輸出樣例輸入 #1復制7 1 3 5 7 9 11 6輸出 #11 3 5 6輸入 #…

【CE】圖形化CE游戲教程通關手冊

【CE】圖形化CE游戲教程通關手冊 文章目錄【CE】圖形化CE游戲教程通關手冊導讀需求1?? 第一關提示操作總結2?? 第二關&#xff08;代碼共享&#xff09;提示操作驗證3?? 第三關提示提示總結導讀 需求 除了Tutorial-x86_64.exe教程外&#xff0c;CE還提供了圖形化教程gtu…

leetcode 2785. 將字符串中的元音字母排序 中等

給你一個下標從 0 開始的字符串 s &#xff0c;將 s 中的元素重新 排列 得到新的字符串 t &#xff0c;它滿足&#xff1a;所有輔音字母都在原來的位置上。更正式的&#xff0c;如果滿足 0 < i < s.length 的下標 i 處的 s[i] 是個輔音字母&#xff0c;那么 t[i] s[i] 。…

支付子系統架構及常見問題

支付流程對于支付系統來說&#xff0c;它最重要的其實是安全&#xff0c;所以整個支付流程采用秘鑰加簽的方式進行操作&#xff0c;一共四對秘鑰&#xff0c;以支付寶在線支付為例子&#xff0c;首先通過RSA2算法生成商戶公鑰以及商戶私鑰&#xff0c;同時支付寶平臺會提供支付…

內存傳輸速率MT/s

1 0 0 0 0 0 0 0 0 010 9 8 7 6 5 4 3 2 1十 億 千 百 十 萬 千 百 十 個億 萬 萬 萬傳輸速率 …

.env文件的作用和使用方法

目錄 什么是 .env 文件&#xff1f; 為什么要使用 .env 文件&#xff1f;&#xff08;好處&#xff09; 如何使用 .env 文件&#xff1f; 通用步驟&#xff1a; 具體技術棧中的實現&#xff1a; 最佳實踐和注意事項 總結 什么是 .env 文件&#xff1f; .env 文件&#x…

深度拆解 Python 裝飾器參數傳遞:從裝飾器生效到參數轉交的每一步

在 Python 裝飾器的學習中&#xff0c;“被裝飾函數的參數如何傳遞到裝飾器內層函數”是一個高頻疑問點。很多開發者能寫出裝飾器的基本結構&#xff0c;卻對參數傳遞的底層邏輯一知半解。本文將以一段具體代碼為例&#xff0c;把參數傳遞過程拆成“裝飾器生效→調用觸發→參數…

【Vue2 ?】Vue2 入門之旅 · 進階篇(七):Vue Router 原理解析

在前幾篇文章中&#xff0c;我們介紹了 Vue 的性能優化機制、組件緩存等內容。本篇將深入解析 Vue Router 的原理&#xff0c;了解 Vue 如何管理路由并進行導航。 目錄 Vue Router 的基本概念路由模式&#xff1a;hash 和 history路由匹配原理導航守衛Vue Router 的路由過渡動…

Linux磁盤級文件/文件系統理解

Linux磁盤級文件/文件系統理解 1. 磁盤的物理結構 磁盤的核心是一個利用磁性介質和機械運動進行數據讀寫的、非易失性的存儲設備。 1.1 盤片 盤片是傳統機械硬盤中最核心的部件&#xff0c;它是數據存儲的物理載體。盤片是一個堅硬的、表面極度光滑的圓形碟片&#xff0c;被安裝…

【星海出品】rabbitMQ - 叁 應用篇

rabbitMQ 的基礎知識這里就不闡述了,可以參看我早年寫的文章 -> rabbitMQ 入門 https://blog.csdn.net/weixin_41997073/article/details/118724779 Celery 官網:http://www.celeryproject.org/ Celery 官方文檔英文版:http://docs.celeryproject.org/en/latest/index.h…

C# 每個chartArea顯示最小值、平均值、最大值

private void AddStatisticsAnnotations(ChartArea chartArea, int channelIndex) {RemoveExistingAnnotations(channelIndex);// 獲取ChartArea的相對坐標&#xff08;百分比&#xff09;float chartAreaX chartArea.Position.X; // X坐標&#xff08;百分比&#xff09;floa…

打破“不可能三角”:WALL-OSS開源,具身智能迎來“安卓時刻”?

目錄 引言&#xff1a;當“大腦”學會思考&#xff0c;機器人才能走出實驗室 一、具身智能的“不可能三角”&#xff1a;機器人“大腦”的核心困境 二、WALL-OSS的四把重錘&#xff1a;如何系統性地破解難題&#xff1f; 2.1 第一錘&#xff1a;更聰明的“大腦”架構 —— …

SigNoz分布式追蹤新體驗:cpolar實現遠程微服務監控

前言 SigNoz是一款開源的應用性能監控工具&#xff0c;專為微服務架構設計&#xff0c;集成了指標、追蹤和日志分析功能。它能夠全面監控分布式系統的性能&#xff0c;幫助開發團隊快速定位問題根源。SigNoz支持OpenTelemetry協議&#xff0c;可以無縫集成各種編程語言和框架&…