当前位置: 首页 > news >正文

微信小程序实战:幸运抽奖小程序

一、项目介绍

1.1 项目简介

本项目是一款基于微信小程序的蓝粉色梦幻风盲盒幸运抽奖系统,模拟商场线下抽奖活动场景。摒弃传统大转盘样式,采用当下流行的福袋盲盒抽奖交互,界面采用清新蓝粉色渐变主题,搭配漂浮动画、毛玻璃卡片、渐变按钮,整体美观、年轻化、吸引力强。项目完整实现了抽奖业务逻辑、页面动态交互、数据绑定、定时器动画、页面传参等小程序核心技术点。空白代码包和图片文件已在顶部的链接给出,可自行下载学习。

1.2 功能介绍

  • 蓝粉色全局主题UI:导航栏、背景、按钮统一蓝粉渐变风格

  • 福袋盲盒抽奖:抽奖过程福袋左右晃动动画

  • 双按钮控制:开始抽奖、停止开奖

  • 抽奖次数限制:每日默认3次抽奖机会

  • 动态状态提示:空闲/抽奖中文字动态切换

  • 奖品结果页展示:展示奖品图片、奖品名称、奖品描述

  • 抽奖规则弹窗:点击弹窗展示活动说明

  • 全局漂浮装饰动画:爱心、星星、光点浮动特效

效果展示:

1.3 项目目录结构

项目根目录 ├─ images # 抽奖所需图片资源 │ ├─ box.png # 福袋盲盒图片 │ ├─ p1.png # 一等奖 │ ├─ p2.png # 二等奖 │ ├─ p3.png # 三等奖 │ ├─ p4.png # 参与奖 │ ├─ p5.png # 幸运奖 │ ├─ p6.png # 纪念奖 │ ├─ p7.png # 购物奖 │ └─ p8.png # 谢谢参与 ├─ pages │ ├─ index # 抽奖首页 │ └─ result # 抽奖结果页 ├─ app.js # 全局逻辑 ├─ app.json # 全局配置 └─ app.wxss # 全局样式

二、完整可运行代码 + 逐文件知识点讲解

2.1 app.json 全局配置文件

功能:注册页面、配置导航栏整体样式、主题颜色

{ "pages": [ "pages/index/index", "pages/result/result" ], "window": { "navigationBarBackgroundColor": "#FFA1D9", "navigationBarTitleText": "幸运抽奖小程序", "navigationBarTextStyle": "white" }, "style": "v2", "sitemapLocation": "sitemap.json" }

知识点 & 用到的API

  • pages:小程序页面注册,数组第一个为默认首页

  • navigationBarBackgroundColor:导航栏背景色(蓝粉色主题)

  • navigationBarTitleText:导航栏标题文字

  • navigationBarTextStyle:导航文字颜色仅支持 black / white

  • style:v2:启用小程序新版样式渲染

2.2 app.wxss 全局样式文件

功能:统一全局背景、布局、清除默认样式,实现蓝粉渐变全局背景

page { margin: 0; padding: 0; background: linear-gradient(135deg, #A8E6FF 0%, #FFD1F0 100%); min-height: 100vh; font-family: "PingFang SC","Microsoft YaHei",sans-serif; } .container { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40rpx; min-height: 100vh; position: relative; } button::after { border: none; }

知识点

  • linear-gradient:CSS渐变背景,实现蓝粉梦幻配色

  • Flex 垂直居中布局:页面内容居中显示

  • rpx 自适应单位:小程序专属适配所有手机

  • button::after:清除微信按钮默认边框

2.3 首页 index.json

{ "navigationBarTitleText": "幸运抽奖小程序 " }

知识点

页面独立配置,优先级高于全局配置,单独设置当前页面导航标题。

2.4 首页 index.wxml 结构代码

<view class="container"> <!-- 装饰图案 --> <view class="decorations"> <view class="decoration cloud"></view> <view class="decoration heart"></view> <view class="decoration star"></view> <view class="decoration star"></view> <view class="decoration star"></view> </view> <!-- 标题 --> <view class="title-box"> <text class="title">🎁 幸运抽奖</text> <text class="subtitle">Lucky Draw</text> </view> <!-- 福袋盲盒 --> <view class="gift-container"> <image src="/images/box.png" class="gift-box {{running ? 'shake' : ''}}" mode="aspectFill"></image> <view class="status">{{running ? '正在抽奖中...' : '点击福袋开启好运'}}</view> </view> <!-- 抽奖次数 --> <view class="count-box"> <text>今日剩余次数:{{count}}</text> </view> <!-- 操作按钮 --> <view class="btn-group"> <button class="btn start" disabled="{{running || count == 0}}" bindtap="start">开始抽奖</button> <button class="btn stop" disabled="{{!running}}" bindtap="stop">停止</button> </view> <!-- 抽奖规则 --> <view class="rule" bindtap="showRule">抽奖规则</view> </view>

知识点 & API

  • 数据绑定 {{}}:渲染 js 中的变量数据

  • 三元表达式:动态切换文字、动画 class

  • bindtap:点击事件绑定 API

  • disabled:按钮禁用状态动态控制

  • image 组件:展示本地图片资源

  • 条件动态class:抽奖时自动添加晃动动画

2.5 首页 index.wxss 样式代码

/* 装饰图案 */ .decorations { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; overflow: hidden; } .decoration { position: absolute; opacity: 0.7; animation: float 8s ease-in-out infinite; } .cloud { width: 120rpx; height: 60rpx; background: rgba(255, 255, 255, 0.8); border-radius: 50%; top: 10%; left: 10%; animation-delay: 0s; } .cloud::before, .cloud::after { content: ''; position: absolute; background: rgba(255, 255, 255, 0.8); border-radius: 50%; } .cloud::before { width: 60rpx; height: 60rpx; top: -30rpx; left: 20rpx; } .cloud::after { width: 40rpx; height: 40rpx; top: -20rpx; right: 10rpx; } .heart { width: 40rpx; height: 40rpx; background: #F8BBD0; transform: rotate(45deg); top: 20%; right: 15%; animation-delay: 1s; } .heart::before, .heart::after { content: ''; position: absolute; width: 40rpx; height: 40rpx; background: #F8BBD0; border-radius: 50%; } .heart::before { top: -20rpx; left: 0; } .heart::after { top: 0; left: -20rpx; } .star { width: 0; height: 0; border-left: 20rpx solid transparent; border-right: 20rpx solid transparent; border-bottom: 35rpx solid #B3E5FC; transform: rotate(30deg); top: 30%; left: 20%; animation-delay: 2s; } .star::before { content: ''; position: absolute; width: 0; height: 0; border-left: 20rpx solid transparent; border-right: 20rpx solid transparent; border-bottom: 35rpx solid #B3E5FC; transform: rotate(-70deg); top: -18rpx; left: -20rpx; } @keyframes float { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-20rpx) rotate(5deg); } } /* 标题 */ .title-box{text-align:center;margin-bottom:80rpx;} .title{display:block;font-size:68rpx;font-weight:bold;color:#6A1B9A;text-shadow:0 6rpx 15rpx rgba(106, 27, 154, 0.2);letter-spacing:4rpx;} .subtitle{font-size:28rpx;color:#880E4F;letter-spacing:6rpx;} /* 福袋 */ .gift-container{display:flex;flex-direction:column;align-items:center;margin-bottom:60rpx;} .gift-box{width:340rpx;height:340rpx;border-radius:50rpx;box-shadow:0 25rpx 45rpx rgba(106, 27, 154, 0.2);margin-bottom:30rpx;transition: all 0.3s ease;} .gift-box:hover { transform: translateY(-10rpx); } .shake{animation:shake 0.18s infinite alternate;} @keyframes shake{from{transform:rotate(-6deg);}to{transform:rotate(6deg);}} .status{font-size:32rpx;color:#6A1B9A;} /* 次数 */ .count-box{background:rgba(179, 229, 252, 0.5);padding:16rpx 36rpx;border-radius:50rpx;margin-bottom:50rpx;backdrop-filter: blur(10rpx);} .count-box text{color:#6A1B9A;font-size:28rpx;} /* 按钮组 */ .btn-group{display:flex;gap:35rpx;margin-bottom:40rpx;} .btn{width:240rpx;height:90rpx;font-size:34rpx;border-radius:50rpx;color:#fff;display:flex;align-items:center;justify-content:center;box-shadow:0 10rpx 20rpx rgba(0,0,0,0.15);transition: all 0.3s ease;} .btn:hover { transform: translateY(-5rpx); box-shadow: 0 15rpx 25rpx rgba(0,0,0,0.2); } .start{background:linear-gradient(90deg,#92d2e6,#2febf1);color:#6A1B9A;font-weight:bold;} .stop{background:linear-gradient(90deg,#FF8A65,#F4511E);} .btn[disabled]{background:#bbb!important;color:#777!important;box-shadow:none;transform: none;} /* 规则 */ .rule{font-size:24rpx;color:#880E4F;margin-top:10rpx;}

知识点

  • @keyframes 关键帧动画:实现漂浮、晃动效果

  • clip-path:裁剪星星形状

  • box-shadow:卡片阴影提升立体感

  • 渐变按钮:蓝粉双色渐变搭配主题

  • 文字阴影 text-shadow:提升文字质感

2.6 首页 index.js 逻辑代码(核心)

Page({ data: { running: false, count: 3, timer: null, prizeIndex: 0 }, start() { if (this.data.running || this.data.count <= 0) return; this.setData({ running: true, count: this.data.count - 1 }); const timer = setInterval(() => { this.setData({ prizeIndex: Math.floor(Math.random() * 8) }); },100); this.setData({timer}) }, stop() { clearInterval(this.data.timer); this.setData({ running: false }); wx.navigateTo({url:`/pages/result/result?index=${this.data.prizeIndex}`}) }, showRule() { wx.showModal({title:'抽奖规则',content:'1.每日免费3次抽奖;2.中奖奖品前往商场服务台兑换;3.活动最终解释权归商场',showCancel:false}) }, onUnload(){clearInterval(this.data.timer)} })

核心API & 知识点

  • Page():注册页面

  • data:页面数据存储

  • setData():修改数据、更新视图

  • setInterval():定时器快速切换奖品模拟抽奖

  • clearInterval():关闭定时器

  • Math.random():随机数生成奖品

  • wx.navigateTo():页面跳转+传参

  • wx.showModal():弹窗提示API

  • onUnload:页面卸载生命周期,防止定时器残留

2.7 结果页 result.json

{ "navigationBarTitleText": "抽奖结果" }

2.8 结果页 result.wxml

<view class="container"> <!-- 装饰图案 --> <view class="decorations"> <view class="decoration cloud"></view> <view class="decoration heart"></view> <view class="decoration star"></view> </view> <!-- 抽奖结果卡片 --> <view class="result-card"> <image src="/images/{{prize.img}}" class="prize-img" mode="aspectFill"></image> <text class="result-name">{{prize.name}}</text> <text class="result-desc">{{prize.desc}}</text> </view> <!-- 返回按钮 --> <button class="back-btn" bindtap="back">继续抽奖</button> </view>

2.9 结果页 result.wxss

/* 装饰图案 */ .decorations { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; overflow: hidden; } .decoration { position: absolute; opacity: 0.7; animation: float 8s ease-in-out infinite; } .cloud { width: 120rpx; height: 60rpx; background: rgba(255, 255, 255, 0.8); border-radius: 50%; top: 10%; left: 10%; animation-delay: 0s; } .cloud::before, .cloud::after { content: ''; position: absolute; background: rgba(255, 255, 255, 0.8); border-radius: 50%; } .cloud::before { width: 60rpx; height: 60rpx; top: -30rpx; left: 20rpx; } .cloud::after { width: 40rpx; height: 40rpx; top: -20rpx; right: 10rpx; } .heart { width: 40rpx; height: 40rpx; background: #F8BBD0; transform: rotate(45deg); top: 20%; right: 15%; animation-delay: 1s; } .heart::before, .heart::after { content: ''; position: absolute; width: 40rpx; height: 40rpx; background: #F8BBD0; border-radius: 50%; } .heart::before { top: -20rpx; left: 0; } .heart::after { top: 0; left: -20rpx; } .star { width: 0; height: 0; border-left: 20rpx solid transparent; border-right: 20rpx solid transparent; border-bottom: 35rpx solid #B3E5FC; transform: rotate(30deg); top: 30%; left: 20%; animation-delay: 2s; } .star::before { content: ''; position: absolute; width: 0; height: 0; border-left: 20rpx solid transparent; border-right: 20rpx solid transparent; border-bottom: 35rpx solid #B3E5FC; transform: rotate(-70deg); top: -18rpx; left: -20rpx; } @keyframes float { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-20rpx) rotate(5deg); } } /* 结果卡片 */ .result-card { background: rgba(255, 255, 255, 0.8); padding: 80rpx 60rpx; border-radius: 40rpx; text-align: center; box-shadow: 0 30rpx 50rpx rgba(106, 27, 154, 0.2); margin-bottom: 70rpx; min-width: 400rpx; backdrop-filter: blur(10rpx); transition: all 0.3s ease; } .result-card:hover { transform: translateY(-10rpx); box-shadow: 0 40rpx 60rpx rgba(106, 27, 154, 0.3); } .prize-img{ width:240rpx; height:240rpx; margin:0 auto 20rpx; border-radius:20rpx; box-shadow: 0 10rpx 20rpx rgba(0,0,0,0.1); } .result-name { font-size: 52rpx; font-weight: bold; color: #6A1B9A; display: block; margin-bottom: 20rpx; } .result-desc { font-size: 30rpx; color: #880E4F; } /* 返回按钮 */ .back-btn { background: linear-gradient(90deg, #b9e7bc, #8af7d6); color: #02529c; font-weight: bold; width: 320rpx; height: 90rpx; border-radius: 50rpx; font-size: 34rpx; display: flex; align-items: center; justify-content: center; box-shadow: 0 10rpx 20rpx rgba(0,0,0,0.15); transition: all 0.3s ease; } .back-btn:hover { transform: translateY(-5rpx); box-shadow: 0 15rpx 25rpx rgba(0,0,0,0.2); }

知识点

  • backdrop-filter: blur:毛玻璃磨砂效果

  • 透明卡片布局:现代化UI设计

  • 延续全局蓝粉渐变主题,界面统一

2.10 结果页 result.js

const prizeArr = [ {img:"p1.png",name:"一等奖",desc:"品牌微波炉一台"}, {img:"p2.png",name:"二等奖",desc:"200元商场实体购物卡"}, {img:"p3.png",name:"三等奖",desc:"50元无门槛代金券"}, {img:"p4.png",name:"参与奖",desc:"高档保温水杯"}, {img:"p5.png",name:"幸运奖",desc:"10元商超现金券"}, {img:"p6.png",name:"纪念奖",desc:"可爱毛绒玩偶"}, {img:"p7.png",name:"购物奖",desc:"30元全场优惠券"}, {img:"p8.png",name:"谢谢参与",desc:"精美小挂件礼品"} ] Page({ data:{prize:{}}, onLoad(options){ let idx = Number(options.index)||7; this.setData({prize:prizeArr[idx]}) }, back(){wx.navigateBack()} })

知识点 & API

  • onLoad(options):页面加载生命周期,接收跳转传参

  • 数组对象存储奖品数据:数据与视图分离

  • wx.navigateBack():返回上一页API

三、图片资源命名清单(必须严格对应)

将9张图片放入项目images文件夹:

  • box.png —— 福袋盲盒封面

  • p1.png —— 一等奖微波炉

  • p2.png —— 200元购物卡

  • p3.png —— 50元代金券

  • p4.png —— 高档保温杯

  • p5.png —— 10元现金券

  • p6.png —— 毛绒玩偶

  • p7.png —— 30元无门槛券

  • p8.png —— 精美小礼品

四、项目总结

本项目完成了一款高颜值蓝粉色梦幻风微信盲盒抽奖小程序。项目使用微信小程序原生技术开发,实现了页面布局、动态装饰动画、福袋抽奖动画、随机抽奖逻辑、次数限制、页面传参、结果渲染等功能。熟练掌握了小程序数据绑定、事件监听、定时器、页面跳转、CSS动画、Flex布局、毛玻璃效果等核心知识点,界面美观、交互流畅、功能完整,达到小程序前端开发基础实验要求。

http://www.jsqmd.com/news/952550/

相关文章:

  • 婴幼儿人脸识别技术挑战与深度学习解决方案
  • 告别32位限制!手把手教你用MX Component V5在Win10/11上搞定三菱PLC通信(C#/VB.NET通用)
  • AWVS新手避坑指南:用DVWA靶场完成你的第一次Web漏洞扫描
  • 免费Steam创意工坊下载器WorkshopDL:跨平台模组下载完整指南
  • 地铁客流实时预测系统源码(Vue+Django+LSTM,含热力图与断面分析)
  • 【鸿蒙 PC三方库构建系统】SHA 库 鸿蒙PC 适配详解
  • VMware克隆三台CentOS 7虚拟机后,别忘了检查这3个网络配置!否则集群搭建第一步就失败
  • 一文讲清楚 Agent 权限怎么做:从最小权限到提示注入防护
  • 别再死记硬背BMS架构了!用一张图搞懂集中式与分布式的核心差异与选型指南
  • 告别数小时环境配置:用快马平台云端qt环境即刻开启高效开发
  • 从MobileNetV3的h-swish激活函数聊起:为什么Google要放弃Swish?手把手复现与性能对比
  • HMS Core 5.2.0实战:用Network Kit给你的App网络请求和文件传输“提提速”
  • AWVS扫描DVWA实战:从78个漏洞报告看如何优化扫描策略与结果分析
  • 吴恩达深度学习笔记:手把手教你推导深层神经网络的前向与反向传播(附矩阵维度检查技巧)
  • 如何突破文档下载限制:kill-doc一站式解决方案
  • Linux 内核中的 cgroups:从资源隔离到内存规约
  • 别再只盯着PS的GPIO了!手把手教你用Vivado配置AXI GPIO软核,点亮PL端第一个LED
  • Linux → QNX 程序移植:API 差异与适配指南
  • 2026年5月正规的展馆设计维护推荐,主题展厅设计/文化馆设计/展馆设计/展厅设计/纪念馆设计,展馆设计制作推荐 - 品牌推荐师
  • 2026义乌疏通下水道、马桶实测榜单|首选老牌靠谱店,避坑指南收好 - 极速版本
  • SystemVerilog 2012新特性实战:用‘with’和‘bins for sequence’写出更智能的覆盖率模型
  • 手把手教你用Simulink搭建直流电机调速模型:从开环到PI闭环的完整仿真流程
  • AI Agent 产品冷启动:从技术 Demo 到杀手级价值产品的跨越
  • 避坑指南:Zynq AXI GPIO中断配置的5个常见错误与解决方法(基于Vivado SDK)
  • 中空XY晶圆检测平台:为半导体量测而生的精密运动核心
  • 从FreeRTOS转向ThreadX:在STM32H743上体验微软RTOS的差异与配置要点
  • 2026年近期浙江酒瓶采购方寻求优质厂家,这家企业值得深度关注 - 2026年企业资讯
  • 如何精准识别辖区内企业技术需求以提高产学研对接效率?
  • 别再只调光圈了!聊聊手机拍照时,那个帮你‘咔嚓’一下变清晰的幕后功臣——3A算法之AF
  • 逆向思维抓包:当APP检测代理时,如何用Fiddler+夜神模拟器依然搞定数据捕获?