zoukankan      html  css  js  c++  java
  • 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
                },
                 {
                    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
                },
                 {
                    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
                },
                 {
                    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 {
             40%;
            height: 80rpx;
            line-height: 80rpx;
            text-align: center;
            border-radius: 10rpx;
            margin: 30rpx 30%;
            position: relative;
        }
    
        .box {
             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;
             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;
             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
                },
                 {
                    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}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-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;
             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;
             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;
             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;
             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
                },
                 {
                    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}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}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;
             inherit;
            height: inherit;
            border-radius: 50%;
        }
    
        .cs-list {
            position: absolute;
            left: 0;
            top: 0;
             inherit;
            height: inherit;
            z-index: 9999;
        }
    
        .cs-item {
            position: absolute;
            left: 0;
            top: 0;
             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 {
             60upx;
            height: 60upx;
            
            border-radius: 50%;
        }
    
        /* 分隔线 */
        .cs-line {
            position: absolute;
            left: 0;
            top: 0;
             inherit;
            height: inherit;
            z-index: 99;
        }
    
        .cs-litem {
            position: absolute;
            
            top: 0;
             3upx;
            
            overflow: hidden;
            
        }
    
        /**  
    * 抽奖按钮  
    */
        .cs-btn {
            position: absolute;
            background-color: #e44025;
            z-index: 400;
             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;
             0;
            height: 0;
            overflow: hidden;
            border- 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 {
            
             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+'rpx', height : height+'rpx'}">
    
                    <view class="blow" v-if="is_show" :style="{ 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+'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
                },
                 {
                    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,
                         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 {
                 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;
             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+'rpx', height : height+'rpx'}" >
                    <view style="position: absolute;" v-if="is_show">
                    
                        <view>
                            <image :style="{ width+'rpx', height : height+'rpx'}"  :src="result_img"></image>
                        </view>
                    
                    </view>
                    <canvas style="position: absolute;" :style="{ 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
                },
                 {
                    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,
                         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;
             100%;
        }
    </style>

    刮自定义

    <template>
        <view >
            <view  :id="canvasId" class="box">
                <view  :style="{ width+'rpx', height : height+'rpx'}" >
                    <slot></slot>
                    <canvas style="position: absolute;" :style="{ 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
                },
                 {
                    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,
                         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;
             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;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;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 {
                 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;
             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

  • 相关阅读:
    next_permutation
    P1087 FBI树
    P4047 [JSOI2010]部落划分
    买礼物
    P2121 拆地毯
    Nebula Graph 在大规模数据量级下的实践和定制化开发
    深入了解kafka系列-消费者
    一分钟教你搭建WebRTC流媒体服务器Janus-gateway
    什么是"前端工程化"?
    斗鱼Juno 监控中心的设计与实现
  • 原文地址:https://www.cnblogs.com/2186009311CFF/p/14435558.html
Copyright © 2011-2022 走看看