uni-app 抽奖
本文出自:https://www.cnblogs.com/2186009311CFF/p/14435558.html
uniapp插件(示例可直接运行查看效果):https://ext.dcloud.net.cn/plugin?id=4194
预览效果:
ay-lottery组件:
<template> <view> <turnLottery v-if="type==1" :themeColor="themeColor" :btn_Color="btn_Color" :seled_Color="seled_Color" :seled_t_Color="seled_t_Color" :un_seled_Color="un_seled_Color" :un_seled_t_Color="un_seled_t_Color" :show_again="show_again" :again_txt="again_txt" :result_txt="result_txt" :tips_init="tips_init" :no_z_init="no_z_init" @show="show" @again="again" ></turnLottery> <marquee v-if="type==2" :list="list" :themeColor="themeColor" :bgColor="bgColor" :bg_sd_Color="bg_sd_Color" @result="result" @toDetailPage="toDetailPage"></marquee> <turnplate v-if="type==3" :list="list" :chance_num_init="chance_num_init" :height="height" :width="width" @result="result" @toDetailPage="toDetailPage" :stay_index="stay_index"></turnplate> <blow v-if="type==4" ref="blowRef" :canvasId="canvasId" :height="height" :width="width" :percentage="percentage" :touchSize="touchSize" :fillColor="fillColor" :watermark="watermark" :watermarkColor="watermarkColor" :watermarkSize="watermarkSize" :title="title" :titleColor="titleColor" :titleSize="titleSize" :disabled="disabled" :is_show="is_show" :result_img="result_img" :result_txt="result_txt" :txtFontSize="txtFontSize" :txtColor="txtColor" @complete="complete" @init="init"></blow> <blowImg v-if="type==5" ref="blowRef" :canvasId="canvasId" :height="height" :width="width" :percentage="percentage" :touchSize="touchSize" :fillColor="fillColor" :watermark="watermark" :watermarkColor="watermarkColor" :watermarkSize="watermarkSize" :title="title" :titleColor="titleColor" :titleSize="titleSize" :disabled="disabled" :is_show="is_show" :result_img="result_img" :result_txt="result_txt" :txtFontSize="txtFontSize" :txtColor="txtColor" @complete="complete" @init="init"></blowImg> </view> </template> <script> import marquee from './marquee.vue'; import turnplate from './turnplate.vue'; import turnLottery from './turnLottery.vue'; import blow from './blow.vue'; import blowImg from './blow_img.vue'; export default { components: { marquee, turnplate, turnLottery, blow, blowImg, }, props: { type: { type: Number, default: 1, //1:翻牌 2:跑马灯 3:转盘 4: 刮一刮(文本) 5: 刮一刮(图片) }, list: { type: Array, default () { return [] } }, height: { type: Number, default: 150 }, width: { type: Number, default: 150 }, themeColor: { type: String, default: '#33CCCC', }, btn_Color: { type: String, default: '#ffffff', }, seled_Color: { type: String, default: '#f43f3b', }, seled_t_Color: { type: String, default: '#98FB98', }, un_seled_Color: { type: String, default: '#00BFFF', }, un_seled_t_Color: { type: String, default: '#33CCCC', }, result_txt: { type: String, default: '中奖结果', }, show_again: { type: Boolean, default: false }, again_txt: { type: String, default: '重新开始', }, tips_init: { type: String, default: '点击', }, no_z_init: { type: String, default: '谢谢参与', }, bgColor: { type: String, default: '#1E90FF', }, bg_sd_Color: { type: String, default: '#4169E1', }, chance_num_init :{ type: Number, default: 5 }, height: { type: Number, default: 700 }, width: { type: Number, default: 700 }, txtColor: { type: String, default: '#FFFFFF', }, txtFontSize: { type: Number, default: 50, }, canvasId: { type: String, default: 'blow', }, //停留位置 stay_index :{ type: Number, default: 1 }, percentage : { //刮开百分之多少的时候开奖 type : Number , default : 45 }, touchSize : { //触摸画笔大小 type : Number , default : 20 }, fillColor : { //未刮开图层时的填充色 type : String , default : '#ddd' }, watermark : { //水印文字 type : String , default : '刮一刮' }, watermarkColor : { //水印文字颜色 type : String , default : '#c5c5c5' }, watermarkSize : { //水印文字大小 type : Number , default : 14 }, title : { //提示文字 type : String , default : '刮一刮开奖' }, titleColor : { //提示文字颜色 type : String , default : '#888' }, titleSize : { //提示文字大小 type : Number , default : 24 }, disabled : { //是否禁止刮卡 type : Boolean , default : false }, is_show : { //防止画布画好前闪烁 type : Boolean , default : false }, result_img: { type: String, default: 'https://cdn.pixabay.com/photo/2021/01/04/07/38/lily-5886728__340.jpg', }, }, computed: { }, watch: { }, data() { return { }; }, methods: { initBlow(){ this.$refs.blowRef.initBlow() }, show(e){ this.$emit('show', e); }, again(e){ this.$emit('again', e); }, result(e){ this.$emit('result', e); }, toDetailPage(e){ this.$emit('toDetailPage', e); }, complete(e){ this.$emit('complete', e); }, init(e){ this.$emit('init', e); }, }, } </script> <style lang="scss"> </style>
翻牌
<aylottery :type="1" themeColor="#33CCCC" btn_Color="#ffffff" seled_Color="#DB7093" seled_t_Color="#98FB98" un_seled_Color="#00BFFF" un_seled_t_Color="#33CCCC" :result_txt="result_turn" @show="show_turn" @again="again_turn" :show_again="true" again_txt="重新开始" :tips_init="tips_init_turn" :no_z_init="no_z_init_turn"></aylottery>
<template> <view> <view v-if="show_again" class="re-turn" :style="[{'background-color': themeColor},{color: btn_Color }]" @click="again">{{again_txt}}</view> <view class="box"> <view @click="tamin(index)" v-for="(item,index) in 9" :key="index" class="box-item" :class="[really == index+1?'animt':'', really != index+1 && surplus?'animt':'', really == ''?'item'+(index+1):'']" :style="really == index+1 && implement > 1?style_seled:style_un_seled"> {{really == index+1?can_z:''}}{{really != index+1 && really != ''?no_z:''}}{{really == ''?tips:''}} </view> </view> </view> </template> <script> export default { props: { themeColor: { type: String, default: '#33CCCC', }, btn_Color: { type: String, default: '#ffffff', }, seled_Color: { type: String, default: '#f43f3b', }, seled_t_Color: { type: String, default: '#98FB98', }, un_seled_Color: { type: String, default: '#00BFFF', }, un_seled_t_Color: { type: String, default: '#33CCCC', }, result_txt: { type: String, default: '结果', }, show_again: { type: Boolean, default: false }, again_txt: { type: String, default: '重新开始', }, tips_init: { type: String, default: '点击', }, no_z_init: { type: String, default: '谢谢参与', }, height: { type: Number, default: 150 }, width: { type: Number, default: 350 }, }, watch:{ result_txt(e){ this.can_z = e ; }, tips_init(e){ this.tips = e ; }, no_z_init(e){ this.no_z = e ; }, }, created:function(){ let tips_init = this.tips_init this.tips = tips_init ; this.can_z = tips_init ; this.no_z = this.no_z_init ; }, computed: { style_seled() { let that = this; var style = ''; style = `background-image: linear-gradient(45deg, ${that.seled_Color}, ${that.seled_t_Color});`; return style; }, style_un_seled() { let that = this; var style = ''; style = `background-image: linear-gradient(45deg, ${that.un_seled_Color}, ${that.un_seled_t_Color});`; return style; }, }, data() { return { whether: false, can_z: '', really: '', implement: 0, surplus: false, no_z: '', tips:'', } }, methods: { again(e) { if (this.implement == 3 || this.implement == 0) { this.whether = false this.can_z = this.tips ; this.really = '' this.implement = 0 this.surplus = false this.no_z = this.tips ; let data = { }; this.$emit('again', data); } else { uni.showToast({ title: '正在执行中...', icon: 'none', duration: 2000 }) return false } }, tamin(index) { if (this.really == '') { this.whether = true this.really = index + 1 this.implement = 1 setTimeout(res => { this.can_z = '' }, 500) setTimeout(res => { //this.can_z = this.result_txt; let data = { result : 1 ,//1成功 0失败 }; this.$emit('show', data); this.surplus = true this.implement = 2 }, 1200) setTimeout(res => { this.no_z = '' }, 1700) setTimeout(res => { let data = { result : 0 ,//1成功 0失败 }; this.$emit('show', data); //this.no_z = '谢谢惠顾' this.implement = 3 }, 2500) } } } } </script> <style lang="scss"> .re-turn { width: 40%; height: 80rpx; line-height: 80rpx; text-align: center; border-radius: 10rpx; margin: 30rpx 30%; position: relative; } .box { width: 100%; display: flex; justify-content: space-around; align-items: center; flex-wrap: wrap; padding: 10upx 10upx 20upx 10upx; } .box-item { display: flex; flex-direction: column; align-items: center; font-size: 25upx; width: 28%; height: 200rpx; line-height: 200rpx; border-radius: 10rpx; position: relative; color: #fff; margin-left: 0%; margin-top: 50rpx; text-align: center; } .box-item::before { content: ""; display: block; background: inherit; filter: blur(10rpx); position: absolute; width: 100%; height: 100%; top: 10rpx; left: 10rpx; z-index: -1; opacity: 0.4; transform-origin: 0 0; border-radius: inherit; transform: scale(1, 1); } .item1 { animation: item1 alternate linear 2 1s; } @keyframes item1 { from { top: 0; left: 0; } to { top: 230rpx; left: 230rpx; } } .item2 { animation: item2 alternate linear 2 1s; } @keyframes item2 { from { top: 0; left: 0; } to { top: 230rpx; left: 0rpx; } } .item3 { animation: item3 alternate linear 2 1s; } @keyframes item3 { from { top: 0; left: 0; } to { top: 230rpx; left: -230rpx; } } .item4 { animation: item4 alternate linear 2 1s; } @keyframes item4 { from { top: 0; left: 0; } to { top: 0rpx; left: 230rpx; } } .item6 { animation: item6 alternate linear 2 1s; } @keyframes item6 { from { top: 0; left: 0; } to { top: 0rpx; left: -230rpx; } } .item7 { animation: item7 alternate linear 2 1s; } @keyframes item7 { from { top: 0; left: 0; } to { top: -230rpx; left: 230rpx; } } .item8 { animation: item8 alternate linear 2 1s; } @keyframes item8 { from { top: 0; left: 0; } to { top: -230rpx; left: 0rpx; } } .item9 { animation: item9 alternate linear 2 1s; } @keyframes item9 { from { top: 0; left: 0; } to { top: -230rpx; left: -230rpx; } } .animt { animation: turn 1.2s; } @keyframes turn { 0% { transform: perspective(150px) rotateY(0deg); } 50% { transform: perspective(150px) rotateY(0deg); } 100% { transform: perspective(150px) rotateY(179.9deg); } } </style>
跑马灯
<aylottery :type="2" :list="list" themeColor="#33CCCC" bgColor="#1E90FF" bg_sd_Color="#4169E1" @result="resultFun"
@toDetailPage="toDetailPage"></aylottery>
<template> <view> <view class="box" :style="style_box"> <view class="dot" :class="'dot-'+(index+1)" v-for="(item,index) in dotList" :key="index"></view> <view class="box-in" :style="style_box_in"> <view class="ct-out" :class="['award-'+(index+1),index==indexSelect?'awardSelect':'']" v-for="(item,index) in list" :key="index"> <image lazy-load="true" @tap="toDetailPage({index: index})" class="award-image" :src="item.img"></image> </view> <view class="btn-start" :class="isRunning?'ative':''" @click="start">开始</view> </view> </view> </view> </template> <script> export default { props: { list: { type: Array, default () { return [] } }, themeColor: { type: String, default: '#33CCCC', }, bgColor: { type: String, default: '#1E90FF', }, bg_sd_Color: { type: String, default: '#4169E1', }, height: { type: Number, default: 600 }, width: { type: Number, default: 650 }, }, data() { return { dotList: 24, //圆点个数 //奖品 indexSelect: 0, //抽中的奖品下标 isRunning: false //抽中状态 } }, computed: { style_box() { let that = this; var height = parseInt(that.height); var width = parseInt(that.width); var style = ''; if (height > 0) { style = `height:${height}rpx;`; } if (width > 0) { style += `width:${width}rpx;`; } style += `background-color:${that.bgColor};`; style += `box-shadow: 0 10px 0 ${that.bg_sd_Color};`; return style; }, style_box_in() { let that = this; var height = parseInt(that.height); var width = parseInt(that.width); var style = ''; if (height > 70) { style = `height:${height-70}rpx;`; } if (width > 70) { style += `width:${width-70}rpx;`; } style += `background-color:${that.themeColor};`; return style; }, }, methods: { //详情页 toDetailPage(item) { let that = this ; let list = that.list ; let index = item.index ; let data = { curIndex: index, item : list[index] , list: list }; this.$emit('toDetailPage', data); }, //随机数 random(u) { let rnd = Math.random() > 0.5 ? "2" : "1"; u = u || 3; for (var i = 0; i < u; i++) { rnd += Math.floor(Math.random() * 10); } return Number(rnd); }, //开始 start() { let that = this ; if (this.isRunning) return this.isRunning = true; let indexSelect = 0; let i = 0; let randomNum = this.random(3); let timer = setInterval(() => { ++indexSelect; //这里用y=30*x+150函数做的处理.可根据自己的需求改变转盘速度 indexSelect = indexSelect % 8; this.indexSelect = indexSelect; i += 40; if (i > randomNum) { //去除循环 clearInterval(timer) timer = null; let data = { curIndex: indexSelect, item: that.list[indexSelect], list: that.list }; this.$emit('result', data); this.isRunning = false } }, (70 + i)) } } } </script> <style lang="scss"> .box { margin: 40rpx auto; border-radius: 40rpx; position: relative; } .box-in { border-radius: 40rpx; position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; } /**小圆点 start*/ .dot { position: absolute; display: block; border-radius: 50%; height: 20rpx; width: 20rpx; } .dot:nth-child(odd) { background: #fff; animation: 0.5s odd linear infinite; } .dot:nth-child(even) { background: #fcf400; animation: 0.5s even linear infinite; } .dot-1 { left: 15rpx; top: 15rpx; } .dot-2 { left: 117.5rpx; top: 7.5rpx; } .dot-3 { left: 220rpx; top: 7.5rpx; } .dot-4 { left: 322.5rpx; top: 7.5rpx; } .dot-5 { left: 425rpx; top: 7.5rpx; } .dot-6 { left: 527.5rpx; top: 7.5rpx; } .dot-7 { left: 620rpx; top: 15rpx; } .dot-8 { left: 622rpx; top: 109rpx; } .dot-9 { left: 622rpx; top: 203rpx; } .dot-10 { left: 622rpx; top: 297rpx; } .dot-11 { left: 622rpx; top: 391rpx; } .dot-12 { left: 622rpx; top: 485rpx; } .dot-13 { left: 620rpx; top: 565rpx; } .dot-14 { left: 517.5rpx; top: 572rpx; } .dot-15 { left: 415rpx; top: 572rpx; } .dot-16 { left: 312.5rpx; top: 572rpx; } .dot-17 { left: 210rpx; top: 572rpx; } .dot-18 { left: 107.5rpx; top: 572rpx; } .dot-19 { left: 15rpx; top: 565rpx; } .dot-20 { left: 7.5rpx; top: 471rpx; } .dot-21 { left: 7.5rpx; top: 377rpx; } .dot-22 { left: 7.5rpx; top: 283rpx; } .dot-23 { left: 7.5rpx; top: 189rpx; } .dot-24 { left: 7.5rpx; top: 95rpx; } @-webkit-keyframes odd { 0% { background: #fff; } 100% { background: #fcf400; } } @keyframes odd { 0% { background: #fff; } 100% { background: #fcf400; } } @-webkit-keyframes even { 0% { background: #fcf400; } 100% { background: #fff; } } @keyframes even { 0% { background: #fcf400; } 100% { background: #fff; } } /**小圆点 end*/ .ct-out { position: absolute; height: 150rpx; width: 168rpx; background-color: #fcecec; border-radius: 15rpx; box-shadow: 0 4px 0 #fcc8d0; } /* 580 530 */ .award-1 { left: 24rpx; top: 24rpx; } .award-2 { left: 206rpx; top: 24rpx; } .award-3 { left: 388rpx; top: 24rpx; } .award-4 { left: 388rpx; top: 188rpx; } .award-5 { left: 388rpx; top: 352rpx; } .award-6 { left: 206rpx; top: 352rpx; } .award-7 { left: 24rpx; top: 352rpx; } .award-8 { left: 24rpx; top: 188rpx; } /**居中 加粗*/ .btn-start { position: absolute; top: 188rpx; left: 206rpx; border-radius: 15rpx; height: 150rpx; width: 168rpx; background-color: #fc4034; box-shadow: 0 4px 0 #fcc8d0; color: #fcf400; text-align: center; font-size: 32rpx; font-weight: bold; line-height: 150rpx; } .ative { opacity: 0.6 !important; } .award-image { position: absolute; margin: auto; top: 0; left: 0; bottom: 0; right: 0; height: 50rpx; width: 50rpx; border-radius: 50%; } .awardSelect { background-color: #fcf400 !important; box-shadow: 0 4px 0 rgb(240, 208, 12) !important; } </style>
转盘
<aylottery :type="3" :list="list_r" :height="600" :width="600" :chance_num_init="chance_num_init" @result="resultFun_chance"
@toDetailPage="toDetailPage" :stay_index="stay_index_r"></aylottery>
<template> <view> <view class="box" :style="style_box"> <view :animation="animationData" class="cs-ct" :style="style_wh"> <view class="cs-line"> <view class="cs-litem" v-for="(item,index) in awardsList" :key="index" :style="[{transform:'rotate('+item.lineTurn+')'},{'background-color':themeColor},{left:(width/2) +'rpx'},{height:(height/2) +'rpx'},{'-webkit-transform-origin': '50% ' +(height/2) +'rpx'},{'transform-origin': '50% ' +(height/2) +'rpx'}]"></view> </view> <view class="cs-list"> <view class="cs-item" :style="{color: themeColor }" v-for="(iteml,index2) in awardsList" :key="index2"> <view class="cs-item-text" :style="[{transform:'rotate('+iteml.turn+')'},{'-webkit-transform-origin': '50% ' +(height/2) +'rpx'},{'transform-origin': '50% ' +(height/2) +'rpx'}]"> <text class="txt">{{iteml.name}}</text> <image lazy-load="true" class="cs-item-text-img" :src="iteml.img" @tap="toDetailPage({index: index2})"></image> </view> </view> </view> </view> <view @tap="playReward" class="cs-btn" :style="[{left:((width/2)-40) +'rpx'},{top:((height/2)-40) +'rpx'}]" v-bind:class="btnDisabled">开始 </view> <view class="cs-btn-table" :style="[{left:((width/2)-50) +'rpx'},{top:((height/2)+50) +'rpx'},{color: themeColor }]">剩余{{chance_num}}次</view> </view> </view> </template> <script> export default { props: { list: { type: Array, default () { return [] } }, height: { type: Number, default: 700 }, width: { type: Number, default: 700 }, themeColor: { type: String, default: '#33CCCC', }, chance_num_init :{ type: Number, default: 5 }, //停留位置 stay_index :{ type: Number, default: 1 }, }, data() { return { chance: true, awardsList: {}, animationData: {}, btnDisabled: '', chance_num: 5 }; }, watch:{ list(){ this.init() }, chance_num_init(e){ this.chance_num = e ; }, }, created() { this.init(); this.chance_num = this.chance_num_init ; }, computed: { style_box() { let that = this; var height = parseInt(that.height); var width = parseInt(that.width); var style = ''; if (height > 0) { style = `height:${height}rpx;`; } if (width > 0) { style += `width:${width}rpx;`; } style += `border: 8rpx solid ${that.themeColor};`; return style; }, style_wh() { let that = this; var height = parseInt(that.height); var width = parseInt(that.width); var style = ''; if (height > 0) { style = `height:${height}rpx;`; } if (width > 0) { style += `width:${width}rpx;`; } return style; }, }, methods: { //详情页 toDetailPage(item) { let that = this ; let list = that.awardsList ; let index = item.index ; let data = { curIndex: index, item : list[index] , list: list }; this.$emit('toDetailPage', data); }, //画抽奖圆盘 init: function() { var awards = this.list; var awardsList = []; var turnNum = 1 / awards.length * 360; // 文字旋转 turn 值 // 奖项列表 for (var i = 0; i < awards.length; i++) { awardsList.push({ turn: i * turnNum + 'deg', lineTurn: i * turnNum + turnNum / 2 + 'deg', name: awards[i].name, img : awards[i].img, }); } this.btnDisabled = this.chance ? '' : 'disabled'; this.awardsList = awardsList; }, //发起抽奖 playReward: function() { let that = this ; if (this.chance_num == 0) { uni.showToast({ title: '次数已经用完', icon: 'none' }) return } //中奖index var awardsNum = that.list; //var awardIndex = Math.round(Math.random() * (awardsNum.length - 1)); //随机数 var awardIndex = that.stay_index ; var runNum = 8; //旋转8周 var duration = 4000; //时长 // 旋转角度 this.runDeg = this.runDeg || 0; this.runDeg = this.runDeg + (360 - this.runDeg % 360) + (360 * runNum - awardIndex * (360 / awardsNum.length)) //创建动画 var animationRun = uni.createAnimation({ duration: duration, timingFunction: 'ease' }) animationRun.rotate(that.runDeg).step(); that.animationData = animationRun.export(); that.btnDisabled = 'disabled'; // 中奖提示 var isAward = that.list[awardIndex].isAward || false; that.chance_num = that.chance_num - 1; if (isAward) { setTimeout(function() { that.btnDisabled = ''; }.bind(that), duration); } else { setTimeout(function() { uni.showModal({ title: '很遗憾', content: '没中 ' + (that.list[awardIndex].name), showCancel: false }); that.btnDisabled = ''; }.bind(that), duration); } setTimeout(function() { let data = { curIndex: awardIndex, item: that.list[awardIndex], list: that.list, isAward : isAward , }; this.$emit('result', data); }.bind(that), duration); } } } </script> <style> .txt{ padding-top: 10upx; padding-bottom: 10upx; } /* 转盘 */ .box { margin: 0 auto; position: relative; border-radius: 50%; box-shadow: 0 10upx 30upx #333, 0 0 10upx #000; } .cs-ct { position: absolute; left: 0; top: 0; z-index: 1; display: block; border-radius: inherit; background-clip: padding-box; } .cs-element { position: relative; z-index: 1; width: inherit; height: inherit; border-radius: 50%; } .cs-list { position: absolute; left: 0; top: 0; width: inherit; height: inherit; z-index: 9999; } .cs-item { position: absolute; left: 0; top: 0; width: 100%; height: 100%; font-weight: bold; text-shadow: 0 1upx 1upx rgba(255, 255, 255, 0.6); } .cs-item-text { position: relative; display: block; padding-top: 20upx; margin: 0 auto; text-align: center; display: flex; flex-direction: column; align-items: center; } .cs-item-text text { font-size: 30upx; } .cs-item-text-img { width: 60upx; height: 60upx; border-radius: 50%; } /* 分隔线 */ .cs-line { position: absolute; left: 0; top: 0; width: inherit; height: inherit; z-index: 99; } .cs-litem { position: absolute; top: 0; width: 3upx; overflow: hidden; } /** * 抽奖按钮 */ .cs-btn { position: absolute; background-color: #e44025; z-index: 400; width: 80upx; height: 80upx; border-radius: 50%; color: #f4e9cc; line-height: 80upx; text-align: center; font-size: 26upx; text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.6); box-shadow: 0 3px 5px rgba(0, 0, 0, 0.6); text-decoration: none; } .cs-btn::after { position: absolute; display: block; content: ' '; left: 12upx; top: -44upx; width: 0; height: 0; overflow: hidden; border-width: 30upx; border-style: solid; border-color: transparent; border-bottom-color: #e44025; } .cs-btn.disabled { pointer-events: none; background: #b07a7b; color: #ccc; } .cs-btn.disabled::after { border-bottom-color: #b07a7b; } .cs-btn-table { width: 120upx; text-align: center; position: absolute; font-size: 26upx; background-color: #FFFFFF; opacity: 0.9; } </style>
刮一刮(文本)
<aylottery :type="4" canvasId="canvasId1" :height="200" :width="600" refs="card" style="position: relative;margin: 20upx 40upx;"
@complete="seatShow" :disabled="false" title="刮文本" watermark="刮一刮" @init="init_blow" :is_show="is_show_blow" :result_txt="result_blow" themeColor="#33CCCC" :txtFontSize="txtFontSize_blow" :txtColor="txtColor_blow">
</aylottery>
<template> <view> <view :id="canvasId" class="box"> <view :style="{width: width+'rpx', height : height+'rpx'}"> <view class="blow" v-if="is_show" :style="{width: width+'rpx', height : height+'rpx'}" style="position: absolute;"> <view class="box" :style="{background: themeColor }"> <view class="result" :style="[{'font-size':txtFontSize+'rpx'},{color: txtColor }]"> <text>{{result_txt}}</text> </view> </view> </view> <canvas style="position: absolute;" :style="{width: width+'rpx', height : height+'rpx'}" :disable-scroll="true" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove" :canvas-id="canvasId"></canvas> </view> </view> </view> </template> <script> let ctx = null; export default { props: { is_show: { //防止画布画好前闪烁 type: Boolean, default: false }, result_txt: { type: String, default: '结果', }, themeColor: { type: String, default: '#33CCCC', }, txtColor: { type: String, default: '#FFFFFF', }, txtFontSize: { type: Number, default: 50, }, canvasId: { type: String, default: 'blow', }, height: { type: Number, default: 200 }, width: { type: Number, default: 300 }, percentage: { //刮开百分之多少的时候开奖 type: Number, default: 45 }, touchSize: { //触摸画笔大小 type: Number, default: 20 }, fillColor: { //未刮开图层时的填充色 type: String, default: '#ddd' }, watermark: { //水印文字 type: String, default: '刮一刮' }, watermarkColor: { //水印文字颜色 type: String, default: '#c5c5c5' }, watermarkSize: { //水印文字大小 type: Number, default: 14 }, title: { //提示文字 type: String, default: '刮一刮开奖' }, titleColor: { //提示文字颜色 type: String, default: '#888' }, titleSize: { //提示文字大小 type: Number, default: 24 }, disabled: { //是否禁止刮卡 type: Boolean, default: false }, }, data() { return { startX: null, startY: null, computing: false, complete: false, reset: false, ready: false, storePoints: [] }; }, mounted() { ctx = uni.createCanvasContext(this.canvasId, this); this.initBlow(); }, methods: { initBlow: function() { this.computing = false; this.complete = false; this.reset = false; this.ready = false; ctx.clearRect(0, 0, this.width, this.height); //绘制画布 ctx.setFillStyle(this.fillColor); ctx.fillRect(0, 0, this.width, this.height); this.ready = true; //绘制文字水印 this.fillWatermark(); //绘制标题 this.fillTitle(); ctx.draw(); setTimeout(res => { let data = { }; this.$emit('init', data); }, 50) }, /** * 绘制文字水印 */ fillWatermark: function(e) { if (!this.watermark) { return; } var width = this.watermark.length * this.watermarkSize; ctx.save(); ctx.rotate(-10 * Math.PI / 180); let x = 0; let y = 0; let i = 0; while ((x <= this.width * 5 || y <= this.height * 5) && i < 300) { ctx.setFillStyle(this.watermarkColor); ctx.setFontSize(this.watermarkSize); ctx.fillText(this.watermark, x, y); x += width + width * 1.6; if (x > this.width && y <= this.height) { x = -Math.random() * 100; y += this.watermarkSize * 3; } i++; } ctx.restore(); }, /** * 绘制标题 */ fillTitle: function(e) { if (!this.title) { return; } ctx.setTextAlign("center"); ctx.setTextBaseline("middle"); ctx.setFillStyle(this.titleColor); ctx.setFontSize(this.titleSize); ctx.fillText(this.title, this.width / 2 / 2, this.height / 2 / 2); //因单位是rpx故再除以2 }, touchstart: function(e) { if (this.disabled) { return; } this.startX = e.touches[0].x; this.startY = e.touches[0].y; }, touchend: function(e) { this.getFilledPercentage(); }, touchmove: function(e) { if (this.complete || this.disabled) { return; } // ctx.globalCompositeOperation = 'destination-out'; ctx.moveTo(this.startX, this.startY); // ctx.beginPath(); // ctx.arc(this.startX, this.startY, 20, 0, Math.PI * 20); // ctx.fill(); ctx.clearRect(this.startX, this.startY, this.touchSize, this.touchSize); ctx.draw(true); //记录移动点位 this.startX = e.touches[0].x; this.startY = e.touches[0].y; }, getFilledPercentage: function(e) { if (this.computing) { return; } this.computing = true; uni.canvasGetImageData({ canvasId: this.canvasId, x: 0, y: 0, width: this.width, height: this.height, success: (res) => { let pixels = res.data; let transPixels = []; for (let i = 0; i < pixels.length; i += 4) { if (pixels[i + 3] < 128) { transPixels.push(pixels[i + 3]); } } var percent = (transPixels.length / (pixels.length / 4) * 100).toFixed(2); if (percent >= this.percentage) { this.success(); } this.computing = false; console.log(percent) }, fail: function(e) { console.log(e); }, }, this); }, success: function(e) { this.complete = true; if (this.reset) { return; } this.reset = true; ctx.moveTo(0, 0); ctx.clearRect(0, 0, this.width, this.height); ctx.stroke(); ctx.draw(true); this.$emit("complete", {}); }, } } </script> <style lang="scss"> .blow { background-size: contain; margin: 0rpx auto; box-sizing: border-box; position: relative; overflow: hidden; .box { width: 100%; height: 100%; // background: #aaaa7f; border-radius: 10rpx; position: relative; overflow: hidden; .result { height: 100%; display: flex; justify-content: center; align-items: center; // font-size: 50rpx; // color: #FFFFFF; } } } .box { display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; } </style>
刮一刮(图片)
<aylottery :type="5" canvasId="canvasId2" :height="200" :width="600" refs="card" style="position: relative;margin: 0 40upx;" @complete="seatShow"
:disabled="false" title="刮图片" watermark="刮一刮" @init="init_blow" :is_show="is_show_blow" :result_img="result_img_blow">
<template> <view > <view :id="canvasId" class="box"> <view :style="{width: width+'rpx', height : height+'rpx'}" > <view style="position: absolute;" v-if="is_show"> <view> <image :style="{width: width+'rpx', height : height+'rpx'}" :src="result_img"></image> </view> </view> <canvas style="position: absolute;" :style="{width: width+'rpx', height : height+'rpx'}" :disable-scroll="true" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove" :canvas-id="canvasId"></canvas> </view> </view> </view> </template> <script> let ctx = null ; export default { props:{ is_show: { //防止画布画好前闪烁 type: Boolean, default: false }, result_img: { type: String, default: 'https://cdn.pixabay.com/photo/2021/01/04/07/38/lily-5886728__340.jpg', }, canvasId: { type: String, default: 'blow', }, height: { type: Number, default: 200 }, width: { type: Number, default: 300 }, percentage : { //刮开百分之多少的时候开奖 type : Number , default : 45 }, touchSize : { //触摸画笔大小 type : Number , default : 20 }, fillColor : { //未刮开图层时的填充色 type : String , default : '#ddd' }, watermark : { //水印文字 type : String , default : '刮一刮' }, watermarkColor : { //水印文字颜色 type : String , default : '#c5c5c5' }, watermarkSize : { //水印文字大小 type : Number , default : 14 }, title : { //提示文字 type : String , default : '刮一刮开奖' }, titleColor : { //提示文字颜色 type : String , default : '#888' }, titleSize : { //提示文字大小 type : Number , default : 24 }, disabled : { //是否禁止刮卡 type : Boolean , default : false }, }, data() { return { startX : null , startY : null , computing : false , complete : false , reset : false , ready : false , storePoints:[] }; }, mounted() { ctx = uni.createCanvasContext(this.canvasId , this) ; this.initBlow(); }, methods:{ initBlow : function(){ this.computing = false ; this.complete = false ; this.reset = false ; this.ready = false ; ctx.clearRect(0,0,this.width,this.height); //绘制画布 ctx.setFillStyle(this.fillColor); ctx.fillRect(0, 0, this.width , this.height ); this.ready = true ; //绘制文字水印 this.fillWatermark(); //绘制标题 this.fillTitle(); ctx.draw(); setTimeout(res => { let data = { }; this.$emit('init', data); }, 50) }, /** * 绘制文字水印 */ fillWatermark : function(e){ if (!this.watermark) { return ; } var width = this.watermark.length * this.watermarkSize ; ctx.save() ; ctx.rotate(-10 * Math.PI / 180); let x = 0 ; let y = 0 ; let i = 0 ; while( (x <= this.width * 5 || y <= this.height*5) && i < 300){ ctx.setFillStyle(this.watermarkColor); ctx.setFontSize(this.watermarkSize); ctx.fillText(this.watermark, x , y ); x += width + width * 1.6 ; if (x > this.width && y <= this.height ) { x = -Math.random()*100 ; y += this.watermarkSize * 3 ; } i++ ; } ctx.restore(); }, /** * 绘制标题 */ fillTitle : function(e){ if (!this.title) { return ; } ctx.setTextAlign("center"); ctx.setTextBaseline("middle"); ctx.setFillStyle(this.titleColor); ctx.setFontSize(this.titleSize); ctx.fillText(this.title, this.width/2/2 , this.height/2/2 );//因单位是rpx故再除以2 }, touchstart : function(e){ if (this.disabled) { return ; } this.startX = e.touches[0].x; this.startY = e.touches[0].y; }, touchend : function(e){ this.getFilledPercentage(); }, touchmove : function(e){ if(this.complete || this.disabled ){ return ; } // ctx.globalCompositeOperation = 'destination-out'; ctx.moveTo(this.startX , this.startY ); // ctx.beginPath(); // ctx.arc(this.startX, this.startY, 20, 0, Math.PI * 20); // ctx.fill(); ctx.clearRect( this.startX , this.startY , this.touchSize , this.touchSize ) ; ctx.draw(true); //记录移动点位 this.startX = e.touches[0].x; this.startY = e.touches[0].y; }, getFilledPercentage:function(e){ if (this.computing) { return ; } this.computing = true ; uni.canvasGetImageData({ canvasId: this.canvasId , x: 0, y: 0, width: this.width , height: this.height , success: (res) => { let pixels = res.data; let transPixels = []; for (let i = 0; i < pixels.length; i += 4) { if (pixels[i + 3] < 128) { transPixels.push(pixels[i + 3]); } } var percent = (transPixels.length / (pixels.length / 4) * 100).toFixed(2); if( percent >= this.percentage ){ this.success(); } this.computing = false ; console.log(percent) }, fail : function(e){ console.log(e); }, }, this); }, success : function(e){ this.complete = true ; if (this.reset) { return ; } this.reset = true ; ctx.moveTo(0, 0); ctx.clearRect(0,0, this.width, this.height); ctx.stroke() ; ctx.draw(true); this.$emit("complete",{}); }, } } </script> <style lang="scss"> .box{ display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; } </style>
刮自定义
<template> <view > <view :id="canvasId" class="box"> <view :style="{width: width+'rpx', height : height+'rpx'}" > <slot></slot> <canvas style="position: absolute;" :style="{width: width+'rpx', height : height+'rpx'}" :disable-scroll="true" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove" :canvas-id="canvasId"></canvas> </view> </view> </view> </template> <script> let ctx = null ; export default { props:{ canvasId: { type: String, default: 'blow', }, height: { type: Number, default: 200 }, width: { type: Number, default: 300 }, percentage : { //刮开百分之多少的时候开奖 type : Number , default : 45 }, touchSize : { //触摸画笔大小 type : Number , default : 20 }, fillColor : { //未刮开图层时的填充色 type : String , default : '#ddd' }, watermark : { //水印文字 type : String , default : '刮一刮' }, watermarkColor : { //水印文字颜色 type : String , default : '#c5c5c5' }, watermarkSize : { //水印文字大小 type : Number , default : 14 }, title : { //提示文字 type : String , default : '刮一刮开奖' }, titleColor : { //提示文字颜色 type : String , default : '#888' }, titleSize : { //提示文字大小 type : Number , default : 24 }, disabled : { //是否禁止刮卡 type : Boolean , default : false }, }, data() { return { startX : null , startY : null , computing : false , complete : false , reset : false , ready : false , storePoints:[] }; }, mounted() { ctx = uni.createCanvasContext(this.canvasId , this) ; this.initBlow(); }, methods:{ initBlow : function(){ this.computing = false ; this.complete = false ; this.reset = false ; this.ready = false ; ctx.clearRect(0,0,this.width,this.height); //绘制画布 ctx.setFillStyle(this.fillColor); ctx.fillRect(0, 0, this.width , this.height ); this.ready = true ; //绘制文字水印 this.fillWatermark(); //绘制标题 this.fillTitle(); ctx.draw(); setTimeout(res => { let data = { }; this.$emit('init', data); }, 50) }, /** * 绘制文字水印 */ fillWatermark : function(e){ if (!this.watermark) { return ; } var width = this.watermark.length * this.watermarkSize ; ctx.save() ; ctx.rotate(-10 * Math.PI / 180); let x = 0 ; let y = 0 ; let i = 0 ; while( (x <= this.width * 5 || y <= this.height*5) && i < 300){ ctx.setFillStyle(this.watermarkColor); ctx.setFontSize(this.watermarkSize); ctx.fillText(this.watermark, x , y ); x += width + width * 1.6 ; if (x > this.width && y <= this.height ) { x = -Math.random()*100 ; y += this.watermarkSize * 3 ; } i++ ; } ctx.restore(); }, /** * 绘制标题 */ fillTitle : function(e){ if (!this.title) { return ; } ctx.setTextAlign("center"); ctx.setTextBaseline("middle"); ctx.setFillStyle(this.titleColor); ctx.setFontSize(this.titleSize); ctx.fillText(this.title, this.width/2/2 , this.height/2/2 );//因单位是rpx故再除以2 }, touchstart : function(e){ if (this.disabled) { return ; } this.startX = e.touches[0].x; this.startY = e.touches[0].y; }, touchend : function(e){ this.getFilledPercentage(); }, touchmove : function(e){ if(this.complete || this.disabled ){ return ; } // ctx.globalCompositeOperation = 'destination-out'; ctx.moveTo(this.startX , this.startY ); // ctx.beginPath(); // ctx.arc(this.startX, this.startY, 20, 0, Math.PI * 20); // ctx.fill(); ctx.clearRect( this.startX , this.startY , this.touchSize , this.touchSize ) ; ctx.draw(true); //记录移动点位 this.startX = e.touches[0].x; this.startY = e.touches[0].y; }, getFilledPercentage:function(e){ if (this.computing) { return ; } this.computing = true ; uni.canvasGetImageData({ canvasId: this.canvasId , x: 0, y: 0, width: this.width , height: this.height , success: (res) => { let pixels = res.data; let transPixels = []; for (let i = 0; i < pixels.length; i += 4) { if (pixels[i + 3] < 128) { transPixels.push(pixels[i + 3]); } } var percent = (transPixels.length / (pixels.length / 4) * 100).toFixed(2); if( percent >= this.percentage ){ this.success(); } this.computing = false ; console.log(percent) }, fail : function(e){ console.log(e); }, }, this); }, success : function(e){ this.complete = true ; if (this.reset) { return ; } this.reset = true ; ctx.moveTo(0, 0); ctx.clearRect(0,0, this.width, this.height); ctx.stroke() ; ctx.draw(true); this.$emit("complete",{}); }, } } </script> <style lang="scss"> .box{ display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; } </style>
页面引用
<template> <view class="content"> <aylottery :type="1" themeColor="#33CCCC" btn_Color="#ffffff" seled_Color="#DB7093" seled_t_Color="#98FB98" un_seled_Color="#00BFFF" un_seled_t_Color="#33CCCC" :result_txt="result_turn" @show="show_turn" @again="again_turn" :show_again="true" again_txt="重新开始" :tips_init="tips_init_turn" :no_z_init="no_z_init_turn"></aylottery> <aylottery :type="2" :list="list" themeColor="#33CCCC" bgColor="#1E90FF" bg_sd_Color="#4169E1" @result="resultFun" @toDetailPage="toDetailPage"></aylottery> <aylottery :type="3" :list="list_r" :height="600" :width="600" :chance_num_init="chance_num_init" @result="resultFun_chance" @toDetailPage="toDetailPage" :stay_index="stay_index_r"></aylottery> <!-- <aylottery :type="4" canvasId="canvasId1" :height="200" :width="600" refs="card" style="position: relative;margin: 20upx 40upx;" @complete="seatShow" :disabled="false" title="刮文本" watermark="刮一刮" @init="init_blow" :is_show="is_show_blow" :result_txt="result_blow" themeColor="#33CCCC" :txtFontSize="txtFontSize_blow" :txtColor="txtColor_blow"> </aylottery> --> <!-- <aylottery :type="5" canvasId="canvasId2" :height="200" :width="600" refs="card" style="position: relative;margin: 0 40upx;" @complete="seatShow" :disabled="false" title="刮图片" watermark="刮一刮" @init="init_blow" :is_show="is_show_blow" :result_img="result_img_blow"></aylottery> --> <!-- <blowAny canvasId="canvasId1" :height="200" :width="600" refs="card" style="position: relative;margin: 0 40upx;" @complete="seatShow" :disabled="false" title="刮文本" watermark="刮一刮" @init="init_blow"> <view class="blow" v-if="is_show_blow" style="height:200rpx;width:600rpx;position: absolute;"> <view class="box" :style="{background: themeColor }"> <view class="result" :style="[{'font-size':txtFontSize_blow+'rpx'},{color: txtColor_blow }]"> <text>{{result_blow}}</text> </view> </view> </view> </blowAny> --> <!-- <blowAny canvasId="canvasId1" :height="200" :width="600" refs="card" style="position: relative;margin: 0 40upx;" @complete="seatShow" :disabled="false" title="刮图片" watermark="刮一刮" @init="init_blow"> <view style="position: absolute;" v-if="is_show_blow" > <view> <image style="height:200rpx;width:600rpx;" :src="result_img_blow"></image> </view> </view> </blowAny> --> <!-- <blowAny canvasId="canvasId1" :height="200" :width="600" refs="card" style="position: relative;margin: 0 40upx;" @complete="seatShow" :disabled="false" title="刮自定义" watermark="刮一刮" @init="init_blow"> <view style="position: absolute;" v-if="is_show_blow" > <view> 自定义内容需自己编写 </view> </view> </blowAny> --> </view> </template> <script> import aylottery from '@/components/ay-lottery/ay-lottery.vue'; import blowAny from '@/components/ay-lottery/blow_any.vue'; export default { components: { aylottery, blowAny, }, data() { return { result_img_blow: 'https://cdn.pixabay.com/photo/2021/01/04/07/38/lily-5886728__340.jpg', is_show_blow: false, //防止画布画好前闪烁 themeColor: '#33CCCC', txtFontSize_blow: 50, txtColor_blow: '#FFFFFF', stay_index_r_init : 4 , stay_index_r : 1, tips_init_turn:'点击', no_z_init_turn:'点击', result_turn:'', result_blow:'谢谢参与', chance_num_init:6, list: [{ img: "https://cdn.pixabay.com/photo/2017/01/21/13/55/nature-1997282__340.jpg", name: "不要指望他" }, { img: "https://cdn.pixabay.com/photo/2021/01/11/21/39/temple-5909803__340.jpg", name: "你在开玩笑么?" }, { img: "https://cdn.pixabay.com/photo/2020/01/13/23/15/snowboarding-4763731__340.jpg", name: "可怕" }, { img: "https://cdn.pixabay.com/photo/2019/11/30/21/37/stars-4664313__340.jpg", name: "可能" }, { img: "https://cdn.pixabay.com/photo/2020/12/23/14/41/forest-5855196_640.jpg", name: "不用担心" }, { img: "https://cdn.pixabay.com/photo/2021/01/24/21/52/grand-canyon-5946657__340.jpg", name: "答案就在你身边" }, { img: "https://cdn.pixabay.com/photo/2021/01/14/20/32/fish-5917864__340.jpg", name: "大胆一点" }, { img: "https://cdn.pixabay.com/photo/2020/01/03/21/32/field-4739176__340.jpg", name: "好运将会降临" }], list_r: [{ index: 0, name: '1次机会', isAward : true , val : 1 , type: 1, img: 'https://cdn.pixabay.com/photo/2020/11/23/15/00/butterfly-5770034__340.jpg', }, { index: 1, name: '谢谢参与', isAward : false , type: 0, img: 'https://cdn.pixabay.com/photo/2021/01/07/15/02/york-minster-5897525__340.jpg', }, { index: 2, name: '会特别顺利', val : 2 , isAward : true , type: 2, img: 'https://cdn.pixabay.com/photo/2021/01/20/21/03/purple-5935577__340.jpg', }, { index: 3, name: '谢谢参与', isAward : false , type: 0, img: 'https://cdn.pixabay.com/photo/2021/01/13/18/07/tree-5914851__340.jpg', }, { index: 4, name: '2次机会', val : 2 , isAward : true , type: 1, img: 'https://cdn.pixabay.com/photo/2021/01/11/18/41/snowfall-5909261__340.jpg', }, { index: 5, name: '谢谢参与', isAward : false , type: 0, img: 'https://cdn.pixabay.com/photo/2021/01/05/19/55/winter-5892335__340.jpg', }, { index: 6, name: '4次机会', val : 4 , isAward : true , type: 1, img: 'https://cdn.pixabay.com/photo/2018/11/11/19/46/christmas-3809544__340.jpg', }, { index: 7, name: '谢谢参与', isAward : false , type: 0, img: 'https://cdn.pixabay.com/photo/2020/12/15/20/50/christmas-5834904__340.jpg', }, { index: 8, name: '会付出代价', val : 5 , isAward : true , type: 2, img: 'https://cdn.pixabay.com/photo/2016/11/14/16/20/snowflake-1823942__340.jpg', }, { index: 9, name: '谢谢参与', isAward : false , type: 0, img: 'https://cdn.pixabay.com/photo/2020/12/01/16/11/ornaments-5794746__340.jpg', },], } }, onLoad() { let that = this; that.loadData(); }, onShow() { }, onReady: function() { let that = this; //#ifndef MP-WEIXIN setTimeout(function() { //that.$refs.blowRef.initBlow() }, 50) // #endif }, methods: { //刮一刮 init_blow() { this.is_show_blow = true; }, reset: function() { this.$refs.card.init(); }, seatShow: function() { }, toDetailPage(e) { let list = e.list; let idx = e.curIndex; let list_img = []; let item = e.item; list.forEach(item => { list_img.push(item.img) }) if (list_img && list_img.length > 0) { uni.previewImage({ current: list_img[idx], // 传 Number H5端出现不兼容 urls: list_img, indicator: "number", loop: true, }); } }, again_turn(e){ let that = this; that.result_turn = ''; that.no_z_init_turn = that.tips_init_turn; }, show_turn(e){ let that = this; if(e.result==1){ that.result_turn = that.getShowTxt(); }else{ that.no_z_init_turn = '谢谢参与'; } }, getShowTxt(){ let that = this; //随机获取list的值 let num = Math.floor(Math.random()*10);//可均衡获取0到9的随机整数 let legth = that.list.length || 0 ; let index = num<legth ? num : (legth-1) ; return that.list[index].name ||'哈哈' }, resultFun(e) { let that = this; let item = e.item; this.msg_modal("抽中了" + item.name,'恭喜您') }, resultFun_chance(e){ let that = this; let item = e.item; let index = e.curIndex ; let list = e.list; //定义下一次转的位置 that.stay_index_r = Math.round(Math.random() * (list.length - 1)); //随机数 if(e.isAward){ this.msg_modal('获得' + (item.name),'恭喜') let type = item.type ; if(type==1){ that.chance_num_init += item.val ; } } }, async loadData() { let that = this; uni.showLoading({ title: '加载中', mask: true, }) that.result_blow = that.getShowTxt(); that.result_blow = that.getShowTxt(); uni.hideLoading(); //第一次转盘停的位置 that.stay_index_r = that.stay_index_r_init ; that.isLoaded = true; }, msg_modal(content,title='温馨提示'){ //统一提示方便全局修改 if (Boolean(content) === false) { return; } uni.showModal({ title: title, content: content, confirmText: '确定', showCancel: false, confirmColor: '#33CCCC', success(res) { if (res.confirm) { } } }) } } } </script> <style lang="scss"> // 刮自定义 .blow { background-size: contain; margin: 0rpx auto; box-sizing: border-box; position: relative; overflow: hidden; .box { width: 100%; height: 100%; // background: #aaaa7f; border-radius: 10rpx; position: relative; overflow: hidden; .result { height: 100%; display: flex; justify-content: center; align-items: center; // font-size: 50rpx; // color: #FFFFFF; } } } .box { display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; } </style>
参考:
https://blog.csdn.net/qq_43764578/article/details/106329612
https://www.baidu.com/link?url=Vudt-1kEqZqAXnDyaw67FKE6qdANdkWOVl8OS9VSbezcql181qVYSar7PUdMPrzzM45XZnI4xF1deeIFbXMfTa&wd=&eqid=db15fd820008c60f000000065fafac6f
https://ext.dcloud.net.cn/plugin?id=1890
https://blog.csdn.net/qq_40101922/article/details/102463778
https://ext.dcloud.net.cn/plugin?id=3685
https://ext.dcloud.net.cn/plugin?id=2481