Reference juejin. Cn/post / 696131…

Other activities achieved:

Collection of energy: vue.js to achieve the receipt of energy red envelope rain: vue.js to achieve red envelope rain vue.js to achieve rotation lottery: vue.js to achieve rotation lottery

For a quick copy of the results, look at heading 2

1. Understand transition and transform.Transition requires an event to be triggered

The 1transform is a transition from state A to state B, so it has to be triggered by an event. It can’t happen automatically when the page loads. 2Transform is a transform that changes the appearance of the element. For example, displacement, scaling, rotation, etc., and the displacement function name is translate, so translate is part of transform. Transform is not animated, you change its value, the element changes immediately

When I wanted to see the 360 degree rotation effect, I found the browser and showed it directly

 <div id="test"></div>
 #test {
  width: 100px;
  height: 100px;
  background-color: red;
  transition: transform 5s ease-in-out 0s;
  transform:  rotate(360deg);
}
Copy the code

The display effect is:

So we should change it to:

  <div id="test"></div>
  <div onclick="test()">Click on the</div>
  <style>
    #test {
      width: 100px;
      height: 100px;
      background-color: red;
    }
    .test {
      transition: transform 5s ease-in-out 0s;
      transform:  rotate(360deg);
    }
  </style>
</head>
<body>
  <script>
    function test() {
      document.getElementById('test').className = 'test'
    }
  </script>
Copy the code

2. Realize the lottery of static rotary table

 data() {
    return {
      rotateAngle: 0.// Rotate the Angle
      config: {
        duration: 3000.// Total rotation time ms level
        circle: 7.// The number of turns
        mode: 'ease-in-out'.// The inertia effect from fast to slow is reduced
      },
      drawIndex: 0.// Lottery index dial picture sort pointer right hand start 0-... 0 to 5
      juneInfoStatusObj: {
        residueCount: 0.// The number of remaining lucky draws
      },
      run: false.// If it is rotating
      rewardMaskVisible: false.// The winning frame
      rewardList: [].}},async mounted() {
    this.$loading.show()
    try {
      await this.getActivity21StJuneInfo()
    } finally {
      this.$loading.hide()
    } 
  },
   methods: {
    // Basic information
    async getActivity21StJuneInfo() {
      const data = awaitXXXXXXX interface (this.token)
      const { residueCount = 0 } = data
      this.juneInfoStatusObj = { residueCount } // First get the number of lucky draw, the code has been deleted, if you only need to draw once can be removed
    },
    // Click the wheel to get the specified item
    async getActivity21StJuneLottery() {
      const { reward } = awaitThe interface XXXX of what prize should be won (this.token)
      this.rewardList = [ reward ] // The backend returns what prize did the user win
      this.drawIndex = reward.id // The backend directly returns the user which prize to win
    },
    // Start to rotate
    async startPlay() {
      if (!this.checkToken()) return // If you do not need to log in, you can delete it
      if (+this.rotateAngle > 0) {
        this.$toast('Please do not double click while drawing')
        return 
      }
      if (+this.juneInfoStatusObj.residueCount === 0) {
        this.$toast('Operation reached upper limit')
        return
      }
      await this.getActivity21StJuneLottery()
      this.run = true
      this.rotateAngle = this.config.circle * 360 - (30 + this.drawIndex * 60)}},Copy the code

this.rotateAngle = this.config.circle * 360 – (30 + this.drawIndex * 60) The most important thing to understand is to make sure that the pointer of the lottery is pointing straight at the middle line and not biased towards any module, so if there are 6 areas, each area will be 360/6=60 degrees. If you look clockwise, the first area will be index = 0. The second field corresponds to index = 1….. The sixth field is index= 5, and if the back end returns index=4, it points to the fifth field. The number of turns in the config object can be discussed with the product, and the number of turns *360 is the number of turns

Index =5, index=4,index… Index =0 through the pointer in order, if the index=0 returned by the back end, i.e., in the middle of the rotation close to 360 degrees,360-30, this.config.circle * 360- (30 + this.drawindex * 60), Remember, if the hands are not moving and the dial is moving, what is the regional rotation path of the dial

The above can complete the operation of the turntable from turn to stop, if you need to turn after, and the number of rotation, you can add the following code

 // Close the dialog box
    setData(dialogName, handle) {
       this.run = false
       this.rotateAngle = 0  
       this.rewardMaskVisible = false
    },
    // Wait n seconds to play again
    sleep(time){
      return new Promise(function(resolve){
        setTimeout(resolve, time)
      })
    },
    // When the rotation is complete, pop up the frame
    async finishRotate() {
      await this.sleep(1000)
      this.rewardDetailVisible = true
    },
    
Copy the code

FinishRotate actually has a transitionEnd listening event when the rotation is complete

<img
  :style="` ${! run ? '' : rotateStyle}`"
  class="turntable-img"
  src="@/assets/image/juneTurntable/turntable-center.png"
  @transitionend="finishRotate"
>
Copy the code

3. First move, click and then draw, and then move the way of drawing

Previously, our lucky draw button was static, so it might not be able to attract users to remove it visually. Therefore, we changed the clicking of the lucky draw button into a dynamic one, and let the rotary wheel slowly turn in

I have considered two methods. The first one is to use animation: Rotate 15s Linear Infinite to do perpetual motion first, and then rotate with 0 when clicked, which will have a reset effect on the page. Therefore, the second one is to use timer to do perpetual motion

this.rotateAngle = 0
await this.sleep(0)
this.rotateAngle = this.config.circle * 360 - (30 + this.drawIndex * 60)
Copy the code
Code (add or modify above)
 <img
  :style="`${normalRotateStyle} ${! run ? '' : rotateStyle}`"
  :class="['turntable-img', {'normal': normalTranstion}]"
  src="@/assets/image/juneTurntable/turntable-center.png"
  @transitionend="finishRotate"
> 
.turntable-img {
    width: 524px;
    height: 524px;
    &.normal{
      transition: transform 1slinear; }}Copy the code
data() {
    return {
      normalRotateAngle: 0.normalTranstion: true,}},computed: {
    rotateStyle () {
      const config = this.config
      console.log(this.rotateAngle, 78979)
      return `
        -webkit-transition: transform ${config.duration}ms ${config.mode};
        transition: transform ${config.duration}ms ${config.mode};
        -webkit-transform: rotate(The ${this.rotateAngle}deg);
            transform: rotate(The ${this.rotateAngle}deg); `
    },
    normalRotateStyle () {
      return `transform: rotate(The ${this.normalRotateAngle}deg); `}},async mounted() {
    this.$loading.show()
    try {
      await this.getActivity21StJuneInfo()
    } finally {
      this.$loading.hide()
    } 
    this.initNormalRotate()
},
methods: {
    initNormalRotate () {
      this.t = setInterval(() = > {
        this.normalRotateAngle += 10
        this.normalTranstion = true
      }, 500)},// Start to rotate
   async startPlay() {
      if (!this.checkToken()) return // If you do not need to log in, you can delete it
      if (+this.rotateAngle > 0) {
        this.$toast('Please do not double click while drawing')
        return 
      }
      if (+this.juneInfoStatusObj.residueCount === 0) {
        this.$toast('Operation reached upper limit')
        return
      }
      await this.getActivity21StJuneLottery()
      clearInterval(this.t)
      this.normalTranstion = false
      this.run = true
      this.rotateAngle = this.config.circle * 360 - (30 + this.drawIndex * 60)},// Modify the data function in general
    setData(dialogName, handle) {
        this.run = false
       this.rotateAngle = 0  
       this.rewardMaskVisible = false
       this.initNormalRotate()
       this.getActivity21StJuneInfo()
     },
     // When the rotation is complete, pop up the frame
    async finishRotate() {
      if (!this.run) {
        return
      }
      await this.sleep(1000)
      this.rewardDetailVisible = true
      this.run = false
      this.normalRotateAngle = 0
      this.rotateAngle = 0}},Copy the code