Лотерея апплетов WeChat — провал

внешний интерфейс алгоритм Апплет WeChat анимация

задний план

ps: эта разработка основана на фреймворке wepy

В связи с недавним спросом - лотерея;

Флоп и скремблирование лотерейной деятельности, вероятно, спрос такой, карта сетки из девяти квадратов, сначала отобразите все призы спереди, затем переверните карту, перетасуйте порядок, нажмите на карту, а затем разыграйте лотерею.

Само по себе это требование несложное, в основном оно делится на три этапа;

  • Откройте все карты и переверните их.
  • Перемешайте все карты
  • Нажмите на одну из карточек, чтобы разыграть лотерею

Шаг 1: Переверните карту

Сначала рендерим 9 карт в доме.

<view class="card-module">
  <view class="card {{showClass ? 'change' : ''}}>
    <view class="front card-item">{{cardItem.front}}</view>
    <view class="back card-item">{{cardItem.back}}</view>
  </view>
  </repeat>
</view>

Генерация смоделированных данных карты в данных

cardData: [
    {
      animationData: {},
      front: '正面1',
      back: '反面1'
    },
    ...
    ...
    {
      animationData: {},
      front: '正面9',
      back: '反面9'
    }
  ],
  showClass: false,

Визуализировать базовый стиль карты в стиле

.card-module{
  padding: 45rpx;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  transform:translate3d(0,0,0);
  .card{
    width: 200rpx;
    height: 200rpx;
    line-height: 200rpx;
    text-align: center;
    color: #fff;
    margin: 10rpx;
    position:relative;
    overflow:hidden;
    .card-item{
      position:absolute;
      left:0;
      top:0;
      width:100%;
      height:100%;
      transition:all .5s ease-in-out;
      transform-style:preserve-3d;
      backface-visibility:hidden;
      box-sizing:border-box;
    }
    .front{
      background-color: red;
      transform: rotateY(0deg);
      z-index:2;
    }
    .back{
      background-color: #009fff;
      transform: rotateY(180deg);
      z-index:1;
    }
  }
  .card.change{
    .front{
      z-index:1;
      transform: rotateY(180deg);
    }
    .back{
      z-index:2;
	    transform: rotateY(0deg);
    }
  }
}

Эффект следующий

Некоторые свойства CSS здесь, возможно, потребуется дополнить большей частью исследования.

свойство css3 backface-visibility

Определение и использование

Свойство backface-visibility определяет, виден ли элемент, когда он не обращен к экрану.

Это свойство полезно, если вы не хотите видеть обратную сторону элемента при его вращении.

Свойство перспективы CSS3

Свойство перспективы определяет расстояние в пикселях от 3D-элемента до вида. Это свойство позволяет изменить представление 3D-элемента 3D-элемента.

Когда свойство перспективы определено для элемента, его дочерние элементы получают эффект перспективы, а не сам элемент.

Шаг 2: Перетасовка карт

Так как она используется для лотереи в бизнесе, выбранное решение: после переворачивания карта убирается в середину средней карты, а затем карта возвращается в исходное положение.

Родной фреймворк апплета поддерживает анимационные интерфейсы. Если вы этого не знаете, перейдите по ссылке:Developers.WeChat.QQ.com/mini программа…

После базового понимания анимации мы можем начать добавлять зашифрованные анимации поверх флипов. Интерфейс анимации апплета WeChat используется путем добавления объекта анимации к объекту dom.

dom

<view class="card-module">
  <view class="card {{showClass ? 'change' : ''}} animation="{{cardItem.animationData}}" >
    <view class="front card-item">{{cardItem.front}}</view>
    <view class="back card-item">{{cardItem.back}}</view>
  </view>
  </repeat>
</view>

script

allMove () {
    // 110 是卡牌宽度加边距
    this.methods.shuffle.call(this, 110)
    let timer = setTimeout(() => {
      clearTimeout(timer)
      this.methods.shuffle.call(this, 0)
      this.$apply()
    }, 1000)
},
// 洗牌
shuffle (translateUnit) {
    let curCardData = this.cardData
    curCardData.map((item, index) => {
      let animation = wepy.createAnimation({
        duration: 500,
        timingFunction: 'ease'
      })
      animation.export()
      switch (index) {
        case 0:
          animation.translate(translateUnit, translateUnit).step()
          break
        case 1:
          animation.translate(0, translateUnit).step()
          break
        case 2:
          animation.translate(-translateUnit, translateUnit).step()
          break
        case 3:
          animation.translate(translateUnit, 0).step()
          break
        case 4:
          animation.translate(0, 0).step()
          break
        case 5:
          animation.translate(-translateUnit, 0).step()
          break
        case 6:
          animation.translate(translateUnit, -translateUnit).step()
          break
        case 7:
          animation.translate(0, -translateUnit).step()
          break
        case 8:
          animation.translate(-translateUnit, -translateUnit).step()
          break
      }
      item.animationData = animation.export()
    })
    this.cardData = curCardData
    this.$apply()
},

Алгоритм нужно оптимизировать позже, сначала доделываем функцию эффект,

Эффект следующий

Шаг 3: Переверните карту

код дома

<view class="card-module">
  <view class="card {{showClass ? 'change' : ''}}  {{curIndex === index ? 'getprize' : ''}}" @tap="itemChage({{cardItem}}, {{index}})" animation="{{cardItem.animationData}}" >
    <view class="front card-item">{{cardItem.front}}</view>
    <view class="back card-item">{{cardItem.back}}</view>
  </view>
  </repeat>
</view>

код скрипта
Определите объект с curIndex = -1 в данных

data = {
      curOpen: -1,
      }
methods = {
    // 抽奖
      itemChage (item, curIndex) {
        this.cardData[curIndex].front = 'iphone x'
        console.log(item, curIndex)
        this.curOpen = curIndex
      }
}

less

.card.getprize{
    .front{
      z-index:2;
      transform: rotateY(0deg);
    }
    .back{
      z-index:1;
	    transform: rotateY(180deg);
    }
  }

Эффект следующий

Теперь мы выполнили основные требования, но код слишком уродлив, чтобы писать его во время анимации смещения.
Давайте подумаем, как оптимизировать алгоритм;

Теперь мы находимся на макете сетки из девяти квадратов, мы можем рассматривать его как двухмерный макет.

Итак, можем ли мы также использовать атрибут макета двумерного массива в карточке?

resetData () {
    const total = 9 // 总数
    const lineTotal = 3 // 单行数
    curCardData.map((item, index) => {
      let curCardData = this.cardData
      let x = index % lineTotal
      let y = parseInt(index / lineTotal)
      item.twoArry = {x, y}
    })
}

Смещение с использованием дельта-значений 2D-макета в анимации смещения

// 洗牌
shuffle (translateUnit) {
    let curCardData = this.cardData
    curCardData.map((item, index) => {
      let animation = wepy.createAnimation({
        duration: 500,
        timingFunction: 'ease'
      })
      animation.export()
      const translateUnitX = translateUnit * (1 - item.twoArry.x)
      const translateUnitY = translateUnit * (1 - item.twoArry.y)
      animation.translate(translateUnitX, translateUnitY).step()
      item.animationData = animation.export()
    })
    this.cardData = curCardData
    this.$apply()
},

Даже если вся анимация завершена, Пожалуйста, перейдите на github для демонстрацииGithub.com/fish rols kk / ...