属性动画
为了那些改变属性,不那么生硬,有点动画 属性接口(以下简称属性)包含尺寸属性、布局属性、位置属性等多种类型
- 布局属性 | 位置、大小、内边距、外边距、对齐方式、权重等。
- 平移、旋转、缩放、锚点等
- 文字大小、文字颜色,图片对齐方式、模糊等。
- 外观 | 透明度、圆角、边框、阴影等
插补器
还有弹簧的
curves.responsiveSpringMotion(1, 0.25))
curves.springMotion()
| Linear | 表示动画从头到尾的速度都是相同的。 |
|---|---|
| Ease | 表示动画以低速开始,然后加快,在结束前变慢,CubicBezier(0.25, 0.1, 0.25, 1.0)。 |
| EaseIn | 表示动画以低速开始,CubicBezier(0.42, 0.0, 1.0, 1.0)。 |
| EaseOut | 表示动画以低速结束,CubicBezier(0.0, 0.0, 0.58, 1.0)。 |
| EaseInOut | 表示动画以低速开始和结束,CubicBezier(0.42, 0.0, 0.58, 1.0)。 |
| FastOutSlowIn | 标准曲线,CubicBezier(0.4, 0.0, 0.2, 1.0)。 |
| LinearOutSlowIn | 减速曲线,CubicBezier(0.0, 0.0, 0.2, 1.0)。 |
| FastOutLinearIn | 加速曲线,CubicBezier(0.4, 0.0, 1.0, 1.0)。 |
| ExtremeDeceleration | 急缓曲线,CubicBezier(0.0, 0.0, 0.0, 1.0)。 |
| Sharp | 锐利曲线,CubicBezier(0.33, 0.0, 0.67, 1.0)。 |
| Rhythm | 节奏曲线,CubicBezier(0.7, 0.0, 0.2, 1.0)。 |
| Smooth | 平滑曲线,CubicBezier(0.4, 0.0, 0.4, 1.0)。 |
| Friction | 阻尼曲线,CubicBezier(0.2, 0.0, 0.2, 1.0)。 |
使用animateTo产生属性动画
// 改变刷行的方法
changeAnimate(){
animateTo({ duration: 1000, curve: curves.springMotion() }, () => {
if (this.scaleImage == 1) {
this.scaleImage = 0.4
this.translateImage = 100
this.angleImage = 45
} else {
this.scaleImage = 1
this.translateImage = 0
this.angleImage = 0
}
})
}
使用animation产生属性动画
@State radius: number = 0
@State widthText: number = 150
@State opacityText: number = 1
@State heightText: number = 100
@State fontSizeText: number = 25
@State scaleImage: number = 1
@State translateImage: number = 0
@State angleImage: number = 0
build() {
Column() {
Text('大哥好')
.borderRadius(this.radius)
.borderColor(Color.Red)
.fontSize(this.fontSizeText)
.width(this.widthText)
.height(this.heightText)
.opacity(this.opacityText)
.animation({ duration: 1000, curve: curves.springMotion() })
.textAlign(TextAlign.Center)
.borderWidth(2)
.onClick(() => {
if (this.radius == 0) {
this.radius = 50
this.widthText = 100
this.heightText = 50
this.fontSizeText = 30
this.opacityText = 0.3
} else {
this.radius = 0
this.widthText = 150
this.heightText = 100
this.fontSizeText = 20
this.opacityText = 1
}
})
Image($r('app.media.startIcon'))
.scale({
x: this.scaleImage,
y: this.scaleImage
})
.translate({ x: this.translateImage, y: this.translateImage })
.rotate({ angle: this.angleImage })// .transform(matrix4.identity()
// .translate({ x: this.translateImage, y: this.translateImage })
// .scale({ x: this.scaleImage, y: this.scaleImage })
// .rotate({
// angle: this.angleImage
// }))
.width(110)
.aspectRatio(1)
.animation({
duration: 500,
curve: Curve.Smooth
})
.onClick(() => {
if (this.scaleImage == 1) {
this.scaleImage = 0.4
this.translateImage = 100
this.angleImage = 45
} else {
this.scaleImage = 1
this.translateImage = 0
this.angleImage = 0
}
})
}.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
自定义属性
@AnimatableExtend 使用这个来重写控件的属性
@AnimatableExtend(Text)
function animatableFontSize(size: number) {
.fontSize(size) // 调用系统属性接口
}
Text("AnimatableProperty")
.backgroundColor("#0C000000")
.animatableFontSize(this.fontSize)// 第二步:将自定义可动画属性接口设置到组件上
.animation({ duration: 1100, curve: "ease" })// 第三步:为自定义可动画属性接口绑定动画
.width(250)
.height(140)
.textAlign(TextAlign.Center)
.onClick(() => {
this.fontSize = this.fontSize == 20 ? 30 : 20; // 第四步:改变自定义可动画属性的参数,产生动画
})
转场动画
转场动画是指对将要出现或消失的组件做动画,对组件进行动画,当组件挂载的时候会,卸载的时候
挂载/卸载动画
// 第一步,创建 TransitionEffect
private effect: TransitionEffect =
TransitionEffect.OPACITY.animation({ curve: Curve.Smooth })
.combine(TransitionEffect.scale({ x: 0, y: 0 }))
.combine(TransitionEffect.rotate({ angle: 90 }))
.combine(TransitionEffect.translate({ y: 150 }))
if (this.isPresent) {
Column() {}
.justifyContent(FlexAlign.Center)
.width(150)
.height(150)
.borderRadius(10)
.backgroundColor(0xf56c6c)
// 第二步:将转场效果通过transition接口设置到组件
.transition(this.effect)
}
模态转场
- bindContentCover 弹出全屏的模态组件。 用于自定义全屏的模态展示界面,结合转场动画和共享元素动画可实现复杂转场动画效果,如缩略图片点击后查看大图。
- bindSheet 弹出半模态组件。 用于半模态展示界面,如分享框。
- bindMenu 弹出菜单,点击组件后弹出。 需要Menu菜单的场景,如一般应用的“+”号键。
- bindContextMenu 弹出菜单,长按或者右键点击后弹出。 长按浮起效果,一般结合拖拽框架使用,如桌面图标长按浮起。
- bindPopup 弹出Popup弹框。 Popup弹框场景,如点击后对某个组件进行临时说明。
- if
共享元素动画
页面间的
使用 geometryTransition 绑定同样的东西 和 transition 以及 属性动画配合做出来的效果,再加上id,加了id之后,新建的spring图片会复用之前的spring图片节点,不会重新创建节点,也就不会有重影问题
.geometryTransition("picture")
.transition(TransitionEffect.OPACITY)
.id('item1')
Stack({ alignContent: Alignment.Center }) {
if (this.isShow) {
Image('https://pic2.zhimg.com/80/v2-393c15200b287070fbb3105c08e6ebf5_1440w.webp')
.width(200)
.height(200)
.borderRadius(100)
.clip(true)
.geometryTransition("picture")
.transition(TransitionEffect.OPACITY)
.id('item1')
} else {
// geometryTransition 此处绑定的是容器,那么容器内的子组件需设为相对布局跟随父容器变化,
// 套多层容器为了说明相对布局约束传递
Image('https://pic2.zhimg.com/80/v2-393c15200b287070fbb3105c08e6ebf5_1440w.webp')
.size({ width: '100%', height: '100%' })
.width(100)
.height(100)
.borderRadius(50)
.clip(true)
.geometryTransition("picture")// transition保证节点离场不被立即析构,设置通用转场效果
.transition(TransitionEffect.OPACITY)
.position({ x: 40, y: 40 })
.id('item2')
}
}
.onClick(() => {
animateTo({
curve: curves.springMotion()
}, () => {
this.isShow = !this.isShow;
})
})