ArkUI抽卡页面

前言

UI方面:整体为Stack布局,里面的布局方面是多种多样的,组件使用了Badge组件把人物包起来,这样就可以实现角标的效果,此外还使用了动画animation属性方法,使得当顶层页面跳出时更加顺滑
TS方面:使用随机数(Math.random)方法来实现随机抽卡的逻辑,然后集齐所有的卡即可兑换神卡,如果有想玩黑神话悟空的bro,祝你们玩的开心,因为我的电脑带不动,只能等换电脑再玩了
这个案例也是跟着黑马敲的

效果

页面能看即可doge
在这里插入图片描述
在这里插入图片描述

代码

interface ImageCount {
  url: string
  count: number
  name: string
}

//遮掩层显隐,opacity 0-1,层级index -1-99
//图片缩放 scale 0-1
@Entry
@Component
struct stringDemo {
  @State images: ImageCount[] = [
    { url: 'app.media.zfb_mine', count: 0, name: '孙悟空' },
    { url: 'app.media.zfb_mine', count: 0, name: '猪八戒' },
    { url: 'app.media.zfb_mine', count: 0, name: '沙僧' },
    { url: 'app.media.zfb_mine', count: 0, name: '白龙马' },
    { url: 'app.media.zfb_mine', count: 0, name: '二郎神' },
    { url: 'app.media.zfb_mine', count: 0, name: '如来佛祖' }
  ]
  //控制遮掩层的透明度和显示优先级
  @State maskOpacity: number = 0
  @State maskZIndex: number = -1
  //控制图片的X轴和Y轴的缩放比例
  @State maskImageX: number = 0
  @State maskImageY: number = 0
  //生成随机数下标
  @State randomIndex: number = 1
  //控制中大奖的显影
  @State isGet: boolean = false

  build() {
    Stack() {
      //初始化网格布局
      Column() {
        Grid() {
          ForEach(this.images, (item: ImageCount, index) => {
            GridItem() {
              Column() {
                Badge({
                  count: item.count,
                  position: BadgePosition.RightTop, //角标位置
                  style: {
                    fontSize: 14,
                    badgeSize: 20,
                    badgeColor: '#FA2A2D'
                  }
                }) {
                  Image($r(item.url))
                    .height(80)
                    .width(80)
                }

                Text(item.name)
                  .width(60)
                  .margin({ top: 5 })
                  .textAlign(TextAlign.Center)
              }
            }

          })
        }
        .columnsTemplate('1fr 1fr 1fr')
        .rowsTemplate('1fr 1fr')
        .width('100%')
        .height(300)
        .margin({ top: 100 })

        Button('抽卡')
          .width(200)
          .backgroundColor('#eb5b8c')
          .margin(50)
          .onClick(() => {
            //点击时,改变遮掩层的opacity和zindex
            this.maskOpacity = 1
            this.maskZIndex = 99
            //图片缩放
            this.maskImageX = 1
            this.maskImageY = 1
            //计算随机数,选择要抽到的卡
            this.randomIndex = Math.floor(Math.random() * 6)

          })
      }
      .width('100%')
      .height('100%')
      .backgroundColor(Color.Pink)

      //抽卡遮掩图
      Column() {
        Text('抽中了')
          .fontColor('#f5ebcf')
          .fontSize(25)
          .fontWeight(FontWeight.Bold)

        Image($r(this.images[0].url))
          .width(200)
          .fillColor(Color.White)//控制图片的缩放
          .scale({
            x: this.maskImageX, y: this.maskImageY
          })
          .animation({
            duration: 100
          })
        Text(this.images[this.randomIndex].name)
          .width(60)
          .textAlign(TextAlign.Center)
          .fontColor('#fff9e0')
        Button('就选你了')
          .width(200)
          .height(50)
          .backgroundColor(Color.Transparent)
          .border({ width: 2, color: '#fff9e0' })
          .margin({ top: 10 })
          .onClick(() => {
            this.maskOpacity = 0
            this.maskZIndex = -1
            //重置缩放
            this.maskImageX = 0
            this.maskImageY = 0
            //右红标加一,如果是对象数组需要更新,需要修改替换整个对象
            // this.images[this.randomIndex].count++
            this.images[this.randomIndex] = {
              url: this.images[this.randomIndex].url,
              count: this.images[this.randomIndex].count + 1,
              name: this.images[this.randomIndex].name
            }
            //每次收卡,都要判断
            let flag: boolean = true
            for (let item of this.images) {
              if (item.count == 0) {
                flag = false
                break
              }
            }
            this.isGet = flag
          })
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#cc000000')
      .justifyContent(FlexAlign.Center)
      .opacity(this.maskOpacity)
      .zIndex(this.maskZIndex)
      //动画
      .animation({
        duration: 100
      })

      if (this.isGet) {
        //抽大奖的遮掩层
        Column({ space: 30 }) {
          Text('迎接你们的王')
            .fontColor('#f5ebcf')
            .fontSize(25)
            .fontWeight(700)
          Image($r(this.images[0].url))
            .fillColor(Color.White)
            .width(300)
          Text(`神·${this.images[0].name}`)
            .fontColor('#f5ebcf')
            .fontSize(25)
            .fontWeight(700)
          Button('继续抽奖')
            .width(200)
            .height(50)
            .backgroundColor(Color.Transparent)
            .border({ width: 2, color: '#fff9e0' })
            .onClick(() => {
              this.isGet = false
              this.images = [{ url: 'app.media.zfb_mine', count: 0, name: '孙海军' },
                { url: 'app.media.zfb_mine', count: 0, name: '潘玉鹏' },
                { url: 'app.media.zfb_mine', count: 0, name: '张子隆' },
                { url: 'app.media.zfb_mine', count: 0, name: '鲁玉' },
                { url: 'app.media.zfb_mine', count: 0, name: '变祁隆' },
                { url: 'app.media.zfb_mine', count: 0, name: '曹远征' }]
            })
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#cc000000')
        .justifyContent(FlexAlign.Center)
        .animation({
          duration: 200
        })
      }
    }
  }
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值