小程序 大转盘 抽奖 canvas animation
项目需求运用到大转盘 可设置概率 可直接自定义结果 效果如下

两种方法及结合法
一 通过canvas 实现 但是因为定时器原因 手机端卡顿严重 故而最终使用了方法二 但也是该记录下 学习canvas
二 通过小程序Api animation完成完美解决卡顿问题 更精确定位 有样式缺陷 css无法解决样式 自动分配问题 故结合一二两种方法 出现第三种
三 通过小程序Api animation 做动画旋转 样式用canvas来实现 完美解决各类问题
话不多说踩坑部分 就不展示 直接上第三种方法
创建动画区域 (animation) 动画可参考小程序官方API animationData动画参数 在点击开始的时候填充数据
<view class="wrapper-content" style='margin:0 auto;'>
<view class="canvas-container">
<view animation="{{animationData}}" class="canvas-content" style='margin:0 auto;'>
</view>
</view>
</view>
//CSS
.wrapper-content{
background: #E0CFBC;
border-radius: 50%;
width: 720rpx;
height: 720rpx;
padding: 40rpx;
position: relative;
box-sizing: border-box;
z-index:;
}
.canvas-container {
margin: 0 auto;
position: absolute;
left: 40rpx;
top: 40rpx;
width: 640rpx;
height: 640rpx;
border-radius: 50%;
}
.canvas-content {
overflow: hidden;
box-sizing: content-box;
border: 20rpx solid #CDB193;
position: absolute;
left:;
top:;
z-index:;
display: block;
width: 600rpx;
height: 600rpx;
border-radius: inherit;
background-clip: padding-box;
}
配合CSS3 扇形实现圆盘
html
<!-- 扇形 -->
<view class="canvas-list">
<view class="canvas-item2" wx:for="{{awardsConfig.slicePrizes}}" wx:key="key" style="transform: rotate({{item.item2Deg}});background-color:{{awardsConfig.slicePrizes.length==2?(index%2==0?'#faf5e7':'#f3e2c6'):''}};opacity:{{ awardsConfig.slicePrizes.length==2?item.opacity: awardsConfig.slicePrizes.length==3?item.opacity:''}};width:{{size}}rpx;height:{{size/2-2}}rpx;transform-origin:{{size/2}}rpx {{size/2}}rpx">
<view class="canvas-item2-after" style="transform: rotate({{item.afterDeg}});background-color:{{index%2==0?'#faf5e7':'#f3e2c6'}};opacity:{{ awardsConfig.slicePrizes.length==3?'':item.opacity}};width:{{size/2}}rpx;height:{{size/2}}rpx;transform-origin: {{size/2}}rpx {{size/2}}rpx">
</view>
<view wx:if='{{awardsConfig.slicePrizes.length==3}}' class="canvas-item2-after" style="background-color:{{index%2==0?'#faf5e7':'#f3e2c6'}};width:{{size/2}}rpx;height:{{size/2}}rpx;transform-origin: {{size/2}}rpx {{size/2}}rpx"></view>
</view>
</view>
<!-- 选项内容 -->
<view class="wk-wheel-list">
<view class="wk-wheel-item" data-index="{{index}}" wx:for="{{awardsConfig.slicePrizes}}" wx:key='key'>
<view class="wk-wheel-icontent" style="height:262rpx;overflow:hidden;font-size:{{item.text.length>9?'20':'26'}}rpx;padding-top:5rpx;transform: rotate({{index*turnNum}}turn);transform-origin: 50% {{size/2-2}}rpx">
<view class="canvas-litem-text-name">{{item.text}}</view>
<view class="canvas-litem-text-image">
<image src="{{item.img}}" mode="widthFix" style="width:80rpx;max-height:60rpx;padding:10rpx 0 0;"></image>
<view class="canvas-litem-text-image-num">100</view>
</view>
<view style="font-size:20rpx;">{{item.num}}x1</view>
</view>
</view>
</view>
</view>
CSS
/* //css扇形 */
.canvas-item2 {
position: absolute;
left: 0px;
top:;
width: 620rpx;
height: 328rpx;
color: #e4370e;
font-weight: bold;
transform-origin: 330rpx 330rpx;
overflow: hidden;
} .canvas-item2-after {
position: absolute;
top:;
left:;
width: 330rpx;
height: 330rpx;
transform-origin: 330rpx 330rpx;
opacity:;
} .wk-wheel-list {
position: absolute;
left:;
top:;
width: 100%;
height: 100%;
z-index:;
} .wk-wheel-item {
position: absolute;
left:;
top:;
width: 100%;
height: 100%;
color: #fff;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.6);
} .wk-wheel-icontent {
position: relative;
display: block;
padding-top: 50rpx;
margin: 0 auto;
text-align: center;
transform-origin: 50% 328rpx;
color: #AA8B6B;
}
1.awardsConfig.slicePrizes为奖品列表 因为大转盘是圆的 所以W H 是一样的
2.this.data.windowWidth 是屏幕的宽度 小程序有API 可以获取 用屏幕宽度/750*设置内容宽度rpx = 实际内容宽度的px 值
3.size 是圆盘的宽度
设置点击抽奖按钮 两种方法 一直接在canvas内绘制 二在HTML里面通过定位实现
提供二 HTML 定位实现按钮
<view class="canvas-btn" bindtap="getLottery">
<view>
<view style="font-size:56rpx;color:#fff;padding-bottom:4rpx;">开始</view>
<view style="font-size:20rpx;color:#6F5942;font-weight:600;">点击抽奖</view>
</view>
</view>
css
.canvas-btn {
display: flex;
flex-direction: column;
justify-content: space-around;
position: absolute;
left: 50%;
top: 50%;
margin-left: -110rpx;
margin-top: -110rpx;
z-index:;
width: 220rpx;
height: 220rpx;
border-radius: 50%;
color: #f4e9cc;
border: 10px solid #cdb193;
text-align: center;
font-size: 40rpx;
text-decoration: none;
box-sizing: border-box;
}
.canvas-btn>view {
position: absolute;
top: 7%;
left: 7%;
width: 86%;
height: 86%;
border-radius: 50%;
box-sizing: border-box;
padding: 22rpx 20rpx 0;
background: linear-gradient(134deg, rgba(232, 219, 197, 1) 0%, rgba(205, 177, 147, 1) 100%);
/* box-shadow:0px 5px 7px 0px rgba(255,255,255,1); */
margin: auto;
z-index:;
}
.canvas-btn::after {
position: absolute;
display: block;
content: ' ';
left: 39%;
top: -78%;
width:;
height:;
overflow: hidden;
border-width: 80rpx 20rpx 80rpx 20rpx;
border-style: solid;
border-color: transparent;
border-bottom-color: #ffab52;
}
js
getLottery() {
let that = this;
// 获取奖品配置
let awardsConfig = that.data.awardsConfig,
runNum = 12, len = awardsConfig.slicePrizes.length,
awardIndex = 0;
awardIndex = parseInt(Math.random() * 6)
console.log("奖品序号:" + awardIndex);
// 旋转抽奖
app.runDegs = app.runDegs || 0
app.runDegs = app.runDegs + (360 - app.runDegs % 360) + (360 * runNum - awardIndex * (360 / len))
//创建动画
let animationRun = wx.createAnimation({
duration: 4000,
timingFunction: 'ease'
})
console.log(awardsConfig.slicePrizes[awardIndex]);
that.animationRun = animationRun
animationRun.rotate(app.runDegs - (360 / len * 2 + (360 / len)) ).step()
that.setData({
animationData: animationRun.export()
})
},
点击按钮触发getLottery 进行动画数据填充 实现旋转效果 runNum为旋转的圈数 awardIndex为中奖的序号
整体如此完美实现献上整体代码
html
<view class="wrapper-content" style='margin:0 auto;'>
<view class="canvas-container-quiu" wx:for="{{list}}" style="-webkit-transform: rotate({{index * (360/list.length)}}deg);transform: rotate({{index * (360/list.length)}}deg);{{index%2==0?'background:#F2E86D':'background:#ffffff'}}"></view>
<view class="canvas-container">
<view animation="{{animationData}}" class="canvas-content" style='margin:0 auto;'>
<canvas class="canvas-line" disable-scroll="true" bindtouchstart="canvasTouchStart" bindtouchmove="touchMove" bindtouchend="canvasTouchEnd" canvas-id="canvas"></canvas>
</view>
<view class="canvas-btn" bindtap="getLottery">
<view>
<view style="font-size:56rpx;color:#fff;padding-bottom:4rpx;">开始</view>
<view style="font-size:20rpx;color:#6F5942;font-weight:600;">点击抽奖</view>
</view>
</view>
</view>
</view>
css
.wrapper-content{
background: #E0CFBC;
border-radius: 50%;
width: 720rpx;
height: 720rpx;
padding: 40rpx;
position: relative;
box-sizing: border-box;
z-index:;
}
.canvas-container ul, .canvas-container li {
margin:;
padding:;
list-style: none;
}
.canvas-container {
margin: 0 auto;
position: absolute;
left: 40rpx;
top: 40rpx;
width: 640rpx;
height: 640rpx;
border-radius: 50%;
}
.canvas-container-quiu{
width: 20rpx;
height: 20rpx;
border-radius: 50%;
position: absolute;
left:10rpx;
top: 50%;
margin-top: -8rpx;
-webkit-transform-origin: 330rpx 50%;
transform-origin: 350rpx 50%;
z-index:;
}
.canvas-content {
overflow: hidden;
box-sizing: content-box;
border: 20rpx solid #CDB193;
position: absolute;
left:;
top:;
z-index:;
display: block;
width: 600rpx;
height: 600rpx;
border-radius: inherit;
background-clip: padding-box;
}
.canvas-btn {
display: flex;
flex-direction: column;
justify-content: space-around;
position: absolute;
left: 50%;
top: 50%;
margin-left: -110rpx;
margin-top: -110rpx;
z-index:;
width: 220rpx;
height: 220rpx;
border-radius: 50%;
color: #f4e9cc;
border: 10px solid #cdb193;
text-align: center;
font-size: 40rpx;
text-decoration: none;
box-sizing: border-box;
}
.canvas-btn>view {
position: absolute;
top: 7%;
left: 7%;
width: 86%;
height: 86%;
border-radius: 50%;
box-sizing: border-box;
padding: 22rpx 20rpx 0;
background: linear-gradient(134deg, rgba(232, 219, 197, 1) 0%, rgba(205, 177, 147, 1) 100%);
/* box-shadow:0px 5px 7px 0px rgba(255,255,255,1); */
margin: auto;
z-index:;
}
.canvas-btn::after {
position: absolute;
display: block;
content: ' ';
left: 39%;
top: -78%;
width:;
height:;
overflow: hidden;
border-width: 80rpx 20rpx 80rpx 20rpx;
border-style: solid;
border-color: transparent;
border-bottom-color: #ffab52;
}
js
var app = getApp()
var utils = require('../../utils/utils.js');
var Animation = require('../../utils/Animation.js');
var Wheel = require('../../utils/Wheel.js');
Page({ /**
* 页面的初始数据
*/
data: {
awardsList: {},
list: [],
statusBarHeight: getApp().globalData.statusBarHeight,
scrollHeight: 200,
windowWidth:0,
windowHeight:0,
awardsConfig: {
count: 50,
slicePrizes: [
{ text: "恭喜中大奖", img: "/assets/coupon_gold.png", title: "积分券x1", num: "1200", x: "1" },
{ text: "医疗服务费", img: "/assets/coupon_gold.png", title: "积分券x1", num: "50", x: "2" },
{ text: "健康保养费", img: "/assets/coupon_gold.png", title: "积分券x1", num: "500", x: "1" },
{ text: "谢谢参与", img: "/assets/coupon_gold.png", title: "积分券x3", num: "0", x: "2" },
{ text: "青春补偿费", img: "/assets/coupon_gold.png", title: "积分券x1", num: "200", x: "1" },
{ text: "感恩奉献费", img: "/assets/coupon_gold.png", title: "积分券x1", num: "100", x: "2" },
{ text: "咨询售后费", img: "/assets/coupon_gold.png", title: "积分券x1", num: "150", x: "1" },
{ text: "谢谢参与", img: "/assets/coupon_gold.png", title: "积分券x1", num: "0", x: "1" }, { text: "咨询售后费", img: "/assets/coupon_gold.png", title: "积分券x1", num: "150", x: "1" },
{ text: "谢谢参与", img: "/assets/coupon_gold.png", title: "积分券x1", num: "0", x: "1" }
],
},
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
var that = this;
that.initAdards()
wx.getSystemInfo({
success: function (res) {
that.setData({
windowWidth: res.windowWidth,
windowHeight: res.windowHeight,
scrollHeight: res.windowHeight - res.windowWidth / 750 * (getApp().globalData.statusBarHeight * 2 + 98)
});
},
})
},
onReady: function(e) {
let that = this,
fps = 60, awardsConfig = that.data.awardsConfig,
w = this.data.windowWidth / 750 * 600,
h = this.data.windowWidth / 750 * 600,
; wx.getSystemInfo({
success: function(res) {
that.setData({
contentHeight: res.windowHeight
});
},
})
that.setData({
count: awardsConfig.count
})
let len = awardsConfig.slicePrizes.length,
rotateDeg = 360 / len / 2 ,
list = [],
turnNum = 1 / len;
for (var i = 0; i < len; i++) {
list.push({
award: awardsConfig.slicePrizes[i].text,
});
};
that.setData({
list: list.concat(list)
});
},
//初始化奖品数据 计算角度
initAdards() {
var that = this,
awardsConfig = that.data.awardsConfig;
var t = awardsConfig.slicePrizes.length; // 选项长度
var e = 1 / t,
i = 360 / t,
r = i - 90; for (var g = 0; g < t; g++) {
awardsConfig.slicePrizes[g].item2Deg = g * i + 90 - i / 2 + "deg"; //当前下标 * 360/长度 + 90 - 360/长度/2
awardsConfig.slicePrizes[g].afterDeg = r + "deg";
awardsConfig.slicePrizes[g].opacity = '1';
}
that.setData({
turnNum: e, // 页面的单位是turn
awardsConfig: awardsConfig,
})
},
/**
* 抽奖处理函数:
*/
getLottery: function () {
let that = this;
// 获取奖品配置
let awardsConfig = that.data.awardsConfig,
runNum = 12,
len = awardsConfig.slicePrizes.length,
awardIndex = 0;
awardIndex = parseInt(Math.random() * 6)
console.log("奖品序号:" + awardIndex);
// 旋转抽奖
app.runDegs = app.runDegs || 0
app.runDegs = app.runDegs + (360 - app.runDegs % 360) + (360 * runNum - awardIndex * (360 / len))
//创建动画
let animationRun = wx.createAnimation({
duration: 4000,
timingFunction: 'ease'
})
console.log(awardsConfig.slicePrizes[awardIndex]);
that.animationRun = animationRun
animationRun.rotate(app.runDegs).step()
that.setData({
animationData: animationRun.export()
})
},
})
![]()
小程序 大转盘 抽奖 canvas animation的更多相关文章
- 微信小程序,转盘抽奖
微信小程序大转盘 代码源码:https://github.com/yewook/Lottery-turntable
- 纯CSS3大转盘抽奖(响应式、可配置)
源于前段时候微信小程序最初火爆公测时段,把以前用 Canvas 实现的大转盘抽奖移植成微信小程序,无奈当时小程序对 Canvas 支持不够完善,只好降低用 CSS3 实现.虽然比不上 Canvas 绘 ...
- jquery——九宫格大转盘抽奖
一.用到的图片 二.代码如下,重点是js部分 <!DOCTYPE html> <html> <head> <meta http-equiv="Con ...
- PHP实现大转盘抽奖算法实例
本文主要向大家介绍了PHP语言实现大转盘抽奖算法,通过具体的实例向大家展示,希望对大家学习PHP抽奖有所帮助. 流程:1.拼装奖项数组,2.计算概率,3.返回中奖情况 代码如下:中奖概率 ' v ' ...
- PHP+AJAX开发幸运大转盘抽奖
PHP+AJAX开发幸运大转盘抽奖,通过奖品库存.中奖次数来计算中奖概率 奖品设置 $prizes = array( 0 => array( "id" => 0, // ...
- Java 实现大转盘抽奖
需要用到 JAVA中的Random()函数 注意:大转盘抽奖各奖项中奖概率之和为 1.奖品列表中的概率为累加概率,需要按照添加进列表的顺序进行累加,添加顺序不做要求. 实际中使用需要考虑奖品数量限制等 ...
- 转盘抽奖 canvas & 抽奖 H5 源码
转盘抽奖 canvas https://github.com/givebest/wechat-turntalbe-canvas https://blog.givebest.cn/GB-canvas-t ...
- C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断
C#保留2位小数几种场景总结 场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.2 ...
- 【Vue.js游戏机实战】- Vue.js实现大转盘抽奖总结
大家好!先上图看看本次案例的整体效果. 实现思路: Vue component实现大转盘组件,可以嵌套到任意要使用的页面. css3 transform控制大转盘抽奖过程的动画效果. 抽奖组件内使用钩 ...
随机推荐
- 二、YARN
一.YARN 介绍 yarn 是下一代 MapReduce,即 MRv2,是在第一代 MapReduce 基础上演变而来的,主要是为了解决原始 Hadoop 扩展性较差,不支持多计算框架而提出的,通俗 ...
- Spark Streaming 整合 Flume
Spark Streaming 整合 Flume 一.简介二.推送式方法 2.1 配置日志收集Flume 2.2 项目依赖 2.3 Spark Strea ...
- vue中事件代理
由于在vue实例内部,this指向了实例本身,所以在编写事件代理的时候,用e.currentTarget引用绑定事件代理的元素,e.target引用事件目标元素.刚刚不注意想用this引用代理元素报错 ...
- 3.6 Go String型
1. Go String型 Unicode是一种字符集,code point UTF8是unicode的存储实现,转换为字节序列的规则 go的rune类型 可以取出字符串里的unicode 字符串是一 ...
- Django之ORM执行原生sql语句
django中的ORM提供的操作功能有限,在模型提供的查询API不能满足实际工作需要时,可以在ORM中直接执行原生sql语句. Django 提供两种方法使用原生SQL进行查询:一种是使用raw()方 ...
- poj1679最小生成树是否唯一
http://www.cnblogs.com/kuangbin/p/3147329.html #include<cstdio> #include<cstring> #inclu ...
- pyinstaller打包pyqt5,从入坑到填坑,详解
以上省略pyinstaller安装步骤,直入主题.先分享我的心路历程. 1.pyinstaller -F -i 1.ico UI_Main.py (先在CMD中 cd到 py文件对应的路径) 第一步打 ...
- Maven快速入门(二)手动创建maven项目hellomaven
之前讲过Maven介绍及环境搭建,介绍了maven的作用和如何搭建maven环境.接下来就以一个helloworld的例子来说一说如何创建maven项目以及maven项目的项目结构,最后讲maven如 ...
- eatwhatApp开发实战(十四)
之前我们就输入框EditText做了优化,而这次,我们为app添加拨打电话的功能. 首先是布局,将activity_shop_info.xml中对应的电话那一栏进行重新设计: <Relative ...
- [计划任务 - dos]制作任务工具
语法 schtasks /create /tn TaskName /tr TaskRun /sc schedule [/mo modifier] [/d day] [/m month[,month.. ...
