基于ArkUI的水波纹动画开发
成果出现
环境要求
本例基于以下环境开发,开发者也可以基于其余适配的版本启动开发:
成功思绪
本实例触及到的重要个性及其成功打算如下:
开发步骤
针对成功思绪中所提到的内容,详细关键开发步骤如下:
先经过Grid,GridItem等容器组件将UI框架搭建起来,在GuidItem中援用步骤2中的自定义数字按钮numBtn构建出数字栅格。
private numGrid: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 0, -1]...Column() {Grid() {ForEach(this.numGrid, (item: number, index: number) => {GridItem() {...}}, item => item)}.columnsTemplate('1fr 1fr 1fr').rowsTemplate('1fr 1fr 1fr 1fr').columnsGap(10).rowsGap(10).width(330).height(440)}.width('100%').height('100%')
经过Column、Button、Stack、Text等关键组件以及visibility属性构建自定义数字按钮numBtn。
@Componentstruct numBtn {···build() {Column() {Button() {stack(){...Text(`${this.item}`).fontSize(30)}...}.backgroundColor('#ccc').type(ButtonType.Circle).borderRadius(100).width(100).height(100)}.visibility(this.item == -1 ? Visibility.Hidden : Visibility.Visible).borderRadius(100)}}
设置形态变量unPressed,监听数字按钮的形态,同时向Column组件减少onTouch事情,失掉并降级按钮的形态,从而可以依据监听到的按钮形态加载对应的动画成果。
//形态变量unPressed,用于监听按钮按下和开放的形态@State unPressed: boolean = true...// 减少onTouch事情,监听形态.onTouch((event: TouchEvent) => {// 当按钮按下时,降级按钮的形态(unPressed:true -> false)if (event.type == TouchType.Down) {animateTo({ duration: }, () => {this.unPressed = !this.unPressedthis.currIndex = this.index})}// 当按钮开放时,降级按钮的形态(unPressed:false -> true)if (event.type == TouchType.Up) {animateTo({ duration: }, () => {this.unPressed = !this.unPressed})}})
依据按钮组件的按下/开放形态,经过if-else语句选择拔出的Row组件,并随之出现不同的水动摇画成果(按下时水波靠拢,开放时水波分散)。
Stack() {Row() {// 判别按钮组件为开放形态if (this.unPressed && this.currIndex == this.index) {// 拔出Row组件,性能过渡成果Row().customStyle().backgroundColor('#fff')// 水波纹分散动画:从Row组件的核心点开局加大,scale{0,0}变卦scale{1,1}(完整显示).transition({type: TransitionType.Insert,opacity: 0,scale: { x: 0, y: 0, centerY: '50%', centerX: '50%' }})}// 判别按钮组件为按下形态else if (!this.unPressed && this.currIndex == this.index) {// 拔出Row组件,性能过渡成果Row().customStyle().backgroundColor(this.btnColor).scale(this.btnScale).onAppear(() => {// 水波纹靠拢动画:Row组件backgroundColor属性变卦(#ccc -> #fff),拔出动画过渡成果,scale{1,1}(完整显示)变动为scale{0,0}animateTo({ duration: 300,// 靠拢动画播放成功后,须要连贯分散动画,Row组件backgroundColor属性变卦(#fff -> #ccc),拔出动画过渡成果,scale{0,0}变动为scale{1,1}(完整显示)onFinish: () => {this.btnColor = '#ccc'this.btnScale = { x: 1, y: 1 }} },() => {this.btnColor = '#fff'this.btnScale = { x: 0, y: 0 }})})}// 其余形态else {Row().customStyle().backgroundColor('#fff')}}.justifyContent(FlexAlign.Center).alignItems(VerticalAlign.Center).borderRadius(100)Text(`${this.item}`).fontSize(30)}.customStyle()
完整代码
@Entry@Componentexport default struct dragFire {private numGrid: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 0, -1]build() {Column() {Grid() {ForEach(this.numGrid, (item: number, index: number) => {GridItem() {numBtn({ item: item, index: index })}}, item => item)}.columnsTemplate('1fr 1fr 1fr').rowsTemplate('1fr 1fr 1fr 1fr').columnsGap(10).rowsGap(10).width(330).height(440)}.width('100%').height('100%')}}@Componentstruct numBtn {private currIndex: number = -1//形态变量unPressed,用于控制按钮的形态@State unPressed: boolean = true@State btnColor: string = '#ccc'index: numberitem: number@State btnScale: {x: number,y: number} = { x: 1, y: 1 }@Styles customStyle(){.width('100%').height('100%').borderRadius(100)}build() {Column() {Button() {Stack() {Row() {// 判别组件为开放形态if (this.unPressed && this.currIndex == this.index) {// 拔出Row组件,性能过渡成果Row().customStyle().backgroundColor('#fff')// 水波纹分散动画:Row组件backgroundColor属性变卦(#fff -> #ccc),系统拔出动画过渡成果,从组建的核心点开局加大,scale{0,0}变卦scale{1,1}.transition({type: TransitionType.Insert,opacity: 0,scale: { x: 0, y: 0, centerY: '50%', centerX: '50%' }})}// 判别组件为按下形态else if (!this.unPressed && this.currIndex == this.index) {// 拔出Row组件,性能过渡成果Row().customStyle().backgroundColor(this.btnColor).scale(this.btnScale).onAppear(() => {// 水波纹靠拢动画:Row组件backgroundColor属性变卦(#ccc -> #fff),拔出动画过渡成果,scale{1,1}变动为scale{0,0}animateTo({ duration: 300,// 靠拢动画播放成功后,须要连贯分散动画,此时Row组件backgroundColor属性变卦(#fff -> #ccc),拔出动画过渡成果,scale{0,0}变动为scale{1,1}onFinish: () => {this.btnColor = '#ccc'this.btnScale = { x: 1, y: 1 }} },() => {this.btnColor = '#fff'this.btnScale = { x: 0, y: 0 }})})}// 其余形态else {Row().customStyle().backgroundColor('#fff')}}.justifyContent(FlexAlign.Center).alignItems(VerticalAlign.Center).borderRadius(100)Text(`${this.item}`).fontSize(30)}.customStyle()}.stateEffect(false).backgroundColor('#ccc').type(ButtonType.Circle).borderRadius(100).width(100).height(100)}.visibility(this.item == -1 ? Visibility.Hidden : Visibility.Visible).borderRadius(100)// onTouch事情,监听形态.onTouch((event: TouchEvent) => {// 当按钮按下时,降级按钮的形态(unPressed:true -> false)if (event.type == TouchType.Down) {animateTo({ duration: }, () => {this.unPressed = !this.unPressedthis.currIndex = this.index})}// 当按钮开放时,降级按钮的形态(unPressed:false -> true)if (event.type == TouchType.Up) {animateTo({ duration: }, () => {this.unPressed = !this.unPressed})}})}}