├── src ├── app.less ├── pages │ ├── index │ │ ├── index.less │ │ └── index.jsx │ └── bigWheel │ │ ├── bigWheel.less │ │ └── bigWheel.js ├── static │ ├── GIF.gif │ ├── show1.png │ ├── icon-close.png │ ├── wheelBg@3x.jpg │ ├── wheelCircle@3x.png │ ├── wheelRuleBg@3x.png │ ├── wheelStart@3x.png │ ├── wheelTitle@3x.png │ ├── wheelModalFail@3x.png │ └── wheelModalSuccess@3x.png ├── app.jsx └── index.html ├── .gitignore ├── config ├── dev.js ├── prod.js └── index.js ├── project.config.json ├── README.md └── package.json /src/app.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/index/index.less: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | yarn.lock 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /src/static/GIF.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/GIF.gif -------------------------------------------------------------------------------- /src/static/show1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/show1.png -------------------------------------------------------------------------------- /src/static/icon-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/icon-close.png -------------------------------------------------------------------------------- /src/static/wheelBg@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/wheelBg@3x.jpg -------------------------------------------------------------------------------- /src/static/wheelCircle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/wheelCircle@3x.png -------------------------------------------------------------------------------- /src/static/wheelRuleBg@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/wheelRuleBg@3x.png -------------------------------------------------------------------------------- /src/static/wheelStart@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/wheelStart@3x.png -------------------------------------------------------------------------------- /src/static/wheelTitle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/wheelTitle@3x.png -------------------------------------------------------------------------------- /src/static/wheelModalFail@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/wheelModalFail@3x.png -------------------------------------------------------------------------------- /src/static/wheelModalSuccess@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rachel-lj/taro-bigWheel/HEAD/src/static/wheelModalSuccess@3x.png -------------------------------------------------------------------------------- /config/dev.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | NODE_ENV: '"development"' 4 | }, 5 | defineConstants: { 6 | }, 7 | weapp: {}, 8 | h5: {} 9 | } 10 | -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "miniprogramRoot": "./dist", 3 | "projectname": "bigWheel", 4 | "description": "", 5 | "appid": "touristappid", 6 | "setting": { 7 | "urlCheck": true, 8 | "es6": false, 9 | "postcss": false, 10 | "minified": false 11 | }, 12 | "compileType": "miniprogram" 13 | } 14 | -------------------------------------------------------------------------------- /config/prod.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | NODE_ENV: '"production"' 4 | }, 5 | defineConstants: { 6 | }, 7 | weapp: {}, 8 | h5: { 9 | /** 10 | * 如果h5端编译后体积过大,可以使用webpack-bundle-analyzer插件对打包体积进行分析。 11 | * 参考代码如下: 12 | * webpackChain (chain) { 13 | * chain.plugin('analyzer') 14 | * .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, []) 15 | * } 16 | */ 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # taro-bigWheel 2 | 3 | 基于 taro 纯css3写的大转盘抽奖营销组件 适用于小程序 4 | 5 | 奖项是一个 mock 的数组,可以对接接口,活动详情部分可以自由配置,简单好用。 6 | 7 | ![GIF](./src/static/GIF.gif) 8 | 9 | ![](./src/static/show1.png) 10 | 11 | ### Build Setup 12 | 13 | ``` 14 | # 克隆到本地 15 | git clone git@github.com:Lin-jing/taro-bigWheel.git 16 | 17 | # 进入文件夹 18 | cd taro-bigWheel 19 | 20 | # 安装依赖 21 | npm install 22 | 23 | # 编译项目生成dist文件 24 | npm run dev:weapp 25 | 26 | # 然后打开微信开发者工具添加dist文件可以看到效果 27 | ``` 28 | 29 | 对你有帮助的话,请 star 一下 30 | -------------------------------------------------------------------------------- /src/pages/index/index.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from '@tarojs/taro' 2 | import { View, Text } from '@tarojs/components' 3 | import './index.less' 4 | 5 | export default class Index extends Component { 6 | 7 | config = { 8 | navigationBarTitleText: '首页' 9 | } 10 | 11 | componentWillMount () { } 12 | 13 | componentDidMount () { } 14 | 15 | componentWillUnmount () { } 16 | 17 | componentDidShow () { } 18 | 19 | componentDidHide () { } 20 | 21 | render () { 22 | return ( 23 | 24 | Hello world! 25 | 26 | ) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app.jsx: -------------------------------------------------------------------------------- 1 | import Taro, { Component } from '@tarojs/taro'; 2 | import Index from './pages/bigWheel/bigWheel'; 3 | 4 | import './app.less'; 5 | 6 | // 如果需要在 h5 环境中开启 React Devtools 7 | // 取消以下注释: 8 | // if (process.env.NODE_ENV !== 'production' && process.env.TARO_ENV === 'h5') { 9 | // require('nerv-devtools') 10 | // } 11 | 12 | class App extends Component { 13 | config = { 14 | pages: ['pages/bigWheel/bigWheel'], 15 | window: { 16 | backgroundTextStyle: 'light', 17 | navigationBarBackgroundColor: '#fff', 18 | navigationBarTitleText: 'WeChat', 19 | navigationBarTextStyle: 'black' 20 | } 21 | }; 22 | 23 | componentDidMount() {} 24 | 25 | componentDidShow() {} 26 | 27 | componentDidHide() {} 28 | 29 | componentDidCatchError() {} 30 | 31 | // 在 App 类中的 render() 函数没有实际作用 32 | // 请勿修改此函数 33 | render() { 34 | return ; 35 | } 36 | } 37 | 38 | Taro.render(, document.getElementById('app')); 39 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bigWheel", 3 | "version": "1.0.0", 4 | "private": true, 5 | "description": "", 6 | "templateInfo": { 7 | "name": "default", 8 | "typescript": false, 9 | "css": "less" 10 | }, 11 | "scripts": { 12 | "build:weapp": "taro build --type weapp", 13 | "build:swan": "taro build --type swan", 14 | "build:alipay": "taro build --type alipay", 15 | "build:tt": "taro build --type tt", 16 | "build:h5": "taro build --type h5", 17 | "build:rn": "taro build --type rn", 18 | "build:qq": "taro build --type qq", 19 | "build:quickapp": "taro build --type quickapp", 20 | "dev:weapp": "npm run build:weapp -- --watch", 21 | "dev:swan": "npm run build:swan -- --watch", 22 | "dev:alipay": "npm run build:alipay -- --watch", 23 | "dev:tt": "npm run build:tt -- --watch", 24 | "dev:h5": "npm run build:h5 -- --watch", 25 | "dev:rn": "npm run build:rn -- --watch", 26 | "dev:qq": "npm run build:qq -- --watch", 27 | "dev:quickapp": "npm run build:quickapp -- --watch" 28 | }, 29 | "author": "", 30 | "license": "MIT", 31 | "dependencies": { 32 | "@tarojs/components": "1.3.14", 33 | "@tarojs/router": "1.3.14", 34 | "@tarojs/taro": "1.3.14", 35 | "@tarojs/taro-alipay": "1.3.14", 36 | "@tarojs/taro-h5": "1.3.14", 37 | "@tarojs/taro-qq": "1.3.14", 38 | "@tarojs/taro-quickapp": "1.3.14", 39 | "@tarojs/taro-swan": "1.3.14", 40 | "@tarojs/taro-tt": "1.3.14", 41 | "@tarojs/taro-weapp": "^1.3.20", 42 | "classnames": "^2.2.6", 43 | "nerv-devtools": "^1.4.0", 44 | "nervjs": "^1.4.0" 45 | }, 46 | "devDependencies": { 47 | "@tarojs/plugin-babel": "1.3.14", 48 | "@tarojs/plugin-csso": "1.3.14", 49 | "@tarojs/plugin-less": "1.3.14", 50 | "@tarojs/plugin-uglifyjs": "1.3.14", 51 | "@tarojs/webpack-runner": "1.3.14", 52 | "@types/react": "^16.4.6", 53 | "@types/webpack-env": "^1.13.6", 54 | "babel-eslint": "^8.2.3", 55 | "babel-plugin-transform-class-properties": "^6.24.1", 56 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 57 | "babel-plugin-transform-jsx-stylesheet": "^0.6.5", 58 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 59 | "babel-preset-env": "^1.6.1", 60 | "eslint": "^5.16.0", 61 | "eslint-config-taro": "1.3.14", 62 | "eslint-plugin-import": "^2.12.0", 63 | "eslint-plugin-react": "^7.8.2", 64 | "eslint-plugin-react-hooks": "^1.6.1", 65 | "eslint-plugin-taro": "1.3.14", 66 | "stylelint": "9.3.0", 67 | "stylelint-config-taro-rn": "1.3.14", 68 | "stylelint-taro-rn": "1.3.14" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | projectName: 'bigWheel', 3 | date: '2019-10-16', 4 | designWidth: 750, 5 | deviceRatio: { 6 | '640': 2.34 / 2, 7 | '750': 1, 8 | '828': 1.81 / 2 9 | }, 10 | sourceRoot: 'src', 11 | outputRoot: 'dist', 12 | plugins: { 13 | babel: { 14 | sourceMap: true, 15 | presets: [ 16 | ['env', { 17 | modules: false 18 | }] 19 | ], 20 | plugins: [ 21 | 'transform-decorators-legacy', 22 | 'transform-class-properties', 23 | 'transform-object-rest-spread' 24 | ] 25 | } 26 | }, 27 | defineConstants: { 28 | }, 29 | copy: { 30 | patterns: [ 31 | ], 32 | options: { 33 | } 34 | }, 35 | weapp: { 36 | module: { 37 | postcss: { 38 | autoprefixer: { 39 | enable: true, 40 | config: { 41 | browsers: [ 42 | 'last 3 versions', 43 | 'Android >= 4.1', 44 | 'ios >= 8' 45 | ] 46 | } 47 | }, 48 | pxtransform: { 49 | enable: true, 50 | config: { 51 | 52 | } 53 | }, 54 | url: { 55 | enable: true, 56 | config: { 57 | limit: 10240 // 设定转换尺寸上限 58 | } 59 | }, 60 | cssModules: { 61 | enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true 62 | config: { 63 | namingPattern: 'module', // 转换模式,取值为 global/module 64 | generateScopedName: '[name]__[local]___[hash:base64:5]' 65 | } 66 | } 67 | } 68 | } 69 | }, 70 | h5: { 71 | publicPath: '/', 72 | staticDirectory: 'static', 73 | module: { 74 | postcss: { 75 | autoprefixer: { 76 | enable: true, 77 | config: { 78 | browsers: [ 79 | 'last 3 versions', 80 | 'Android >= 4.1', 81 | 'ios >= 8' 82 | ] 83 | } 84 | }, 85 | cssModules: { 86 | enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true 87 | config: { 88 | namingPattern: 'module', // 转换模式,取值为 global/module 89 | generateScopedName: '[name]__[local]___[hash:base64:5]' 90 | } 91 | } 92 | } 93 | } 94 | } 95 | } 96 | 97 | module.exports = function (merge) { 98 | if (process.env.NODE_ENV === 'development') { 99 | return merge({}, config, require('./dev')) 100 | } 101 | return merge({}, config, require('./prod')) 102 | } 103 | -------------------------------------------------------------------------------- /src/pages/bigWheel/bigWheel.less: -------------------------------------------------------------------------------- 1 | page { 2 | width: 100%; 3 | height: 100%; 4 | } 5 | 6 | .container { 7 | z-index: 1; 8 | height: 100%; 9 | } 10 | .iconWheelBg { 11 | width: 750px; 12 | height: 1750px; 13 | z-index: -1; 14 | position: absolute; 15 | } 16 | .history { 17 | width: 750px; 18 | height: 35px; 19 | font-size: 32px; 20 | font-family: PingFang SC; 21 | font-weight: 500; 22 | text-decoration: underline; 23 | color: rgba(255, 255, 255, 1); 24 | line-height: 35px; 25 | text-decoration: underline; 26 | position: absolute; 27 | text-align: right; 28 | top: 30px; 29 | right: 20px; 30 | } 31 | .title { 32 | width: 750px; 33 | height: 80px; 34 | font-size: 70px; 35 | font-family: PingFang SC; 36 | font-weight: bold; 37 | color: rgba(255, 255, 255, 1); 38 | line-height: 80px; 39 | text-align: center; 40 | letter-spacing: 8px; 41 | position: absolute; 42 | white-space: nowrap; 43 | text-overflow: ellipsis; 44 | overflow: hidden; 45 | top: 95px; 46 | } 47 | .rollNum { 48 | width: 750px; 49 | height: 30px; 50 | font-size: 29px; 51 | font-family: PingFang SC; 52 | font-weight: 100; 53 | color: rgba(255, 255, 255, 1); 54 | line-height: 30px; 55 | text-align: center; 56 | letter-spacing: 4px; 57 | position: absolute; 58 | top: 190px; 59 | } 60 | .plate-wrap-box { 61 | position: relative; 62 | z-index: 999; 63 | width: 750px; 64 | height: 678px; 65 | border-radius: 50%; 66 | top: 325px; 67 | text-align: center; 68 | display: flex; 69 | justify-content: center; 70 | } 71 | .iconWheelCircle { 72 | width: 678px; 73 | height: 678px; 74 | z-index: 9; 75 | position: relative; 76 | border-radius: 50%; 77 | } 78 | .plate-border { 79 | width: 678px; 80 | height: 678px; 81 | position: relative; 82 | display: flex; 83 | justify-content: center; 84 | } 85 | 86 | .plate-wrap { 87 | position: absolute; 88 | left: 50%; 89 | top: 50%; 90 | transform: translate(-50%, -50%); 91 | z-index: 9; 92 | width: 440px; 93 | height: 440px; 94 | border: 5px solid #f8ea6e; 95 | border-radius: 50%; 96 | overflow: hidden; 97 | margin: auto; 98 | } 99 | 100 | .plate-light { 101 | z-index: 1; 102 | width: 500px; 103 | height: 500px; 104 | border: none; 105 | } 106 | 107 | .plate-box { 108 | position: absolute; 109 | z-index: 1; 110 | left: 50%; 111 | width: 0; 112 | height: 0; 113 | font-size: 24px; 114 | } 115 | 116 | .bulb { 117 | position: absolute; 118 | width: 16px; 119 | height: 16px; 120 | left: 50%; 121 | top: -242px; 122 | transform: translate(-50%, 0); 123 | border-radius: 50%; 124 | background-color: #fff0c7; 125 | filter: blur(0.5px); 126 | } 127 | 128 | .text-box { 129 | position: absolute; 130 | text-align: center; 131 | display: inline-block; 132 | width: 140px; 133 | word-break: break-all; 134 | top: -200px; 135 | transform: translate(-100%, 0); 136 | font-size: 19px; 137 | font-family: Source Han Sans CN; 138 | font-weight: 500; 139 | left: 70px; 140 | } 141 | 142 | .plate-btn-wrap { 143 | position: absolute; 144 | z-index: 10; 145 | left: 50%; 146 | top: 50%; 147 | transform: translate(-50%, -50%); 148 | width: 126px; 149 | height: 149px; 150 | border-radius: 50%; 151 | } 152 | .iconWheelStart { 153 | width: 126px; 154 | height: 149px; 155 | position: relative; 156 | z-index: 11; 157 | border-radius: 50%; 158 | display: flex; 159 | justify-content: center; 160 | align-items: center; 161 | } 162 | .detial-wrap { 163 | position: absolute; 164 | z-index: 10; 165 | left: 50%; 166 | top: 950px; 167 | transform: translate(-50%, -50%); 168 | width: 750px; 169 | height: 630px; 170 | border-radius: 50%; 171 | } 172 | .iconWheelTitle { 173 | width: 400px; 174 | height: 110px; 175 | top: 75px; 176 | position: relative; 177 | } 178 | .detail-text { 179 | width: 250px; 180 | height: 95px; 181 | font-size: 45px; 182 | font-family: Source Han Sans CN; 183 | font-weight: 800; 184 | color: #a13d01; 185 | line-height: 80px; 186 | position: absolute; 187 | top: 80px; 188 | left: 255px; 189 | text-align: center; 190 | letter-spacing: 5px; 191 | } 192 | .iconWheelRuleBg { 193 | width: 600px; 194 | height: 600px; 195 | } 196 | .rule-detail { 197 | width: 520px; 198 | height: 480px; 199 | font-size: 28px; 200 | font-family: Source Han Sans CN; 201 | font-weight: 550; 202 | color: #f52c32; 203 | overflow: hidden; 204 | position: absolute; 205 | top: 200px; 206 | left: 120px; 207 | text-align: start; 208 | } 209 | // 中奖提示弹窗 210 | .wheel-modal { 211 | width: 100vw; 212 | height: 85vh; 213 | position: fixed; 214 | top: 0; 215 | left: 0; 216 | z-index: 999; 217 | } 218 | .wheel-modal-mask { 219 | width: 100vw; 220 | height: 100vh; 221 | position: absolute; 222 | top: 0; 223 | left: 0; 224 | z-index: 0; 225 | background-color: rgba(0, 0, 0, 0.5); 226 | } 227 | .wheel-modal-content { 228 | width: 750px; 229 | height: 450px; 230 | position: absolute; 231 | top: 0; 232 | left: 0; 233 | bottom: 0; 234 | right: 0; 235 | margin: auto; 236 | } 237 | .modal-img { 238 | width: 705px; 239 | height: 520px; 240 | position: absolute; 241 | top: 0; 242 | left: 0; 243 | bottom: 0; 244 | right: 0; 245 | margin: auto; 246 | } 247 | .modal-text { 248 | height: 60px; 249 | line-height: 60px; 250 | width: 100%; 251 | text-align: center; 252 | position: absolute; 253 | top: 265px; 254 | font-size: 32px; 255 | font-family: PingFang SC; 256 | font-weight: 500; 257 | color: rgba(255, 255, 255, 1); 258 | } 259 | .modal-btnGroup { 260 | width: 750px; 261 | height: 80px; 262 | display: flex; 263 | justify-content: center; 264 | position: absolute; 265 | top: 355px; 266 | } 267 | .modal-btn-giveUp { 268 | width: 224px; 269 | height: 80px; 270 | background: rgba(255, 255, 255, 1); 271 | border-radius: 40px; 272 | text-align: center; 273 | line-height: 80px; 274 | font-size: 32px; 275 | font-family: PingFang SC; 276 | font-weight: 500; 277 | color: rgba(51, 51, 51, 1); 278 | margin-right: 10px; 279 | } 280 | .modal-btn-get-short { 281 | width: 224px; 282 | height: 80px; 283 | background: rgba(248, 228, 55, 1); 284 | border-radius: 40px; 285 | text-align: center; 286 | line-height: 80px; 287 | font-size: 32px; 288 | font-family: PingFang SC; 289 | font-weight: 500; 290 | color: rgba(243, 59, 61, 1); 291 | margin-left: 10px; 292 | } 293 | .modal-btn-get-long { 294 | width: 290px; 295 | height: 80px; 296 | background: rgba(248, 228, 55, 1); 297 | border-radius: 40px; 298 | text-align: center; 299 | line-height: 80px; 300 | font-size: 32px; 301 | font-family: PingFang SC; 302 | font-weight: 500; 303 | color: rgba(243, 59, 61, 1); 304 | margin-left: 10px; 305 | } 306 | .modal-btn-continue { 307 | width: 224px; 308 | height: 80px; 309 | background: rgba(255, 255, 255, 1); 310 | border-radius: 40px; 311 | text-align: center; 312 | line-height: 80px; 313 | font-size: 32px; 314 | font-family: PingFang SC; 315 | font-weight: 500; 316 | color: rgba(243, 59, 61, 1); 317 | } 318 | // 中奖纪录弹窗 319 | .history-modal { 320 | width: 100vw; 321 | height: 100vh; 322 | position: fixed; 323 | top: 0; 324 | left: 0; 325 | z-index: 999; 326 | } 327 | .history-modal-mask { 328 | width: 100vw; 329 | height: 100vh; 330 | position: absolute; 331 | top: 0; 332 | left: 0; 333 | z-index: 0; 334 | background-color: rgba(0, 0, 0, 0.5); 335 | } 336 | .history-modal-content { 337 | width: 635px; 338 | height: 500px; 339 | position: absolute; 340 | background: rgba(255, 255, 255, 1); 341 | border-radius: 20px; 342 | top: 0; 343 | left: 0; 344 | bottom: 0; 345 | right: 0; 346 | margin: auto; 347 | } 348 | .iconWheelModalClose { 349 | width: 64px; 350 | height: 64px; 351 | position: absolute; 352 | top: -100px; 353 | right: 0; 354 | } 355 | .history-modal-header { 356 | width: 635px; 357 | height: 100px; 358 | background: rgba(255, 79, 95, 1); 359 | border-radius: 20px 20px 0px 0px; 360 | text-align: center; 361 | font-size: 32px; 362 | font-family: PingFang SC; 363 | font-weight: 500; 364 | color: rgba(255, 255, 255, 1); 365 | line-height: 100px; 366 | } 367 | .history-modal-title { 368 | height: 70px; 369 | width: 25%; 370 | line-height: 70px; 371 | text-align: center; 372 | font-size: 24px; 373 | font-family: PingFang SC; 374 | font-weight: 500; 375 | color: rgba(102, 102, 102, 1); 376 | } 377 | .history-modal-table { 378 | width: 635px; 379 | height: 325px; 380 | overflow: auto; 381 | margin-bottom: 1px; 382 | } 383 | .history-modal-table-item { 384 | height: 55px; 385 | width: 25%; 386 | line-height: 55px; 387 | text-align: center; 388 | font-size: 24px; 389 | font-family: PingFang SC; 390 | font-weight: 500; 391 | color: rgba(102, 102, 102, 1); 392 | white-space: nowrap; 393 | text-overflow: ellipsis; 394 | overflow: hidden; 395 | } 396 | -------------------------------------------------------------------------------- /src/pages/bigWheel/bigWheel.js: -------------------------------------------------------------------------------- 1 | import { View, Text, Image } from '@tarojs/components'; 2 | import Taro, { Component } from '@tarojs/taro'; 3 | import './bigWheel.less'; 4 | import classNames from 'classnames'; 5 | import iconWheelBg from '../../static/wheelBg@3x.jpg'; 6 | import iconWheelCircle from '../../static/wheelCircle@3x.png'; 7 | import iconWheelModalFail from '../../static/wheelModalFail@3x.png'; 8 | import iconWheelModalSuccess from '../../static/wheelModalSuccess@3x.png'; 9 | import iconWheelRuleBg from '../../static/wheelRuleBg@3x.png'; 10 | import iconWheelStart from '../../static/wheelStart@3x.png'; 11 | import iconWheelTitle from '../../static/wheelTitle@3x.png'; 12 | import iconWheelModalClose from '../../static/icon-close.png'; 13 | class BigWheel extends Component { 14 | state = { 15 | rollState: false, // 是否正在抽奖 16 | visibleModal: false, //抽奖弹窗 17 | visibleHistoryModal: false, //中奖历史弹窗 18 | canRollNum: 0, // 抽奖次数 19 | prizeType: 0, // 奖品类型 0-优惠券1-积分2-实物 20 | prizeName: null, 21 | isWin: false, //是否中奖 22 | num: 1, //用在动画上,让用户在第二次点击的时候可以接着上次转动的角度继续转 23 | lottery: [ 24 | '一等奖', 25 | '二等奖', 26 | '谢谢参与', 27 | '三等奖', 28 | '二等奖', 29 | '谢谢参与', 30 | '三等奖', 31 | '谢谢参与' 32 | ], //奖品数组 33 | title: '抽奖页面标题', 34 | lotteryArrLen: 8, //放奖品的数组的长度 35 | historyData: [ 36 | { 37 | award: '华为xxxxxxxxxxxxxx', 38 | awardName: '一等奖', 39 | exchangeStatusName: '已领取', 40 | winningTime: '2019-10-16' 41 | }, 42 | { 43 | award: '华为xxxx', 44 | awardName: '一等奖', 45 | exchangeStatusName: '已领取', 46 | winningTime: '2019-10-16' 47 | }, 48 | { 49 | award: '华为xxxx', 50 | awardName: '一等奖', 51 | exchangeStatusName: '已领取', 52 | winningTime: '2019-10-16' 53 | }, 54 | { 55 | award: '华为xxxx', 56 | awardName: '一等奖', 57 | exchangeStatusName: '已领取', 58 | winningTime: '2019-10-16' 59 | }, 60 | { 61 | award: '华为xxxx', 62 | awardName: '一等奖', 63 | exchangeStatusName: '已领取', 64 | winningTime: '2019-10-16' 65 | }, 66 | { 67 | award: '华为xxxx', 68 | awardName: '一等奖', 69 | exchangeStatusName: '已领取', 70 | winningTime: '2019-10-16' 71 | }, 72 | { 73 | award: '华为xxxx', 74 | awardName: '一等奖', 75 | exchangeStatusName: '已领取', 76 | winningTime: '2019-10-16' 77 | }, 78 | { 79 | award: '华为xxxx', 80 | awardName: '一等奖', 81 | exchangeStatusName: '已领取', 82 | winningTime: '2019-10-16' 83 | }, 84 | { 85 | award: '华为xxxx', 86 | awardName: '一等奖', 87 | exchangeStatusName: '已领取', 88 | winningTime: '2019-10-16' 89 | }, 90 | { 91 | award: '华为xxxx', 92 | awardName: '一等奖', 93 | exchangeStatusName: '已领取', 94 | winningTime: '2019-10-16' 95 | }, 96 | { 97 | award: '华为xxxx', 98 | awardName: '一等奖', 99 | exchangeStatusName: '已领取', 100 | winningTime: '2019-10-16' 101 | }, 102 | { 103 | award: '华为xxxx', 104 | awardName: '一等奖', 105 | exchangeStatusName: '已领取', 106 | winningTime: '2019-10-16' 107 | } 108 | ] 109 | }; 110 | config = { 111 | navigationBarTitleText: '大转盘', 112 | navigationBarBackgroundColor: '#ffffff', 113 | navigationBarTextStyle: 'black' 114 | }; 115 | componentWillMount() { 116 | // 掉接口看用户有几次抽奖机会,如果抽奖机会大于等于1就可以抽奖 117 | 118 | this.setState({ 119 | canRollNum: 3 120 | }); 121 | 122 | let aniData = Taro.createAnimation({ 123 | //创建动画对象 124 | duration: 3000, 125 | timingFunction: 'ease' 126 | }); 127 | this.aniData = aniData; //将动画对象赋值给this的aniData属性 128 | } 129 | showModal = () => { 130 | console.log('抽奖结束---显示弹窗'); 131 | }; 132 | closeModal = () => { 133 | this.setState({ 134 | visibleModal: false 135 | }); 136 | }; 137 | showHistoryModal = flag => { 138 | this.setState({ visibleHistoryModal: flag }); 139 | }; 140 | startRollTap = () => { 141 | //开始转盘 142 | const { 143 | lotteryArrLen, 144 | lottery, 145 | canRollNum, 146 | rollState, 147 | visibleModal, 148 | num, 149 | isWin 150 | } = this.state; 151 | if (canRollNum < 1 || rollState || visibleModal) return; 152 | 153 | let aniData = this.aniData; //获取this对象上的动画对象 154 | let rightNum = ~~(Math.random() * lotteryArrLen); //生成随机数 155 | console.log('抽奖次数--', canRollNum); 156 | console.log(`随机数是${rightNum}`); 157 | // 随机次数为2,5,7则未中奖 158 | if (rightNum == 2 || rightNum == 5 || rightNum == 7) { 159 | this.setState({ isWin: false }); 160 | } else { 161 | this.setState({ isWin: true, prizeName: lottery[rightNum] }); 162 | } 163 | console.log(`奖品是:${lottery[rightNum]}`); 164 | aniData.rotate(3600 * num - (360 / lotteryArrLen) * rightNum).step(); //设置转动的圈数 165 | this.setState({ 166 | rollState: true, 167 | aniData: aniData.export() //导出动画队列。export 方法每次调用后会清掉之前的动画操作。 168 | }); 169 | 170 | // 动画停止设置状态 171 | setTimeout(_ => { 172 | this.showModal(); // 当转盘停止显示模态框显示抽奖结果 173 | this.setState({ 174 | visibleModal: true, 175 | canRollNum: canRollNum - 1, // 抽奖次数减一 176 | rollState: false, // 将转盘状态切换为可抽奖 177 | num: num + 1 178 | }); 179 | }, 3000); 180 | }; 181 | 182 | render() { 183 | const { 184 | aniData, 185 | lottery, 186 | canRollNum, 187 | title, 188 | visibleModal, 189 | prizeType, 190 | isWin, 191 | visibleHistoryModal, 192 | historyData, 193 | prizeName 194 | } = this.state; 195 | let winText = `您获得${prizeName}`; 196 | let failText = '很遗憾您没有中奖'; 197 | return ( 198 | 199 | 200 | this.showHistoryModal(true)}> 201 | 中奖历史 202 | 203 | 204 | {title} 205 | 206 | 207 | 您共有{`${canRollNum}`}次抽奖机会 208 | 209 | 210 | 211 | 212 | 213 | {lottery.map((item, index) => { 214 | return ( 215 | 242 | 246 | {item} 247 | 248 | 249 | ); 250 | })} 251 | 252 | 253 | {/* 开始抽奖 */} 254 | 255 | 256 | 257 | {/* 活动详情 */} 258 | 259 | 260 | 261 | 活动详情 262 | 263 | 264 | 265 | {/* TODO-LIN 记得处理换行 */} 266 | 267 | 一、这里就是签到规则这里就是签到规则这里就是签到规则 268 | 二、这里就是签到规则这里就是签到规则这里就是签到规则这里就是签到规则这里就是签到规则这里就是签到规则 269 | 三、这里就是签到规则这里就是签到规则这里就是签到规则这里就是签到规则这里就是签到规则 270 | 271 | 272 | 273 | 274 | {/* 中奖提示弹窗 */} 275 | {visibleModal && ( 276 | 277 | 278 | 279 | 283 | 284 | {isWin ? winText : failText} 285 | 286 | {isWin ? ( 287 | 288 | 289 | 放弃奖品 290 | 291 | 298 | 299 | {prizeType == 2 ? '联系客服领取奖品' : '立即领取'} 300 | 301 | 302 | 303 | ) : ( 304 | 305 | 309 | 继续努力 310 | 311 | 312 | )} 313 | 314 | 315 | )} 316 | {/* 中奖记录弹窗 */} 317 | {visibleHistoryModal && ( 318 | 319 | 320 | 321 | this.showHistoryModal(false)} 323 | className="iconWheelModalClose" 324 | src={iconWheelModalClose} 325 | > 326 | 327 | 328 | 中奖历史 329 | 330 | 331 | 332 | 日期 333 | 334 | 335 | 奖品名称 336 | 337 | 338 | 奖品 339 | 340 | 341 | 兑换情况 342 | 343 | 344 | 345 | {historyData.map((item, index) => { 346 | return ( 347 | 348 | 349 | {item.winningTime} 350 | 351 | 352 | {item.awardName} 353 | 354 | 355 | {item.award} 356 | 357 | 358 | {item.exchangeStatusName} 359 | 360 | 361 | ); 362 | })} 363 | 364 | 365 | 366 | )} 367 | 368 | ); 369 | } 370 | } 371 | 372 | export default BigWheel; 373 | --------------------------------------------------------------------------------