ソースを参照

upd: countup 摸拟抽奖

yumingming11 5 年 前
コミット
1e6d991e8b

+ 56 - 47
src/packages/countup/countup.scss

@@ -1,50 +1,59 @@
-.nut-countup{
-    display:inline-block;
-    width: 100%;
-    padding:5px;
-    color: #000;
-	font-weight:bold;
-	// text-align:center;
-    .run-number{
-        margin: 0 auto;
-        padding: 0;
-        overflow: hidden;
-        height: 50px;
-        line-height: 50px;
-        text-align: center;
-        font-weight: bold;
-        position: relative;
-        li {
-            position: absolute;
-            transition: none;
-            // transition: all linear .1s;
-            // animation: myMove 1s linear infinite;
-            // animation-fill-mode: forwards;
-            // @keyframes myMove {
-            //     0% {
-            //       transform: translateY(0);
-            //     }
-            //     100% {
-            //       transform: translateY(-50px);
-            //     }
-            // }
-            span {
-                display: block;
-            }
-        }
-    }
-    .pointstyl {
-        position: absolute;
+.nut-countup {
+  display: inline-block;
+  width: 100%;
+  padding: 5px;
+  color: #000;
+  font-weight: bold;
+  // text-align:center;
+  .run-number {
+    margin: 0 auto;
+    padding: 0;
+    overflow: hidden;
+    height: 50px;
+    line-height: 50px;
+    text-align: center;
+    font-weight: bold;
+    position: relative;
+    li {
+      position: absolute;
+      transition: none;
+      // transition: all linear .1s;
+      // animation: myMove 1s linear infinite;
+      // animation-fill-mode: forwards;
+      // @keyframes myMove {
+      //     0% {
+      //       transform: translateY(0);
+      //     }
+      //     100% {
+      //       transform: translateY(-50px);
+      //     }
+      // }
+      span {
         display: block;
+      }
+    }
+  }
+  .pointstyl {
+    position: absolute;
+    display: block;
+  }
+  .run-number-machine-img {
+    overflow: hidden;
+    li {
+      float: left;
+      background-position: center 0;
+      background-repeat: repeat-y;
+      background-attachment: scroll;
     }
-    .run-number-img {
-        position: relative;
-        li {
-            position: absolute;
-            transition: none;
-            display: inline-block;
-            background-position: 0 0;
-            background-repeat: no-repeat;
-        }
+  }
+  .run-number-img {
+    position: relative;
+    li {
+      position: absolute;
+      transition: none;
+      display: inline-block;
+      background-position: 0 0;
+      background-repeat: no-repeat;
     }
-}
+  }
+}

+ 148 - 65
src/packages/countup/countup.vue

@@ -1,32 +1,52 @@
 <template>
   <div class="nut-countup">
     <template v-if="customBgImg != ''">
-      <ul class="run-number-img" :style="{ height: numHeight + 'px' }">
-        <li
-          class="run-number-img-li"
-          v-for="(val, index) of num_total_len"
-          :key="'cImg' + index"
-          :style="{
-            width: numWidth + 'px',
-            height: numHeight + 'px',
-            left: numWidth * (index > num_total_len - pointNum - 1 ? (index == num_total_len - pointNum ? index * 1.5 : index * 1.3) : index) + 'px',
-            backgroundImage: 'url(' + customBgImg + ')',
-            backgroundPosition: '0 ' + -(String(relNum)[index] * numHeight + customSpacNum * String(relNum)[index]) + 'px',
-            transition: 'all linear ' + during / 10 + 'ms'
-          }"
-        ></li>
-        <div
-          v-if="pointNum > 0"
-          class="pointstyl"
-          :style="{
-            width: numWidth / 2 + 'px',
-            bottom: 0,
-            left: numWidth * (num_total_len - pointNum) * 1.1 + 'px',
-            fontSize: '30px'
-          }"
-          >.</div
-        >
-      </ul>
+      <template v-if="type == 'machine'">
+        <ul class="run-number-machine-img" :style="{ height: numHeight + 'px' }">
+          <li
+            class="run-number-machine-img-li"
+            ref="run-number-machine-img-li"
+            v-for="(val, index) of machineNum"
+            :key="'mImg' + index"
+            :style="{
+              width: numWidth + 'px',
+              height: numHeight + 'px',
+              backgroundImage: 'url(' + customBgImg + ')',
+              backgroundPositionY: prizeY[index] + 'px'
+            }"
+          ></li>
+          <!-- backgroundPositionY: prizeLevelTrun + 'px', -->
+        </ul>
+      </template>
+      <template v-else>
+        <ul class="run-number-img" :style="{ height: numHeight + 'px' }">
+          <li
+            class="run-number-img-li"
+            v-for="(val, index) of num_total_len"
+            :key="'cImg' + index"
+            :style="{
+              width: numWidth + 'px',
+              height: numHeight + 'px',
+              left:
+                numWidth * (index > num_total_len - pointNum - 1 ? (index == num_total_len - pointNum ? index * 1.5 : index * 1.3) : index) + 'px',
+              backgroundImage: 'url(' + customBgImg + ')',
+              backgroundPosition: '0 ' + -(String(relNum)[index] * numHeight + customSpacNum * String(relNum)[index]) + 'px',
+              transition: 'all linear ' + during / 10 + 'ms'
+            }"
+          ></li>
+          <div
+            v-if="pointNum > 0"
+            class="pointstyl"
+            :style="{
+              width: numWidth / 2 + 'px',
+              bottom: 0,
+              left: numWidth * (num_total_len - pointNum) * 1.1 + 'px',
+              fontSize: '30px'
+            }"
+            >.</div
+          >
+        </ul>
+      </template>
     </template>
     <template v-else>
       <ul v-if="scrolling" class="run-number" :style="{ height: numHeight + 'px' }">
@@ -120,6 +140,27 @@ export default {
     customChangeNum: {
       type: Number,
       default: 1
+    },
+    // 抽奖
+    type: {
+      type: String,
+      default: ''
+    },
+    machineNum: {
+      type: Number,
+      default: 3
+    },
+    machinePrizeNum: {
+      type: Number,
+      default: 0
+    },
+    machinePrizeLevel: {
+      type: Number,
+      default: 0
+    },
+    machineTrunMore: {
+      type: Number,
+      default: 0
     }
   },
   data() {
@@ -136,7 +177,12 @@ export default {
       numberVal: 0, //数字
       num_total_len: 0, //数字长度
       relNum: 0, //去除小数点
-      customNumber: 1
+      customNumber: 1,
+      prizeLevelTrun: this.numHeight,
+      prizeY: [],
+      prizeYPrev: [],
+      // machineTransition: 'none',
+      finshMachine: 0
     };
   },
   computed: {},
@@ -144,12 +190,17 @@ export default {
     customChangeNum: function(n, o) {
       this.customNumber = n;
       this.countGo();
+    },
+    machinePrizeLevel: function(n, o) {
+      this.prizeLevelTrun = n;
     }
   },
   mounted() {
     if (this.startFlag) {
       if (this.scrolling || this.customBgImg) {
-        this.countGo();
+        if (this.type != 'machine') {
+          this.countGo();
+        }
       } else {
         this.countChange();
       }
@@ -228,6 +279,7 @@ export default {
         // this.endNum = this.endNum.toFixed(this.toFixed);
       }
       let { initNum, endNum, toFixed, customBgImg } = this;
+
       if (customBgImg) {
         initNum = this.customNumber;
       }
@@ -394,43 +446,74 @@ export default {
           }, that.during);
         });
       });
-
-      // that.timer = setInterval(() => {
-      //     that.relNum = that.calculation(that.relNum, Math.floor(Math.random() * (20 - 4 + 1) + 4), '+');;
-      // }, that.during)
-      // let that = this;
-      // that.clearInterval();
-      // var m = 1;
-      // if(that.pointNum!=0){
-      //     m = (Math.pow(10,that.pointNum));
-      // }
-      // that.timer = setInterval(() => {
-      // if(that.sortFlag == 'add') {
-      //     that.relNum = that.calculation(that.relNum, m * that.speed, '+');
-      //     if(that.relNum >= that.endNum*m) {
-      //         that.relNum = that.endNum*m;
-      //         that.clearInterval();
-      //         this.$emit('scroll-end');
-      //     }
-      // }else {
-      //     that.relNum = that.calculation(that.relNum, m * that.speed, '-');
-      //     if(that.relNum <= 0) {
-      //         that.relNum = String(0).repeat(that.num_total_len);
-      //         that.clearInterval();
-      //         this.$emit('scroll-end');
-      //     }
-      // }
-      // that.relNum = that.calculation(that.relNum, m * that.speed, that.sortFlag == 'add'?'+':'-');
-      // if(that.relNum <= 0) {
-      //     that.relNum = String(0).repeat(that.num_total_len);
-      //     that.clearInterval();
-      //     this.$emit('scroll-end');
-      // }
-      // if(that.relNum >= that.endNum*m) {
-      //     that.relNum = that.endNum*m;
-      //     that.clearInterval();
-      // }
-      // }, that.during);
+    },
+    // 抽奖
+    machineLuck() {
+      this.machineTrunMore = this.machineTrunMore < 0 ? 0 : this.machineTrunMore;
+      let distance = this.numHeight * this.machinePrizeNum; // 所有奖品的高度,雪碧图的高度
+      for (let i = 0; i < this.machineNum; i++) {
+        setTimeout(() => {
+          let turn = distance * (i + 1 + parseFloat(this.machineTrunMore));
+          if (this.prizeLevelTrun >= 999) {
+            this.$set(this.prizeY, i, 100 * i);
+          } else {
+            if (this.prizeYPrev.length != 0) {
+              // this.machineTransition = 'none';
+              // console.log(this.prizeYPrev[i]-(this.numHeight * this.machinePrizeNum));
+              this.$set(this.prizeY, i, this.prizeYPrev[i]);
+            }
+          }
+          let local = this.prizeYPrev[i] ? this.prizeYPrev[i] : 0;
+          let newLocation = turn + local + (this.machinePrizeNum - this.prizeLevelTrun + 1) * this.numHeight + (distance - local);
+          this.scrollTime(
+            i,
+            // parseFloat((this.machinePrizeNum-(this.prizeLevelTrun-1))*this.numHeight + turn + local),
+            newLocation,
+            local
+          );
+        }, 500 * i);
+      }
+    },
+    scrollTime(index, total, num) {
+      // this.machineTransition = `all linear ${this.during/this.machinePrizeNum}ms`;
+      let t = setInterval(() => {
+        if (num <= total) {
+          num += 10;
+          this.$set(this.prizeY, index, parseFloat(num));
+        } else {
+          clearInterval(t);
+          t = null;
+          this.finshMachine += 1;
+          this.$set(this.prizeY, index, total);
+          // 动画未完成的时候触发了判断,需要加个延时或者监听最后一个动画执行结束,保证在动画执行结束
+          // this.$nextTick(() => {
+          //     var f = document.getElementsByClassName('run-number-machine-img-li');
+          //     f[f.length-1].addEventListener('webkitTransitionEnd', () => {
+          //         setTimeout(() => {
+          //             if(this.finshMachine == this.machineNum) {
+          //                 this.finshMachine = 0;
+          //             }
+          //         },200)
+          //     });
+          // })
+          if (this.finshMachine == this.machineNum) {
+            let distance = this.numHeight * this.machinePrizeNum;
+            this.prizeYPrev = [];
+            let prevAry = JSON.parse(JSON.stringify(this.prizeY));
+            prevAry.forEach(item => {
+              let n = item;
+              while (n > distance) {
+                n -= distance;
+              }
+              this.prizeYPrev.push(n);
+            });
+            setTimeout(() => {
+              this.finshMachine = 0;
+              this.$emit('scroll-end');
+            }, 130);
+          }
+        }
+      }, 30);
     }
   }
 };

+ 56 - 5
src/packages/countup/demo.vue

@@ -10,23 +10,53 @@
     </div>
     <h4>数字滚动</h4>
     <div class="show-demo">
-      <nut-countup :scrolling="true" :init-num="17.618" :during="600"> </nut-countup>
+      <!-- <nut-countup :scrolling="true" :init-num='17.618' :during="600">
+        </nut-countup> -->
     </div>
     <h4>自定义滚动图片展示</h4>
     <div class="show-demo">
-      <nut-countup :custom-change-num="customNumber" :custom-bg-img="bgImage" :custom-spac-num="11" :num-width="33" :num-height="47" :during="5000">
+      <!-- <nut-countup
+          :custom-change-num="customNumber"
+          :custom-bg-img="bgImage"
+          :custom-spac-num="11"
+          :num-width="33"
+          :num-height="47"
+          :during="5000"
+        >
+        </nut-countup> -->
+    </div>
+    <h4>抽奖(模拟滚动抽奖)</h4>
+    <div class="show-demo">
+      <nut-countup
+        ref="countup-machine"
+        type="machine"
+        :machine-num="machineNum"
+        :machine-prize-num="5"
+        :machine-prize-level="prizeLevel"
+        :custom-bg-img="bgImage2"
+        :num-width="100"
+        :num-height="100"
+        :during="3000"
+        @scroll-end="scrollAniEnd"
+      >
       </nut-countup>
+      <nut-button @click="startRole" :disabled="startFlag">抽奖</nut-button>
+      <!-- <nut-button @click="startRole2" :disabled="startFlag2">抽奖(不中奖)</nut-button> -->
     </div>
   </div>
 </template>
 
 <script>
 export default {
-  components: {},
   data() {
     return {
       customNumber: 618,
-      bgImage: 'https://img10.360buyimg.com/imagetools/jfs/t1/133024/3/2251/2646/5ee7549aE8dc02d7e/de6901b6c72db396.png'
+      bgImage: 'https://img10.360buyimg.com/imagetools/jfs/t1/133024/3/2251/2646/5ee7549aE8dc02d7e/de6901b6c72db396.png',
+      startFlag: false,
+      startFlag2: false,
+      machineNum: 3,
+      bgImage2: 'https://img10.360buyimg.com/imagetools/jfs/t1/121466/20/6784/28830/5f06e7f2Edbb8998c/9bdd9e7b24dff9fe.png',
+      prizeLevel: 0
     };
   },
   methods: {
@@ -35,10 +65,26 @@ export default {
       timer = setInterval(() => {
         this.customNumber = Math.floor(Math.random() * (700 - 100 + 1) + 100);
       }, 5000);
+    },
+    startRole() {
+      this.prizeLevel = Math.floor(Math.random() * 5 + 1);
+      this.startFlag = true;
+      this.$refs['countup-machine'].machineLuck();
+    },
+    startRole2() {
+      this.prizeLevel = 9999;
+      this.startFlag2 = true;
+      this.$refs['countup-machine'].machineLuck();
+    },
+    scrollAniEnd() {
+      this.$toast.text('恭喜中奖!!!');
+      setTimeout(() => {
+        this.startFlag = false;
+      }, 300);
     }
   },
   mounted() {
-    this.run();
+    // this.run();
   }
 };
 </script>
@@ -47,4 +93,9 @@ export default {
 .show-demo {
   background: #ffffff;
 }
+.disabledClick {
+  pointer-events: none !important;
+  cursor: not-allowed !important;
+  opacity: 0.6 !important;
+}
 </style>

+ 44 - 3
src/packages/countup/doc.md

@@ -51,6 +51,42 @@ export default {
 };
 ```
 
+## 抽奖
+
+```html
+<nut-countup
+    type="machine"
+    :custom-change-num="customNumber"
+    :custom-bg-img="bgImage"
+    :custom-spac-num="11"
+    :num-width="33"
+    :num-height="47"
+    :during="5000"
+>
+</nut-countup>
+```
+```javascript
+export default {
+    data() {
+        return {
+            customNumber: 618, 
+            bgImage: 'https://img10.360buyimg.com/imagetools/jfs/t1/133024/3/2251/2646/5ee7549aE8dc02d7e/de6901b6c72db396.png'
+        };
+    },
+    methods: {
+        run() {
+            let timer = null;
+            timer = setInterval(() => {
+                this.customNumber = Math.floor(Math.random() * (700 - 100 + 1) + 100);
+            }, 5000);
+        }
+    },
+    mounted() {
+        this.run();
+    }
+};
+```
+
 
 ## Prop
 
@@ -63,14 +99,19 @@ export default {
 | start-flag | 触发数字滚动的标识 | Boolean | true
 | during | 滚动一次运行时间 | Number | 1000
 | num-width | 数字宽度,常用于自定义无缝滚动 | Number | 20
-| num-height | 数字高度,常用于自定义无缝滚动 | Number | 20
+| num-height | 数字高度,常用于自定义无缝滚动(抽奖功能必传) | Number | 20
 | scrolling | 用于数字滚动展示 | Boolean | false
 | custom | 用于自定义图片数字滚动 | Boolean | false
 | custom-change-num | 要变化的数字(用于自定义图片,initNum\endNum在此无效) | Number | 1
-| custom-bg-img | 自定义图片(建议使用雪碧图实现) | - | -
+| custom-bg-img | 自定义图片(建议使用雪碧图实现,使用抽奖功能必须使用雪碧图) | - | -
 | custom-spac-num | 图片中数字之间可能会存在间距 | Number | 0
+| type | 使用抽奖功能必穿,“machine” | string | ''
+| machine-prize-num | 奖项数,一共多少个奖品,必传 | number | 4
+| machine-num | 抽奖位数,即几个图标,必传 | number | 3
+| machine-prize-level | 中奖图标,图标在雪碧图中的位置 | number | 0
+| machine-trun-more | 后面图标的滚动比前面多滚动次数 | number | 0
 
-
+###### 说明:抽奖功能是根据图标的定位实现,需要传入雪碧图中单个图标的高度 num-height,