介绍

使用支付宝原有的大转盘营销组件进行改造的,由于背景使用的图片,目前只支持 6 个奖品,一般情况下的大转盘都是这个规格。
转盘停止:之前使用的是计算角度来完成的,没有那种缓慢停止的动画。现在加了一个缓慢停止的动画,让抽奖变得更加顺滑
录出来的动图可能会看到转盘往相反方向转动,但是真机的视觉效果上是看不出来的。

转盘效果图


页面代码

index.axml

<view class="lucky-draw-wrapper"><view class="chance-logs-container"><view class="remaining-chance">您有<text class="chance">{{ chance }}</text>次抽奖机会</view></view><turntableprizeList="{{ prizeList }}"rotTimes="{{ chance }}"onStart="onStart"onFinish="onFinish"onTimesUp="onTimesUp"/>
</view>

index.js

Page({data: {prizeList: [{prizeId: '646739d6dcca4d1f505cb0d3',name: 'H&M100元优惠券',type: 'COUPON',image: 'https://gw.alipayobjects.com/zos/rmsportal/nIQUKeYBbJWliGJVhVmx.png',},{prizeId: '646739d6dcca4d1f505cb0d4',name: '2元话费券',type: 'COUPON',image: 'https://gw.alipayobjects.com/zos/rmsportal/HkrVjjjuxZPUMCUbPazb.png',},{prizeId: '646739d6dcca4d1f505cb0d5',name: '45元飞猪出行券',type: 'COUPON',image: 'https://gw.alipayobjects.com/zos/rmsportal/cDctUxwBLPCszQHRapYV.png',},{prizeId: '646739d6dcca4d1f505cb0d6',name: 'H&M10元优惠券',type: 'COUPON',image: 'https://gw.alipayobjects.com/zos/rmsportal/FAmIWZAWpUwlRFKqQDLz.png',},{prizeId: '646739d6dcca4d1f505cb0d7',name: '2元流量券',type: 'COUPON',image: 'https://gw.alipayobjects.com/zos/rmsportal/cuGomeXzMyeeZMjvVjBj.png',},{prizeId: '646739d6dcca4d1f505cb0d8',name: '谢谢参与',type: 'NONE',image: 'https://zos.alipayobjects.com/rmsportal/dwhgPyWAcXuvJAWlSSgU.png',},],chance: 3,},onLoad() {},async onStart() {return this.data.prizeList[Math.floor(Math.random() * 6)];},async onFinish(result) {if (!result) {return;}const { type, name } = result;my.showToast({type: 'none',content: type === 'NONE' ? '很遗憾,差点就中奖了' : `恭喜您,获得${name}`,});this.setData({chance: this.data.chance - 1,});},onTimesUp() {my.showToast({type: 'none',content: '您的抽奖次数已用完',});},
});

index.json

{"transparentTitle": "auto","titlePenetrate":"YES","barButtonTheme": "default","usingComponents": {"turntable": "./components/Turntable/index"}
}

turntable 组件代码

index.axml

<view class="turntable-container" style="width:{{ width }}rpx; height:{{ width }}rpx;"><viewclass="turntable-list {{ animationStatus }}"style="background:url('{{ bgImg }}') 0% 0% / 100% 100% no-repeat; {{ transform }}"><view a:for="{{ prizeList }}" a:for-index="i"><view class="turntable-item"><viewclass="turntable-img"style="width:{{ prizeWidth }}; padding-top:{{ prizePaddingTop }}; transform:rotate({{ (i + 0.5) / 6 }}turn);{{ itemTransformOrigin }}"><view class="prize-name {{ item.type === 'NONE' ? 'none' : '' }}">{{ item.name }}</view><view a:if="{{ item.coupon }}" class="desc">{{ item.coupon.shortDesc }}</view><image src="{{ item.image }}" mode="widthFix" class="prize-img" /></view></view></view></view><view class="turntable-btn" ><image src="{{ btnImg }}" mode="widthFix" class="img" onTap="onDraw" /></view>
</view>

index.acss

.turntable-container {position: relative;margin: auto;border-radius: 50%;overflow: hidden;
}.turntable-list {position: absolute;border-radius: 50%;width: inherit;height: inherit;transition: all 6s ease;-webkit-transition: all 6s ease;
}.turntable-list.scrolling {animation: scroll-start 0.4s linear infinite;
}@keyframes scroll-start {from {transform: rotate(0);}to {transform: rotate(360deg);}
}.turntable-list.stop {animation: scroll-slow-down 0.7s ease-out;
}@keyframes scroll-slow-down {from {transform: rotate(0);}to {transform: rotate(360deg);}
}.turntable-list.stop-win {animation: scroll-slow-down-win 0.7s ease-out;
}@keyframes scroll-slow-down-win {from {transform: rotate(0);}to {transform: rotate(330deg);}
}.turntable-item {position: absolute;left: 0;top: 0;width: 100%;height: 100%;
}.turntable-img {position: relative;display: block;margin: 0 auto;text-align: center;display: flex;flex-direction: column;align-items: center;
}.turntable-img .prize-name {width: 200rpx;padding: 30rpx 0 20rpx;color: #000;font-weight: 600;font-size: 32rpx;line-height: 30rpx;text-align: center;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}.turntable-img .prize-name.none {color: rgba(17, 17, 17, 0.55);
}.turntable-img .desc {margin-top: -10rpx;font-size: 20rpx;line-height: 28rpx;color: rgba(0, 0, 0, 0.65);
}.turntable-img .prize-img {display: block;max-width: 120rpx;height: 85rpx;
}.turntable-btn {position: absolute;top: -12rpx;left: 0;width: 100%;height: 100%;display: flex;align-items: center;justify-content: center;
}.turntable-btn .img {width: 20%;
}

index.js

Component({data: {degValue: 0, // 旋转角度prizeWidth: 0, // 奖项背景图宽度计算值prizePaddingTop: 0, // 奖项上边距计算值itemTransformOrigin: '', // 奖项旋转原点计算值animationStatus: '',transform: '',},props: {width: 690, // 画布大小,默认单位 rpxinitDeg: 0, // 初始旋转角度rotTimes: 0, // 抽奖机会次数prizeList: [], // 奖品列表prizeWidth: NaN, // 奖项宽度prizePaddingTop: NaN, // 奖项距离圆弧的内边距bgImg: 'https://gw.alipayobjects.com/zos/rmsportal/YIunNQVWkFRxUTaUNhOZ.png', // 背景图btnImg: 'https://gw.alipayobjects.com/zos/rmsportal/JHenAywYHZTLbbrnkIFN.png', // 按钮图onStart() {}, // 开始回调onFinish() {}, // 结束回调onTimesUp() {}, // 次数用尽的回调},didMount() {const widthNum = this._getNum(this.props.width);const widthUnit = this._getUnit(this.props.width);const { prizeWidth } = this.props;const paddingTop = this.props.prizePaddingTop;this.setData({degValue: this.props.initDeg,itemTransformOrigin: `transform-origin: 50% ${0.5 * widthNum}${widthUnit};`,prizeWidth: isNaN(prizeWidth) ? this._calculatePrizeWidth() : prizeWidth,prizePaddingTop: isNaN(paddingTop) ? this._calculatePrizePaddingTop() : paddingTop,});this.count = 6; // 奖品个数this.rotNum = 0; // 当前是第几次抽奖this.onRunning = false; // 是否正在抽奖},methods: {async onDraw() {if (this.onRunning) {return;}if (this.props.rotTimes < 1) {this.props.onTimesUp();return;}this.onRunning = true;this.setData({ animationStatus: 'scrolling' });const result = await this.props.onStart();// 延迟2秒钟展示奖品setTimeout(() => {this.done(result);}, 2000);},done(result) {if (!result) {this.onRunning = false;this.props.onFinish(null);this.setData({ animationStatus: 'stop', transform: '' });return;}this.setData({ animationStatus: 'stop-win', transform: 'transform: rotate(-30deg);' });let tempData = this.props.prizeList;for (let index = 0; index < tempData.length; index++) {if (tempData[index].prizeId === result.prizeId) {const itemAfterIndex = tempData.slice(index, this.props.prizeList.length);const itemBeforeIndex = tempData.slice(0, index);tempData = itemAfterIndex.concat(...itemBeforeIndex);}}this.setData({prizeList: tempData,});// 转盘停止1秒钟后展示弹框setTimeout(() => {this.onRunning = false;this.props.onFinish(result);}, 1000);},_getNum(str) {// 获取像素选项数值return parseFloat(str);},_getUnit(str) {// 获取像素选项单位// eslint-disable-next-line no-param-reassignstr += '';return (str.match(/[a-z]+$/) || [])[0] || 'rpx';},_calculatePrizeWidth() {// 等边三角形内接正方形边长: (4 - 2 * 根号3) * 边长const widthNum = this._getNum(this.props.width);const widthUnit = this._getUnit(this.props.width);return (4 - 2 * Math.sqrt(3)) * 0.5 * widthNum + widthUnit;},_calculatePrizePaddingTop() {// 等边三角形一边的中点离过该边两点的圆弧的距离: 边长 - 边长 * (根号3 / 2)const widthNum = this._getNum(this.props.width);const widthUnit = this._getUnit(this.props.width);return 0.5 * widthNum - 0.25 * widthNum * Math.sqrt(3) + widthUnit;},},
});

index.json

{"component": true
}

支付宝 小程序 抽奖组件 大转盘相关推荐

  1. 微信小程序项目实例——幸运大转盘

    微信小程序项目实例--幸运大转盘 文章目录 微信小程序项目实例--幸运大转盘 一.项目展示 二.抽奖页 三.领奖页 文末:项目代码 项目代码见文字底部,点赞关注有惊喜 一.项目展示 幸运大转盘是一个简 ...

  2. 支付宝小程序camera组件取景框绘制

    因公司需求,要将微信小程序转战到支付宝上面,恰好又是原生的写法,那只能迎着公司的需求来咯 现有一套微信的现成的源码,又不想重新写,费时又费力,这里推荐一个微信转支付宝的插件,贼好用 Antmove 小 ...

  3. 钉钉/支付宝小程序自定义组件

    钉钉/支付宝小程序自定义组件 1.新建自定义文件夹 eg:model 2.鼠标选中model 右键>新建小程序组件 输入测试组件:demo 3.新建小程序组件包含四个文件: 1.acss:组件页 ...

  4. 微信小程序开发之大转盘 仿天猫超市抽奖

    天猫超市翻牌的转盘经常用,以前做Android,没啥想法,现在尝试微信小程序,看到别人家APP里有啥好玩的,就想去做一个. 上GIF看效果: 简要的说一下. 1.外面一圈闪烁的小球是用js控制的样式. ...

  5. 010 - 微信小程序开发之大转盘 仿天猫超市抽奖

    天猫超市翻牌的转盘经常用,以前做Android,没啥想法,现在尝试微信小程序,看到别人家APP里有啥好玩的,就想去做一个. 上GIF看效果: 简要的说一下. 1.外面一圈闪烁的小球是用js控制的样式. ...

  6. 微信小程序开发之大转盘 抽奖

    上代码: 1.index.wxml <view class="container-out"><view class="circle" wx:f ...

  7. 支付宝小程序 | 上传图片组件(添加默认样式以及自定义上传样式)

    使用my.uploadFile. my.chooseImage 的方式实现图片上传 注意: 使用该方式上传文件,后端也需要参照官方文档进行修改 https://opendocs.alipay.com/ ...

  8. 微信小程序和支付宝小程序对应的差异

    记录将微信小程序代码挪到支付宝小程序的过程中遇到的一些支付宝小程序和微信小程序的差异,以免每次都去官方文档查. 1.文件后缀名 微信小程序的四个文件后缀为.js..json..wxml..wxss,支 ...

  9. uni-app跨端开发H5、微信小程序、支付宝小程序遇到的坑

    文章目录 微信支付宝小程序通用功能 1.checkbox样式 2.分享功能 支付宝小程序参数 微信小程序参数 其他兼容问题 H5 微信小程序 支付宝小程序 持续更新中... 微信支付宝小程序通用功能 ...

最新文章

  1. 强化学习笔记:Q_learning (Q-table)示例举例
  2. 使用Eclipse和Open Liberty的Java EE 8上的Java 9
  3. Toad for Oracle9.7中导入数据库以后,数据有中文乱码:
  4. C语言fscanf和fprintf函数的用法详解
  5. Python高并发应用场景下四种写入SQLite数据库的速度比较
  6. 数据结构与算法小结——排序(八)
  7. FISCO BCOS(四)——— 在Ubantu上安装python3.8
  8. leetcode刷题日记-846. 一手顺子
  9. Codewar python训练题全记录——持续更新
  10. optisystem中器件的学习(4-Test Sets/Passives Library/Optical Switches)
  11. 大三上学期学期总结及百度实习感受
  12. 【Android实战】json解析+GridView自适应布局+图片加载
  13. 华为手机鸿蒙切换主页,京东APP可一键切换“华为鸿蒙版界面”:简洁多了
  14. 电饭锅鸿蒙系统,有了美的轻食电饭煲,人们更加确定了做饭工具的重要性
  15. 问卷星破除输入框粘贴限制的两种方法
  16. 豆瓣超高评分《扫黑风暴》热评爬取可视化展示
  17. 时下最火的网络视频编码器传输技术
  18. Linux 调用openoffice报错 disconnected unexpectedly
  19. ERP中各种乱码处理
  20. 2022世界燕窝展|上海滋补品展|虫草、海参展谈卖货,还是卖品牌?不再简单。

热门文章

  1. 记录贴: SQL Data Scientist Profiling and Analyzing the Yelp Dataset Coursera Worksheet
  2. TCP/IP协议专栏——ND 详解——网络入门和工程维护必看
  3. 量化金融分析师学习笔记——上篇完结
  4. 插画|曼奇立德《商业运营插画》学员“安利25周年”实战作品
  5. 您正在通过不兼容的虚拟化管理程序运行 VMware Workstation。禁用此虚拟化管理程序后才能开启虚拟机
  6. 【集创赛】arm杯国奖作品推荐--作品介绍!
  7. stata 画图碎片
  8. FlashSystem 9100系支持19TB FCM NVMe和MRAM Cache技术
  9. 数字平原大型科幻场景废墟构建
  10. 地产数字化,寻找新的价值链