preface

This article encapsulated a similar to the digging lottery large rotary table components, first to see the effect (😂 uniform speed is too fast, resulting in a screen capture… You can change the speed in the configuration item if you want to experience it.)

function

This component features:

  • Refresh to generate random prizes, unlimited
  • New gameplay, comprehensive upgrade! 100% winning rate, 200 diamonds can not buy a loss can not buy deceived, but can take home the prize! 😀
  • Random acceleration, deceleration
  • Of course, the prize is also can be customized, when using the designated prize picture can 😂
  • Based on VUE, other dependencies that contain only one element are self-substitutable

Open to

Use case

/** * @param {Object} pics - a set of objects to import * @example {gift1: () => import(" ")} * @param {Object} options - big disk configuration item * @param {Object} giftName - the name of the pics image corresponding to the giftName, because the picture is only the English name of the gift. * @example {gift1: "Yoyo pillow "} maps the file name of the picture to the name of the gift, $message * @param {number} targetIndex - the location of the prize * @param {Object} positionIndex - The mapping of rotation order rules, default clockwise, Details can be found in the component code configuration comments * @param {func} clickLottery - Click the callback for the lottery button * @param {func} complete - The callback for the end of the turntable run * @returns {} */ <LuckGame :pics="pics" :options="options" :giftName="giftName" :targetIndex="targetIndex" @clickLottery="fetchGiftInfo" @complete="showGift" > </LuckGame>Copy the code

About component source code

Single file component.vue

First talk about the general implementation idea: declare a timer, in the running process has always existed, when accelerating, uniform speed, deceleration only change is the timer time (here is the speed this.optionData.speed, this value is smaller, trigger timer frequency faster, faster; This timer implementation is to repeatedly switch the position of the active element, to achieve the effect of the large wheel “scroll”), everything else is around this.

<! <div class="clearfix flex luck-game"> <div :class="[' luck-unit luck-unit-${i-1} ']" v-for=" I of 9" :key="i" ref="gifts"> <template v-if="i === 5"> <div @click="lottery" class="lottery"> <slot name="btn"> <p Class = "num" > 200 diamond/time < / p > < p class = "tit" > draw < / p > < div class = "img" > < / div > < / slot > < / div > < / template > < / div > < / div > </template> <script> export default { data() { return { optionData: this.options }; }, props: { pics: { type: Object, require: true }, options: { type: Object, require: true }, targetIndex: { type: [Number, null] }, giftName: { type: Object}, /* DOM rotation order 0, 1, 2 0, 1, 2 3, 4, 5 8, 4, 3 6, 7, 8 7, 8 7, 6, 5 */ // Default clockwise rotation rule positionIndex: {type: Object, default() { return { 3: 5, 5: 8, 6: 7, 7: 6, 8: 3 }; } } }, computed: { count() { return this.$refs.gifts.length; }, gifts() { return this.$refs.gifts; }, index() { return this.optionData.index % this.count; } }, mounted() { this.optionData.speed = this.optionData.initSpeed; this.initGiftPic(); this.setActiveDom(this.getIndex(this.optionData.index)); {if}, the methods: {lottery () (this) optionData) set) {this. $message. Warning (" is struggling to get gift for you, please later 😀 "); return; } this.$emit("clickLottery"); this.roll(); }, roll() { let activeDom = this.getActiveDom(); activeDom.classList.remove("active"); ++this.optionData.index; // Skip the middle button if (this.index === 4) {++this.optionData.index; ActiveDom = this.gift.find ((gift) => activeDom = this.gift.find (gift) => gift.classList.contains(`luckunit-${this.getIndex(this.index)}`)); activeDom.classList.add("active"); this.timer = setTimeout(() => { this.roll(); }, this.optionData.speed); // The smaller the speed value, the shorter the timer trigger time, so the faster the speed, control the speed of rotation if (! this.optionData.isRunning) { let timing = this.getRandomTime(this.optionData.upTimer); this.speedUp(timing); this.optionData.isRunning = true; } }, speedUp(timing) { let upTimer; if (this.optionData.speed >= this.optionData.upMax) { upTimer = setTimeout(() => { this.optionData.speed -= this.optionData.upStep; this.speedUp(timing); }, timing); } else { this.speedConstant(); clearTimeout(upTimer); }}, speedConstant() { let constantTimer = setTimeout(() => { let timing = this.getRandomTime(this.optionData.downTimer); this.speedDown(timing); clearTimeout(constantTimer); }, this.optionData.constantTiming); }, speedDown(timing) { let downTimer; if (this.optionData.speed >= this.optionData.downMax && this.targetIndex === this.index) { this.stop(); clearTimeout(downTimer); } else { downTimer = setTimeout(() => { this.optionData.speed += this.optionData.downStep; this.speedDown(timing); }, timing); }}, stop() {this.getActivedom ().title} '; clearTimeout(this.timer); this.$emit("complete", this.getActiveDom()); this.optionData.isRunning = false; }, getRandomTime(timing) {return (math.random () * 4 + 0.4) * timing; }, InitGiftPic () {this.gift.foreach ((giftBox) => {// Set random gift const random = math.ceil (math.random () * Object.keys(this.pics).length); If (giftbox.children. Length === 0) {let giftIndex = 'gift${random}'; let url = this.pics[giftIndex]; giftBox.style.backgroundImage = `url('${url}')`; giftBox.title = this.giftName[giftIndex]; }}); }, getActiveDom() { return this.gifts.find((gift) => gift.classList.contains("active")); }, setActiveDom(index) { this.gifts[index] && this.gifts[index].classList.add("active"); }, getIndex(index) { return this.positionIndex[index] || index; }}}; </script> <style lang="less" scoped> @import url("./index.less"); </style>Copy the code

Less style file

The only image file introduced here is the intermediate BTN file, which can be imported by itself

.luck-game {
    width: 486px;
    height: 478px;
    margin: auto;
    background: skyblue;
    flex-wrap: wrap;
    .luck-unit {
        float: left;
        flex-basis: 33.33%;
        height: 33.33%;
        border-radius: 16px;
        background-size: 50%;
        background-repeat: no-repeat;
        background-position: center;
        animation: all 0.3 s;
        &.active {
            background-color: rgba(255.204.149.0.5);
            &.luck-unit {
                background-size: 58%; }}&.luck-unit-4 {
            background-image: url("~@src/img/common/juejin.svg");
            background-size: contain;
            background-position: center center;
            background-repeat: no-repeat;
            background-size: 92%;
            color: #3e0b08;
            font-weight: 700;
            position: relative;
            cursor: pointer;
            display: flex;
            flex-direction: column;
            justify-content: center;
            .lottery {
                display: flex;
                flex-direction: column;
                justify-content: center;
            }
            .num..tit {
                z-index: 3;
                text-align: center;
                // color: #fff;
            }
            .tit {
                text-shadow: 1px 1px 10px 0px rgba(49.27.17.0.72);
                font-size: 37px;
            }
            .img {
                position: absolute;
                z-index: 2;
                background-image: url("~@src/img/common/juejin.svg");
                background-size: contain;
                background-position: center center;
                background-repeat: no-repeat;
                // top\ and background-position-y are negatives of each other
                top: 0px;
                background-position-y: -0px;
                height: 100%;
                width: 100%;
                transition: all 0.3 s;
            }
            &:hover .img {
                background-image: url("~@src/img/common/juejin.svg");
                background-size: contain;
                background-position: center center;
                background-repeat: no-repeat; }}}}Copy the code

conclusion

Simple big turntable small game on the package, here to provide only ideas oh, there must be a better way to achieve, of course, we can also develop to adapt to their own business 😄