How to implement a small program version of the slot machine

How to implement a small program version of the slot machine

Operation: We recently need to recruit new users and do a simpler activity, just in the form of slot machines.
Product: The slot machine is relatively simple, so many online demos can be copied and copied.
Development: Come, come, you do it.

To the point:

There are many plug-ins for online slot machines, and the implementation principles are also different. Then here is the principle that I thought of when I was doing the slot machine lottery:

Focus on it:
The background-position property of css is to set the starting position of the background image, then we control the background image to display different positions within 0-3 seconds, plus the transition animation to achieve the effect of slot machine rotation

In the first version of this vue version facie effect of the video (second version) video gif turn more than a dozen trillion, up here a little card. Just upload the video. Video effect This version stops and then pops up at a fixed time of 4 seconds, which is quite abrupt. The pop-up window is displayed after the bottom of the slot machine is not scrolled to stop.

Today I m going to talk about the third solution (the pop-up window will be displayed after the bottom scrolling stops and it is consistent with the winning code returned from the backend).

WXML
<view class="box-container">
  <view class="box-tips">{{boxTips}}</view>
  <view class="wheel-boxs">
    <view class="box-list" wx:for="{{boxStatus}}" wx:key="index">
      <view class="box-text" wx:if="{{!isStart}}">{{item}}</view>
      <view class="box-image" style="background: url('https://qiniu-image.qtshe.com/20181113wheels.png'); background-position-y: {{isStart ? ((16 - item) * 100) + 1500 + 'rpx' : 0}}; background-size: 100% 100%; transition-property: {{isStart ? 'all' : 'none'}}; transition-delay: {{(index + 1) * 100 + 'ms'}}; transition-duration: 3.5s;">
     </view>
     {{item}}
    </view>
    </view>
  <view class="start-box">
   <form bindsubmit="startDraw" report-submit="true" wx:if="{{pageVo.remainCount !== 0}}">
       <button class="start-draw" formType="submit"/>
   </form>
  </view>
  <view class="last-tips">  <text>{{pageVo.remainCount || 0}}</text>  </view>
</view>
 
WXSS
.box-container {
  width: 680rpx;
  height: 380rpx;
  background: url(https://qiniu-image.qtshe.com/20190227goddess_02.png) no-repeat center center;
  background-size: 100% 100%;
  position: relative;
  z-index: 10;
  margin: auto;
  overflow: hidden;
}    
.wheel-boxs {
  width: 680rpx;
  padding: 0 80rpx;
  margin-top: 16rpx;
}    
.box-list {
  width: 90rpx;
  height: 100rpx;
  background: url(https://qiniu-image.qtshe.com/20190227goddess_11.png) no-repeat center center;
  background-size: 100% 100%;
  display: inline-block;
  margin-right: 16rpx;
  overflow: hidden;
}    
.box-list:last-child {
  margin-right: 0;
}    
.box-tips {
  width: 500rpx;
  height: 54rpx;
  background: url(https://qiniu-image.qtshe.com/20190227goddess_10.png) no-repeat center center;
  overflow: hidden;
  background-size: 100% 100%;
  margin: 20rpx auto;
  color: #000;
  font-size: 24rpx;
  text-align: center;
  line-height: 54rpx;
  margin-top: 36rpx;
}    
.box-text {
  width: 100%;
  height: 100rpx;
  line-height: 100rpx;
  text-align: center;
  font-size: 44rpx;
  color: #f8294a;
  font-weight: 600;
}    
.box-image {
  height: 1500%;
}    
.start-box {
  width: 100%;
  text-align: center;
  margin: 16rpx 0 8rpx;
}    
.start-box button {
  width: 290rpx;
  height: 76rpx;
  background: url(https://qiniu-image.qtshe.com/20190227startDraw.png) no-repeat center center;
  background-size: 290rpx 76rpx;
  margin: 0 auto;
}
.start-box .start-draw {
  width: 290rpx;
  height: 76rpx;
  background: url(https://qiniu-image.qtshe.com/20190227startDraw.png) no-repeat center center;
  background-size: 290rpx 76rpx;
  margin: 0 auto;
}
 
JS
const app = getApp()
Page({
  data: {
    isStart: false,//
    isDialog: false,//
    dialogId: 1,//
    boxTips: ' 3 8  19:00 ',//
    typeTips: '3 8 20 ',
    boxStatus: [' ', ' ', ' ', ' ', ' '],//
    results: [],//
  },
  onLoad() {
      this.initData()
  },
 //
  handleModel() {
    this.setData({
      isDialog: !this.data.isDialog
    })
  },
  onShow() {},
 //
  initData() {
    let postData = {
      url: 'xxx'
    }
    app.ajax(postData).then((res) => {
      if (res.success) {
        this.setData({
          pageVo: res.data //
        })
      } else {
        util.toast( res.msg || ' ')
      }
    }, () => {
      wx.hideLoading()
      util.toast( ' ')
    })
  },
 //FormId  
  addFormId(e) {
    if (e.detail.formId !== 'the formId is a mock one') {//
      let formData = {
        url: 'xxx',
        data: {
          formId: e.detail.formId,
          openId: wx.getStorageSync('openId') || ''
        }
      }
      app.ajax(formData)
    }
  },
 //
  startDraw(e) {
 //
    this.addFormId(e) //formId
    let postData = {
      url: 'xxx'
    }
    app.ajax(postData).then((res) => {
      if (res.success) {
        this.setData({
          isStart: true,
          results: res.data.result.split(','),//[1,2,3,4,5]
          dialogId: res.data.special ? 3 : 2 //3 2 
        })
      } else {
        util.toast(res.msg || ' ')
      }
    }, () => {
      wx.hideLoading()
      util.toast( ' ')
    })
  },   
  onShareAppMessage() {
    return {
      title: ' 10 ',
      path: '/activity/xxx/xxx',
      imageUrl: 'https://qiniu-image.qtshe.com/20190227goddess-share.png'
    }
  }
})
 

The final complete implementation effect is here: click me to view the complete video effect

Pay attention to two points:

  • The rotating background image is a Sprite image. What I use here is this picture for reference

  • To control the displacement unit of the graph, you need to calculate it so that the value returned by the backend can match your graph. I have 15 icons here, so the calculation method is as follows

    <view class="box-image" style="
       background: url('https://qiniu-image.qtshe.com/20181113wheels.png'); 
       background-position-y: {{isStart ? ((16 - item) * 100) + 1500 + 'rpx' : 0}}; 
       background-size: 100% 100%; 
       transition-property: {{isStart ? 'all' : 'none'}}; 
       transition-delay: {{(index + 1) * 100 + 'ms'}}; 
       transition-duration: 3.5s;">
    </view>
     

Here you can encapsulate it into a custom component, just pass in the picture and the quantity. If I use it later, I will encapsulate it and send it out.

Finally, the matching method of the picture displayed in the pop-up window is calculated based on the picture size, which is more troublesome:

WXML
 <view class="ci-wrapper">
    <view wx:if="{{icontype ==='nomal'}}" class="icon-default  icon-nomal" style=" 
  	  background-position-y: {{(-24 -  117.86 * (typeId - 1)) + 'rpx'}};">
    </view>
    <view wx:else class="icon-default  icon-fade" style=" 
    	background-position-y: {{(-20 - 110.73 * (typeId - 1)) + 'rpx'}}; ">
    </view>
 </view>
 
WXSS
.icon-default {
   width: 70rpx;
   height: 70rpx;
   background-repeat: no-repeat;  
 }
 .icon-nomal {
   background-image: url(https://qiniu-image.qtshe.com/20181113wheels.png);
   background-position-x: -17rpx;
    background-size: 100rpx 1768rpx
 }
 .icon-fade {
   background-image: url(https://qiniu-image.qtshe.com/20181113wheels_fade.png);
   background-size: 110rpx 1661rpx;
   background-position-x: -18rpx;
 }
 
JS
Component({
    properties: {
      icontype: {
        type: String,
        value: "nomal"
      },
      iconid: {
        type: Number,
        value: 1,
        observer(newVal, oldVal) {
          this.setData({ typeId: newVal });
        }
      }
    },
    data: {
      nomalOrigin: {
         x: -17,
         y: -24
      },
      fadeOrigin: {
        x: -17,
        y: -24
      },
      typeId: 1
    }
  })
 

As for the place of reference, just do it like this (resultList is an array of winning numbers):

<code-icon wx:for="{{resultList}}" icontype="nomal" iconid="{{item}}" wx:key="{{index}}"></code-icon>
 

The above is a slot machine implementation scheme of a complete small program, you can point out any optimization points.

Finally, I wrote a code snippet: developers.weixin.qq.com/s/1k5eSnmh7...

At last

A wave of recruitment:

Recruitment position: front-end architect/technical leader Job description:

1. Build tools, refine components, abstract frameworks, promote front-end engineering and service, continue to improve R&D efficiency, and ensure online product quality 2. Build infrastructure such as H5/PC applications, mini programs, and lead the construction of efficiency tool platforms and guide Implement solution 3. Continue to optimize front-end page performance, maintain front-end code specifications, study various cutting-edge technologies and innovative interactions, enhance user experience, and open up front-end capabilities. 4. Have a clear plan for the technical project responsible for at least 1 year, and Set key target nodes

Job requirements: 1. At least 3 years of first-line Internet front-end development experience 2. In-depth research in front-end performance optimization 3. In-depth insights and practices in front-end componentization, modularization, and engineering 4. Node.js product development Experience, familiar with server-side development technology 5. Strong communication skills, strong sense of responsibility, strong thinking logic 6. Experience in github projects is preferred, please attach github or personal blog address

Recruitment position: Senior front-end development engineer Job description:

1. Responsible for the design and development of important front-end modules (PC, mobile, small programs) 2. Research and explore innovative development ideas and front-end technologies, optimize front-end frameworks and design plans, and improve front-end development and delivery efficiency. 3. On the basis of understanding product business, improve product user experience, and technology drives business development. 4. Organize theme sharing regularly, activate the technical atmosphere, and drive the team members to improve their technical capabilities

Description of qualifications and requirements 1. Have a certain understanding of MVC/MVMM, at least proficient in one or more front-end frameworks (React, Vue, etc.) 2. Clear code structure, solid JavaScript foundation, proficient in any front-end MV* framework , Such as Vue, React, etc. 3. Familiar with the HTTP protocol, familiar with the performance optimization, monitoring and analysis methods of web applications 4. Strong communication skills, strong sense of responsibility, strong thinking logic

Recruitment position: Senior front-end development engineer Job description:

1. Complete the front-end page code according to product requirements and design to achieve interactive effects. 2. Cooperate with back-end engineers to complete data interaction and dynamic information display. 3. Maintain and optimize the execution performance and loading performance of the front-end page of the website. Optimize front-end code specifications. 4. Ability Effectively solve actual development problems, maintain good communication with back-end technology development, quickly understand and digest the needs of all parties, and implement them into specific development work

Job Requirements:

1. Familiar with html5/css3 layout, have certain aesthetic ability and observation ability, can quickly and accurately restore design drafts (PS/Sketch), have mobile project development experience 2. Clear code structure, solid javascript foundation, familiar with whatever A front-end MV* framework, such as vueJS, reactJS, etc. 3. Have in-depth insights and practices in front-end componentization, modularization, and engineering 4. Familiar with the basic usage of front-end construction tools (webpack, gulp, grunt) 5. Familiar with CSS Processing LESS/SASS, etc. 6. Those with github project experience is preferred, please attach github or personal blog address