项目需求运用到大转盘 可设置概率 可直接自定义结果 效果如下

两种方法及结合法

一 通过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的更多相关文章

  1. 微信小程序,转盘抽奖

    微信小程序大转盘 代码源码:https://github.com/yewook/Lottery-turntable

  2. 纯CSS3大转盘抽奖(响应式、可配置)

    源于前段时候微信小程序最初火爆公测时段,把以前用 Canvas 实现的大转盘抽奖移植成微信小程序,无奈当时小程序对 Canvas 支持不够完善,只好降低用 CSS3 实现.虽然比不上 Canvas 绘 ...

  3. jquery——九宫格大转盘抽奖

    一.用到的图片 二.代码如下,重点是js部分 <!DOCTYPE html> <html> <head> <meta http-equiv="Con ...

  4. PHP实现大转盘抽奖算法实例

    本文主要向大家介绍了PHP语言实现大转盘抽奖算法,通过具体的实例向大家展示,希望对大家学习PHP抽奖有所帮助. 流程:1.拼装奖项数组,2.计算概率,3.返回中奖情况 代码如下:中奖概率 ' v ' ...

  5. PHP+AJAX开发幸运大转盘抽奖

    PHP+AJAX开发幸运大转盘抽奖,通过奖品库存.中奖次数来计算中奖概率 奖品设置 $prizes = array( 0 => array( "id" => 0, // ...

  6. Java 实现大转盘抽奖

    需要用到 JAVA中的Random()函数 注意:大转盘抽奖各奖项中奖概率之和为 1.奖品列表中的概率为累加概率,需要按照添加进列表的顺序进行累加,添加顺序不做要求. 实际中使用需要考虑奖品数量限制等 ...

  7. 转盘抽奖 canvas & 抽奖 H5 源码

    转盘抽奖 canvas https://github.com/givebest/wechat-turntalbe-canvas https://blog.givebest.cn/GB-canvas-t ...

  8. C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断

    C#保留2位小数几种场景总结   场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.2 ...

  9. 【Vue.js游戏机实战】- Vue.js实现大转盘抽奖总结

    大家好!先上图看看本次案例的整体效果. 实现思路: Vue component实现大转盘组件,可以嵌套到任意要使用的页面. css3 transform控制大转盘抽奖过程的动画效果. 抽奖组件内使用钩 ...

随机推荐

  1. python中minepy包的下载

    minepy包的下载 今天在做机器学习的时候,需要使用到互信息的有关内容,而python包下正好有处理互信息的包,想直接下一个,没想到遇到了不少问题: 基本指令很简单了: pip install mi ...

  2. SpringBoot2.x整合quartz实现多任务定时执行

    一.pom文件中导入相关依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifa ...

  3. removebg抠图小工具

    由于比较简单,直接上代码(removebg接口官网),更多小工具获取 (1)官网API,需注册获取X-Api-Key:removebg_官网api.py import requests respons ...

  4. postman发送请求携带Cookie

    相关步骤: 1.下载 Postman-Interceptor_v0.2.24.zip插件 2.解压下载好的插件,将其拖到应用配置中 3.复制Postman-Interceptor_v中的id地址 4. ...

  5. 服务治理:Spring Cloud Eureka

    Spring Cloud Eureka主要负责完成微服务架构中服务治理功能. 服务治理是微服务架构中最为核心和基础模块,主要用来实现各个微服务实例的自动注册和发现. 服务注册 微服务实例启动后向注册中 ...

  6. Android Studio代码编译通过但是提示停止运行

    这种问题也许有很多可能,但是我遇到过一种,下面分享给大家希望问题会得到解决 检查你的布局文件中图片的位置 如果图片名前有“(v24)”的删掉 重新插入图片到这个目录 然后就可以正常运行了

  7. GO 使用Webhook 实现github 自动化部署

    通常大家开发大部分是本地git push 提交,服务器上git pull 手动更新.git 可以使用webhook实现自动部署.webhook是仓库平台的一个钩子事件,通过hook 钩子监听代码,回调 ...

  8. IO字节流与字符流的操作

    字节流:        FileInputStream读取,FileOutputStream输出 字节流使用数组缓冲区复制文件,最后得出所使用的时间 public class work2 { publ ...

  9. 2020由浅入深最强Java面试题

    1.String,StringBuffer和StringBuilder有什么区别?     String是字符串常量,不可变对象,每次对String修改都等同于生成了一个新的String象,然后将指针 ...

  10. linux高级管理第十二章--rsync

    实验部分 1.安装rsync 2.配置文件 3.配置密码 4.后续 5.为了测试,创建几个文件 配置实时同步 1.调整inotify内核参数 安装inotify-tools 测试同步 编写脚本 验证 ...