案例源碼:
Zodiac_cards: 鴻蒙生肖抽獎卡片
效果演示
初始布局
1. Badge 角標組件
此處為語雀內容卡片,點擊鏈接查看:https://www.yuque.com/kevin-nzthp/lvl039/rccg0o4pkp3v6nua
2. Grid 布局
// 定義接口
interface ImageCount {url: ResourceStr,count: number
}@Entry@Componentstruct Index {@State images: ImageCount[] = [{ url: '/images/bg_00.png', count: 0 },{ url: '/images/bg_01.png', count: 1 },{ url: '/images/bg_02.png', count: 2 },{ url: '/images/bg_03.png', count: 3 },{ url: '/images/bg_04.png', count: 4 },{ url: '/images/bg_05.png', count: 5 },]// 控制遮罩的顯隱@State maskOpacity: number = 0 // 透明度@State maskIndex: number = -1; // 顯示層級// 控制圖片的縮放@State maskImgX: number = 0 // 水平縮放比@State maskImgY: number = 0 // 垂直縮放比build() {Stack() {Column() {Grid() {ForEach(this.images, (item: ImageCount) => {GridItem() {Badge({count: item.count,position: BadgePosition.RightTop,style: {badgeSize: this.maskImgX,fontSize: this.maskImgY}}) {Image(item.url).width(80)}}})}.rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr 1fr').width('100%').height(300).margin({ top: 100 })Button('立即抽卡').width(200).backgroundColor('#ed5b8c').margin({ top: 50 }).onClick(()=>{// 點擊時,修改遮罩參數,讓遮罩顯示this.maskOpacity = 1this.maskIndex = 99// 圖片需要縮放this.maskImgX = 1this.maskImgY = 1})}.width('100%').height('100%').backgroundColor(Color.Pink)// 抽卡遮蓋層Column({space: 30}) {Text('獲得生肖卡').fontColor('#f5ebcf').fontSize(25).fontWeight(FontWeight.Bold)Image('/images/img_00.png').width(200)//控制元素的縮放.scale({x: this.maskImgX,y: this.maskImgY})Button('開心收下').width(200).height(50).backgroundColor(Color.Transparent).border({ width: 2 ,color:'#fff9e0'}).onClick(()=>{// 控制彈層顯隱this.maskOpacity = 0this.maskIndex = -1// 重置縮放比為0,便于下一次進行縮放this.maskImgX = 0this.maskImgY = 0})}.justifyContent(FlexAlign.Center).width('100%').height('100%').backgroundColor('#cc000000')// 設置透明度.opacity(this.maskOpacity).zIndex(this.maskIndex)// 動畫 animation 當我們元素有狀態的改變,可以添加animation做動畫.animation({duration: 500})}}}
抽卡遮罩層
靜態頁面
點擊立即抽卡按鈕后,會進入遮罩層,顯示抽取的卡片,此時抽卡的頁面轉換為背景圖,使用層疊布局
// 定義圖片接口
interface ImageCount {url: ResourceStr,count: number
}@Entry@Componentstruct Index {// 定義圖片渲染數組@State images: ImageCount[] = [{ url: '/images/bg_00.png', count: 0 },{ url: '/images/bg_01.png', count: 1 },{ url: '/images/bg_02.png', count: 2 },{ url: '/images/bg_03.png', count: 3 },{ url: '/images/bg_04.png', count: 4 },{ url: '/images/bg_05.png', count: 5 },]build() {Stack(){Column() {Grid() {ForEach(this.images, (item: ImageCount) => {GridItem() {Badge({count: item.count,position: BadgePosition.RightTop,style: {fontSize: 12,badgeSize: 16}}) {Image(item.url).width(80)}}})}.rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr 1fr').height(300).margin({top: 50, bottom: 50})// .backgroundColor(Color.Pink)Button('立即抽卡').width(200).backgroundColor('#ED5B8C')}Column({space: 30}){Text('獲得生肖卡').fontColor('#F3EAD3').fontWeight(700).fontSize(24)Image('/images/img_00.png').width(200)Button('開心收下').width(200).border({width: 2,color:'#9F9C90',}).backgroundColor(Color.Transparent)}.backgroundColor('#cc000000').width('100%').height('100%').justifyContent(FlexAlign.Center)}}}
抽卡遮罩層- 顯隱效果控制
添加狀態變量控制遮罩層 Z 軸 和 不透明度的數值.
當點擊 “立即抽卡”按鈕時,顯示遮罩層。(此時不能隱藏)
當點擊 遮罩層“開心收下”按鈕時,隱藏遮罩層。
添加動畫
添加遮罩層圖片的縮放
效果
// 定義圖片接口
interface ImageCount {url: ResourceStr,count: number
}@Entry@Componentstruct Index {// 定義圖片渲染數組@State images: ImageCount[] = [{ url: '/images/bg_00.png', count: 0 },{ url: '/images/bg_01.png', count: 1 },{ url: '/images/bg_02.png', count: 2 },{ url: '/images/bg_03.png', count: 3 },{ url: '/images/bg_04.png', count: 4 },{ url: '/images/bg_05.png', count: 5 },]// 控制遮罩的顯隱@State maskOpacity: number = 0 // 透明度@State maskIndex: number = -1; // 顯示層級// 控制遮罩層圖片的縮放@State maskImgScaleX: number = 0 // 水平縮放比@State maskImgScaleY: number = 0 // 垂直縮放比// 獲取圖片build() {Stack() {// 抽卡層Column() {Grid() {ForEach(this.images, (item: ImageCount) => {GridItem() {Badge({count: item.count,position: BadgePosition.RightTop,style: {fontSize: 12,badgeSize: 16}}) {Image(item.url).width(80)}}})}.rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr 1fr').height(300).margin({ top: 50, bottom: 50 })// .backgroundColor(Color.Pink)Button('立即抽卡').width(200).backgroundColor('#ED5B8C').onClick(() => {// 點擊時,修改遮罩參數,讓遮罩顯示this.maskOpacity = 1this.maskIndex = 99// 點擊時修改遮罩層圖片的縮放比this.maskImgScaleX = 1this.maskImgScaleY = 1})}// 遮罩層Column({ space: 30 }) {Text('獲得生肖卡').fontColor('#F3EAD3').fontWeight(700).fontSize(24)Image('/images/img_00.png').width(200).scale({//控制圖片的縮放x: this.maskImgScaleX,y: this.maskImgScaleY}).animation({// 動畫duration: 500})Button('開心收下').width(200).border({width: 2,color: '#9F9C90',}).backgroundColor(Color.Transparent).onClick(() => {// 點擊時,修改遮罩參數,讓遮罩隱藏this.maskOpacity = 0this.maskIndex = -1// // 點擊時修改遮罩層圖片的縮放比為1:1this.maskImgScaleX = 0this.maskImgScaleY = 0})}.zIndex(this.maskIndex).opacity(this.maskOpacity).backgroundColor('#cc000000').width('100%').height('100%').justifyContent(FlexAlign.Center)}}}
隨機卡片
效果演示:
要獲得 0-5 的整數索引,隨機抽取卡片
此時可以獲取隨機卡片,接下來要將抽到的隨機卡片顯示在主頁面并右上角角標顯示。
// 定義圖片接口
interface ImageCount {url: ResourceStr,count: number
}@Entry@Componentstruct Index {// 定義圖片渲染數組@State images: ImageCount[] = [{ url: '/images/bg_00.png', count: 0 },{ url: '/images/bg_01.png', count: 0 },{ url: '/images/bg_02.png', count: 0 },{ url: '/images/bg_03.png', count: 0 },{ url: '/images/bg_04.png', count: 0 },{ url: '/images/bg_05.png', count: 0 },]// 控制遮罩的顯隱@State maskOpacity: number = 0 // 透明度@State maskIndex: number = -1; // 顯示層級// 控制遮罩層圖片的縮放@State maskImgScaleX: number = 0 // 水平縮放比@State maskImgScaleY: number = 0 // 垂直縮放比// 獲取遮罩層選擇的圖片Index@State maskImgIndex: number = 0build() {Stack() {// 抽卡層Column() {Grid() {ForEach(this.images, (item: ImageCount) => {GridItem() {Badge({count: item.count,position: BadgePosition.RightTop,style: {fontSize: 12,badgeSize: 16}}) {Image(item.url).width(80)}}})}.rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr 1fr').height(300).margin({ top: 50, bottom: 50 })// .backgroundColor(Color.Pink)Button('立即抽卡').width(200).backgroundColor('#ED5B8C').onClick(() => {// 點擊時,修改遮罩參數,讓遮罩顯示this.maskOpacity = 1this.maskIndex = 99// 點擊時修改遮罩層圖片的縮放比this.maskImgScaleX = 1this.maskImgScaleY = 1// // 隨機獲取圖片的Indexthis.maskImgIndex = Math.floor(Math.random() * 6)})}// 遮罩層Column({ space: 30 }) {Text('獲得生肖卡').fontColor('#F3EAD3').fontWeight(700).fontSize(24)Image(`/images/img_0${this.maskImgIndex}.png`).width(200).scale({//控制圖片的縮放x: this.maskImgScaleX,y: this.maskImgScaleY}).animation({// 動畫duration: 500})Button('開心收下').width(200).border({width: 2,color: '#9F9C90',}).backgroundColor(Color.Transparent).onClick(() => {// 點擊時,修改遮罩參數,讓遮罩隱藏this.maskOpacity = 0this.maskIndex = -1// // 點擊時修改遮罩層圖片的縮放比為1:1this.maskImgScaleX = 0this.maskImgScaleY = 0// 開心收下this.images[this.maskImgIndex] = {url: `/images/img_0${this.maskImgIndex}.png`,count: this.images[this.maskImgIndex].count + 1}})}.zIndex(this.maskIndex).opacity(this.maskOpacity).backgroundColor('#cc000000').width('100%').height('100%').justifyContent(FlexAlign.Center)}}
}
抽大獎遮罩層
靜態頁面
// 定義圖片接口
interface ImageCount {url: ResourceStr,count: number
}@Entry
@Component
struct Index {// 定義圖片渲染數組@State images: ImageCount[] = [{ url: '/images/bg_00.png', count: 0 },{ url: '/images/bg_01.png', count: 0 },{ url: '/images/bg_02.png', count: 0 },{ url: '/images/bg_03.png', count: 0 },{ url: '/images/bg_04.png', count: 0 },{ url: '/images/bg_05.png', count: 0 },]// 控制遮罩的顯隱@State maskOpacity: number = 0 // 透明度@State maskIndex: number = -1; // 顯示層級// 控制遮罩層圖片的縮放@State maskImgScaleX: number = 0 // 水平縮放比@State maskImgScaleY: number = 0 // 垂直縮放比// 獲取遮罩層選擇的圖片Index@State maskImgIndex: number = 0build() {Stack() {// 抽卡層Column() {Grid() {ForEach(this.images, (item: ImageCount) => {GridItem() {Badge({count: item.count,position: BadgePosition.RightTop,style: {fontSize: 12,badgeSize: 16}}) {Image(item.url).width(80)}}})}.rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr 1fr').height(300).margin({ top: 50, bottom: 50 })// .backgroundColor(Color.Pink)Button('立即抽卡').width(200).backgroundColor('#ED5B8C').onClick(() => {// 點擊時,修改遮罩參數,讓遮罩顯示this.maskOpacity = 1this.maskIndex = 99// 點擊時修改遮罩層圖片的縮放比this.maskImgScaleX = 1this.maskImgScaleY = 1// // 隨機獲取圖片的Indexthis.maskImgIndex = Math.floor(Math.random() * 6)})}// 遮罩層Column({ space: 30 }) {Text('獲得生肖卡').fontColor('#F3EAD3').fontWeight(700).fontSize(24)Image(`/images/img_0${this.maskImgIndex}.png`).width(200).scale({//控制圖片的縮放x: this.maskImgScaleX,y: this.maskImgScaleY}).animation({// 動畫duration: 500})Button('開心收下').width(200).border({width: 2,color: '#9F9C90',}).backgroundColor(Color.Transparent).onClick(() => {// 點擊時,修改遮罩參數,讓遮罩隱藏this.maskOpacity = 0this.maskIndex = -1// // 點擊時修改遮罩層圖片的縮放比為1:1this.maskImgScaleX = 0this.maskImgScaleY = 0// 開心收下this.images[this.maskImgIndex] = {url: `/images/img_0${this.maskImgIndex}.png`,count: this.images[this.maskImgIndex].count + 1}})}.zIndex(this.maskIndex).opacity(this.maskOpacity).backgroundColor('#cc000000').width('100%').height('100%').justifyContent(FlexAlign.Center)// 抽大獎遮罩層Column({space: 30}) {Text('恭喜獲得手機一部').fontColor('#E4DDC7').fontWeight(700).fontSize(25)Image('/images/hw.png').width(300)Button('再來一次').width(200).height(50).border({width: 2,color: '#E4DDC7'}).backgroundColor(Color.Transparent)}.justifyContent(FlexAlign.Center).width('100%').height('100%').backgroundColor('#cc000000')}}
}
抽大獎遮罩層的顯隱
前提:
六張卡片集齊,顯示 --- 中大獎頁面
默認為 false,不顯示此抽大獎遮罩層
判斷數組項的count, 是否都大于0, 只能有一個等于0,就意味著沒及其
最終效果演示
隨機獎品 & 再來一次
獎品隨機抽 -》準備一個獎品數組, Math
再來一次 -》重置數據
獎品隨機抽
準備獎品數組,默認抽中的獎品為空
準備隨機數
在“”開心收下“”按鈕下,判斷是否中獎,如果中獎了,準備抽獎。
效果:
再來一次
將數據重置
效果演示:
完整代碼:
import { trustedAppService } from '@kit.DeviceSecurityKit';// 定義圖片接口
interface ImageCount {url: ResourceStr,count: number
}@Entry@Componentstruct Index {// 定義圖片渲染數組@State images: ImageCount[] = [{ url: '/images/bg_00.png', count: 0 },{ url: '/images/bg_01.png', count: 0 },{ url: '/images/bg_02.png', count: 0 },{ url: '/images/bg_03.png', count: 0 },{ url: '/images/bg_04.png', count: 0 },{ url: '/images/bg_05.png', count: 0 },]// 獎品池@State prizePool: string[] = ['/images/pg.png','/images/hw.png','/images/xm.png']//抽中的獎品@State prize: string = '' // 默認沒中獎// 控制遮罩的顯隱@State maskOpacity: number = 0 // 透明度@State maskIndex: number = -1; // 顯示層級// 控制遮罩層圖片的縮放@State maskImgScaleX: number = 0 // 水平縮放比@State maskImgScaleY: number = 0 // 垂直縮放比// 獲取遮罩層選擇的圖片Index@State maskImgIndex: number = 0// 控制中大獎的顯隱@State isGet: boolean = false // 中大獎顯隱build() {Stack() {// 抽卡層Column() {Grid() {ForEach(this.images, (item: ImageCount) => {GridItem() {Badge({count: item.count,position: BadgePosition.RightTop,style: {fontSize: 12,badgeSize: 16}}) {Image(item.url).width(80)}}})}.rowsTemplate('1fr 1fr').columnsTemplate('1fr 1fr 1fr').height(300).margin({ top: 50, bottom: 50 })// .backgroundColor(Color.Pink)Button('立即抽卡').width(200).backgroundColor('#ED5B8C').onClick(() => {// 點擊時,修改遮罩參數,讓遮罩顯示this.maskOpacity = 1this.maskIndex = 99// 點擊時修改遮罩層圖片的縮放比this.maskImgScaleX = 1this.maskImgScaleY = 1// // 隨機獲取圖片的Indexthis.maskImgIndex = Math.floor(Math.random() * 6)})}// 遮罩層Column({ space: 30 }) {Text('獲得生肖卡').fontColor('#F3EAD3').fontWeight(700).fontSize(24)Image(`/images/img_0${this.maskImgIndex}.png`).width(200).scale({//控制圖片的縮放x: this.maskImgScaleX,y: this.maskImgScaleY}).animation({// 動畫duration: 500})Button('開心收下').width(200).border({width: 2,color: '#9F9C90',}).backgroundColor(Color.Transparent).onClick(() => {// 點擊時,修改遮罩參數,讓遮罩隱藏this.maskOpacity = 0this.maskIndex = -1// // 點擊時修改遮罩層圖片的縮放比為1:1this.maskImgScaleX = 0this.maskImgScaleY = 0// 開心收下this.images[this.maskImgIndex] = {url: `/images/img_0${this.maskImgIndex}.png`,count: this.images[this.maskImgIndex].count + 1}// 每次收完,要進行簡單檢索,判斷是否集齊// 需求:判斷數組項的count, 是否都大于0, 只能有一個等于0,就意味著沒及其let flag: boolean = true // 假設集齊// 驗證是否集齊for (let item of this.images) {if (item.count === 0) {flag = false // 沒集齊break; // 只要沒集齊,便可退出循環}}this.isGet = flagif (flag) {let randIndex: number = Math.floor(Math.random() * 3)this.prize = this.prizePool[randIndex]}})}.zIndex(this.maskIndex).opacity(this.maskOpacity).backgroundColor('#cc000000').width('100%').height('100%').justifyContent(FlexAlign.Center)// 抽大獎遮罩層if (this.isGet) {Column({ space: 30 }) {Text('恭喜獲得手機一部').fontColor('#E4DDC7').fontWeight(700).fontSize(25)Image(this.prize).width(300)Button('再來一次').width(200).height(50).border({width: 2,color: '#E4DDC7'}).backgroundColor(Color.Transparent).onClick(() => {this.isGet = falsethis.prize = ''this.images = [{ url: '/images/bg_00.png', count: 0 },{ url: '/images/bg_01.png', count: 0 },{ url: '/images/bg_02.png', count: 0 },{ url: '/images/bg_03.png', count: 0 },{ url: '/images/bg_04.png', count: 0 },{ url: '/images/bg_05.png', count: 0 },]})}.justifyContent(FlexAlign.Center).width('100%').height('100%').backgroundColor('#cc000000')}}}
}