Project premise

Chinese New Year is coming soon. If you want to change your mobile phone, it will be huawei in addition to fruit. I’m a hammer fan. Unfortunately, hammer is out of business. At the bottom of huawei official website event page, there is a turntable lottery function, which is quite interesting (damn the front-end professional faults), think of the mobile phone does not buy always bring something to go, at the same time, I haven’t written a native JS for a long time, so I want to implement this thing simply (without considering packaging). This is not a case for big men.

Pictured above,

Train of thought to sort out

1. DOM structure

    <div id="allParent">
      <! -- Click Start/Back -->
      <div class="selectBox">
        <div class="parent">
          <div class="start"></div>
          <div class="back">
            <img
              src="https://res7.vmallres.com/shopdc/pic/9c9af0eb-4c3d-4053-ae33-fd5f3fe90492.png"
              alt=""
            />
          </div>
        </div>
      </div>
    </div>
Copy the code

2. Flip effect 3D

Start by adding perspective properties to the outermost layer

    #allParent .item .parent {
        width: 100%;
        height: 100%;
        transform-style: preserve-3d; // Child perspectiveperspective-origin: center; 
        perspective: 500px; // Perspective distanceposition: relative;
      }
Copy the code

Prize and click flip are two pictures together, by default, click flip to rotate first.

     #allParent .item .parent .back{
        position: absolute;
        height: 100%;
        transition: all .6s;
        transform: rotateY(270deg); / / turn first270The degree ofborder-radius: 9px;
        opacity: 0;
      }

Copy the code

3. JS effect

The core code calculates the offset of each award relative to the center position.

Basic idea:

   function initPosition() { // Calculate the position
     var gapW = (allParentWidth - boxWidth * 3) / 4.// The width of the space
       gapH = (allParentHeight - boxHeight * 3) / 2; // Height space distance
     for (var i = 0; i < itemDoms.length; i++) {
       var pos = {};
       if (i < 3) {
         / / the first column
         pos.y = -(gapH + boxHeight); // all Y is the height of the box + the distance of the space
         pos.x = (i - 1) * (boxWidth + gapW);
       } else if (i == 3 || i == 4) {
         / / the second column
         if (i == 3) {
           pos.x = -(boxWidth + gapW);
         } else {
           pos.x = boxWidth + gapW;
         }
         pos.y = 0;
       } else {
         / / the third column
         pos.y = gapH + boxHeight;
         pos.x = (((i + 1) % 3) - 1) * (boxWidth + gapW);// The x offset of the third row} boxsPositions.push(pos); }}Copy the code

All the code

Can copy directly run

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <title>Document</title>
    <style>
      * {
        padding: 0;
        margin: 0;
        box-sizing: border-box;
      }

      #allParent {
        width: 716px;
        height: 508px;
        margin: 0 auto;
        position: relative;
        background: radial-gradient(# 000000a6, # 00000026);
        padding: 10px 0;
        box-sizing: content-box;
      }

      .selectBox {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 144px;
        height: 144px;
        z-index: 99
      }

      .selectBox > div > div {
        width: 144px;
        height: 144px;
      }

      .selectBox .start {
        background: url(https://res0.vmallres.com/shopdc/pic/7848e6d2-8420-410e-893d-fbd3b9ac1e78.png)
          no-repeat center center/ cover;
      }
      .selectBox .back {
        display: none;
      }

      .selectBox .back img {
        width: 100%;
        height: 100%;
        border: 0 none;
        vertical-align: top;
      }

      #allParent .item {
        width: 220px;
        height: 160px;
        position: absolute;
        left: 50%;
        top: 50%;
        margin-left: -110px;
        margin-top: -80px;
        z-index: 10;
      }

      #allParent .item .parent {
        width: 100%;
        height: 100%;
        transform-style: preserve-3d;
        perspective-origin: center;
        perspective: 500px;
        position: relative;
      }

      #allParent .item .parent .face {
        transition: all .6s;
        width: 100%;
        height: 100%;
        position: absolute;
        background-color: rgba(248.113.13.0.1);
        transform: rotateY(0deg);
        border: none;
        backface-visibility: hidden;
        
      }
      #allParent .item .parent.active .face{
         transform:rotateY(180deg);
         opacity: 0;
      }

      #allParent .item .parent .back{
        position: absolute;
        height: 100%;
        transition: all .6s;
        transform: rotateY(270deg);border-radius: 9px;
        opacity: 0;
      }

      #allParent .item .parent.active .back{
        transform: rotateY(360deg);opacity: 1;
      }

    </style>
  </head>
  <body>
    <div id="allParent">
      <! -- Click Start/Back -->
      <div class="selectBox">
        <div class="parent">
          <div class="start"></div>
          <div class="back">
            <img
              src="https://res7.vmallres.com/shopdc/pic/9c9af0eb-4c3d-4053-ae33-fd5f3fe90492.png"
              alt=""
            />
          </div>
        </div>
      </div>
    </div>
  </body>
  <script src="https://res9.vmallres.com/shopdcGray/shopdc/cdn/modules/common/pc/js/jquery-3.5.0.min.js"></script>
  <script>
    var data = [
      {
        img:
          "https://res6.vmallres.com/shopdc/pic/20201231/0924a81c-feff-4686-a4ca-b90913d51d5d.png"}, {img:
          "https://res5.vmallres.com/shopdc/pic/a38461b2-8317-4a66-877a-ee3d1ed8ea27.png"}, {img:
          "https://res0.vmallres.com/shopdc/pic/20201231/c8214cf6-778a-4dc9-a068-bc91622f3e24.png"}, {img:
          "https://res6.vmallres.com/shopdc/pic/20201231/0924a81c-feff-4686-a4ca-b90913d51d5d.png"}, {img:
          "https://res5.vmallres.com/shopdc/pic/a38461b2-8317-4a66-877a-ee3d1ed8ea27.png"}, {img:
          "https://res0.vmallres.com/shopdc/pic/20201231/c8214cf6-778a-4dc9-a068-bc91622f3e24.png"}, {img:
          "https://res2.vmallres.com/shopdcGray/shopdc/pic/f19ce100-4afc-439e-bc90-5b92e4755c07.png"}, {img:
          "https://res6.vmallres.com/shopdc/pic/20201231/0924a81c-feff-4686-a4ca-b90913d51d5d.png",},];var $allParent = $("#allParent"),
      $selectBox = $(".selectBox"),
      $start = $(".start"),
      $back = $(".back")

    var allParentWidth = $allParent.width(),
      allParentHeight = $allParent.height();
    var boxHeight = 160,
      boxWidth = 220;
    var itemDoms = [],
      boxsPositions = [];
    var isFirst = true;

    function init() {
      // Initialize the event

      $selectBox.on("click".".start".function () {

         if(isFirst){
            
            itemDoms.forEach(function(dom){
                dom.find(".parent").addClass("active")})setTimeout(function(){
                for (var i = 0; i < boxsPositions.length; i++) {
                        itemDoms[i].get(0).style.transition = 0.6 s ` ` all
                        itemDoms[i].css({
                        transform: `translate3d(0px, 0px, 0px)`
                        });
                }
                setTimeout(function(){
                    initPricePosition()
                },600)},700)}else{

            itemDoms.forEach(function(dom){
                dom.find(".parent").addClass("active")
            })

         }

         $start.hide();
         $back.show()

         isFirst = false;
         
      });

      $selectBox.on("click".".back".function(){
            
              
            itemDoms.forEach(function(dom){
                dom.find(".parent").removeClass("active")
            })

            $start.show();
            $back.hide()
      })

    }

    function initDom() { // Initialize the DOM
      for (var i = 0; i < data.length; i++) {
        var html = $(`<div class="item i${i + 1}">
                            <div class="parent">
                                <div class="face" style='background: url("${ data[i].img }") center center / 100% 100% no-repeat; '> </div> <div class="back"> <img src="https://res0.vmallres.com/shopdc/pic/193f6450-5327-444e-a610-88125afb4ba7.png" style="width: 100%; height: 100%"> </div> </div> </div>`); itemDoms.push(html); $selectBox.before(html); }}function initPosition() { // Calculate the position
      var gapW = (allParentWidth - boxWidth * 3) / 4.// The width of the space
          gapH = (allParentHeight - boxHeight * 3) / 2; // Height space distance
      for (var i = 0; i < itemDoms.length; i++) {
        var pos = {};
        if (i < 3) {
          / / the first column
          pos.y = -(gapH + boxHeight);
          pos.x = (i - 1) * (boxWidth + gapW);
        } else if (i == 3 || i == 4) {
          / / the second column
          if (i == 3) {
            pos.x = -(boxWidth + gapW);
          } else {
            pos.x = boxWidth + gapW;
          }
          pos.y = 0;
        } else {
          / / the third column
          pos.y = gapH + boxHeight;
          pos.x = (((i + 1) % 3) - 1) * (boxWidth + gapW);
        }
        boxsPositions.push(pos);
      }
      // re-assign itemDoms to transform
    }

    function initPricePosition() { // Initialize the DOM location
      for (var i = 0; i < boxsPositions.length; i++) {
        itemDoms[i].css({
          transform: `translate3d(${boxsPositions[i].x}px, ${boxsPositions[i].y}px, 0px)`}); } } init() initDom();/ / initialization
    initPosition();
    initPricePosition();

  </script>
</html>

Copy the code

conclusion

Small DEMO, for practice CSS3+DOM operations, suitable for just entered the front novice. Welcome friends to pay attention to a wave, we learn together! On the way to the gods.