微信小程序抽奖-翻牌

背景

ps:本次开发基于wepy框架css

因为最近接到一个需求--抽奖活动;html

翻牌打乱活动抽奖活动,大概需求是这样的,九宫格卡牌,先正面展现全部奖品,而后卡牌翻转,打乱排序,点击卡牌,而后抽奖。css3

这个需求自己其实不难,主要是分为三步;git

  • 展现全部卡牌,而后翻转。
  • 打乱全部卡牌
  • 点击其中一张卡牌,抽奖

第一步:卡牌翻转

咱们先在dom中渲染9个卡牌。github

<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属性可能须要大部补充学习一下api

css3 backface-visibility 属性

定义和用法数组

backface-visibility 属性定义当元素不面向屏幕时是否可见。

若是在旋转元素不但愿看到其背面时,该属性颇有用。

CSS3 perspective 属性

perspective 属性定义 3D 元素距视图的距离,以像素计。该属性容许您改变 3D 元素查看 3D 元素的视图。

当为元素定义 perspective 属性时,其子元素会得到透视效果,而不是元素自己。

第二步:卡牌打乱

因为业务上是抽奖使用的,因此选择的方案是:翻转后,卡牌收回到中间的卡牌中间,而后再让卡牌回到原来的位置。

关于小程序的原生框架有支持的动画接口,若不了解的请前往: developers.weixin.qq.com/miniprogram…

在对动画有基本了解以后,咱们能够开始在翻转的基础上加上打乱的动画了 微信小程序的动画接口使用方式是在dom对象上面加上animation对象。

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()
},
复制代码

算法后面须要优化,咱们先完成功能效果,

效果以下

第三步:卡牌翻转

dom代码

<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>
复制代码

script代码
data中定义一个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}
    })
}
复制代码

在位移动画中使用二维布局的差值进行位移

// 洗牌
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()
},
复制代码

这样整个动画就算完成了, demo请前往github github.com/fishmankkk/…

相关文章
相关标签/搜索