如何使用彈簧動畫曲線
場景說明
在動畫開發(fā)場景中,經(jīng)常用到彈性效果,尤其在拖拽某個對象時經(jīng)常伴隨彈性動效。OpenHarmony提供了三種彈簧動畫曲線用來實現(xiàn)彈性效果,本例將為大家介紹這三種曲線的用法。
效果呈現(xiàn)
本例最終效果如下:
運行環(huán)境
本例基于以下環(huán)境開發(fā),開發(fā)者也可以基于其他適配的版本進(jìn)行開發(fā):
- IDE: DevEco Studio 3.1 Beta2
- SDK: Ohos_sdk_public 3.2.11.9(API Version 9 Release)
實現(xiàn)思路
本例主要用到以下三種彈簧動畫曲線:
- curves.springCurve:通過設(shè)置彈簧的初始速度、質(zhì)量、剛度和阻尼來控制彈簧動畫的效果。對應(yīng)本例中springCurve按鈕觸發(fā)的動畫。
- curves.springMotion:通過設(shè)置彈簧震動時間和阻尼來控制彈簧動畫的效果。對應(yīng)本例中springMotion按鈕觸發(fā)的動畫。
- curves.responsiveSpringMotion:構(gòu)造彈性跟手動畫曲線對象,是springMotion的一種特例,僅默認(rèn)參數(shù)不同,可與springMotion混合使用。用來實現(xiàn)拖拽動畫。
開發(fā)步驟
搭建UI框架。
樣例中有兩個按鈕,一個圖片。內(nèi)容整體縱向分布,兩個按鈕橫向分布。縱向布局可以采用Column組件,橫向布局可以采用Row組件。代碼如下:
@Entry
@Component
struct ImageComponent {
build() {
Column() {
Row() {
Button('springCurve')
.margin({right:10})
.fontSize(20)
.backgroundColor('#18183C')
Button('springMotion')
.fontSize(20)
.backgroundColor('#18183C')
}
.margin({top:30})
Image($r("app.media.contact2"))
.width(100)
.height(100)
}.width("100%").height("100%").backgroundColor('#A4AE77')
}
}
為springCurve按鈕添加curves.springCurve的曲線動畫。
...
// 定義狀態(tài)變量translateY,用來控制笑臉圖像的位移
@State translateY: number = 0
...
Button('springCurve')
.margin({right:10})
.fontSize(20)
.backgroundColor('#18183C')
// 綁定點擊事件
.onClick(() => {
// 在點擊事件中添加顯示動畫
animateTo({
duration: 2000,
// 設(shè)定curves.springCurve為動畫曲線
curve: curves.springCurve(100, 10, 80, 10)
},
() => {
// 改變translateY的值,使笑臉圖像發(fā)生位移
this.translateY = -20
})
this.translateY = 0
})
...
Image($r("app.media.contact2"))
.width(100)
.height(100)
// 為笑臉圖像添加位移屬性,以translateY為參數(shù)
.translate({ y: this.translateY })
...
效果如下:
為springMotion按鈕添加curves.springMotion曲線動畫。
這里通過position屬性控制springMotion按鈕的移動,當(dāng)然開發(fā)者也可以繼續(xù)選擇使用translate屬性。
...
// 定義狀態(tài)變量translateY,用來控制笑臉圖像的位置變化
@State imgPos: {
x: number,
y: number
} = { x: 125, y: 400 }
...
Button('springMotion')
.fontSize(20)
.backgroundColor('#18183C')
// 綁定點擊事件
.onClick(() => {
// 在點擊事件中添加顯示動畫
animateTo({
duration: 15,
//設(shè)定curves.springMotion為動畫曲線
curve: curves.springMotion(0.5, 0.5),
onFinish: () => {
animateTo({ duration: 500,
curve: curves.springMotion(0.5, 0.5), }, () => {
// 動畫結(jié)束時笑臉圖像位置還原
this.imgPos = { x: 125, y: 400 }
})
}
}, () => {
// 改變笑臉圖像位置,y軸位置由400,變?yōu)?50
this.imgPos = { x: 125, y: 150 }
})
})
...
Image($r("app.media.contact2"))
.width(100)
.height(100)
.translate({ y: this.translateY })
// 為笑臉圖像添加位置屬性,以imgPos為參數(shù)
.position(this.imgPos)
...
效果如下:
使用curves.responsiveSpringMotion為笑臉圖像添加拖拽動畫。
...
Image($r("app.media.contact2"))
.width(100)
.height(100)
.translate({ y: this.translateY })
.position(this.imgPos)
// 綁定觸摸事件
.onTouch((event: TouchEvent) => {
// 當(dāng)觸摸放開時,笑臉圖像位置還原
if (event.type == TouchType.Up) {
animateTo({
duration: 50,
delay: 0,
curve: curves.springMotion(),
onFinish: () => {
}
}, () => {
this.imgPos = { x: 125, y: 400 }
})
} else {
// 觸摸過程中觸發(fā)跟手動畫
animateTo({
duration: 50,
delay: 0,
//設(shè)定跟手動畫曲線
curve: curves.responsiveSpringMotion(),
onFinish: () => {
}
}, () => {
// 根據(jù)觸點位置改變笑臉圖像位置,從而實現(xiàn)跟手動畫
this.imgPos = {
x: event.touches[0].screenX - 100 / 2,
y: event.touches[0].screenY - 100 / 2
}
})
}
})
...
效果如下:
完整代碼
本例完整代碼如下:
import curves from '@ohos.curves';
@Entry
@Component
struct ImageComponent {
// 定義狀態(tài)變量translateY,用來控制笑臉圖像的位移
@State translateY: number = 0
// 定義狀態(tài)變量translateY,用來控制笑臉圖像的位置變化
@State imgPos: {
x: number,
y: number
} = { x: 125, y: 400 }
build() {
Column() {
Row() {
Button('springCurve')
.margin({right:10})
.fontSize(20)
.backgroundColor('#18183C')
// 綁定點擊事件
.onClick(() => {
// 在點擊事件中添加顯示動畫
animateTo({
duration: 2000,
// 設(shè)定curves.springCurve為動畫曲線
curve: curves.springCurve(100, 10, 80, 10)
},
() => {
// 改變translateY的值,使笑臉圖像發(fā)生位移
this.translateY = -20
})
this.translateY = 0
})
Button('springMotion')
.fontSize(20)
.backgroundColor('#18183C')
// 綁定點擊事件
.onClick(() => {
// 在點擊事件中添加顯示動畫
animateTo({
duration: 15,
//設(shè)定curves.springMotion為動畫曲線
curve: curves.springMotion(0.5, 0.5),
onFinish: () => {
animateTo({ duration: 500,
curve: curves.springMotion(0.5, 0.5), }, () => {
// 動畫結(jié)束時笑臉圖像位置還原
this.imgPos = { x: 125, y: 400 }
})
}
}, () => {
// 改變笑臉圖像位置,y軸位置由400,變?yōu)?50
this.imgPos = { x: 125, y: 150 }
})
})
}
.margin({top:30})
Image($r("app.media.contact2"))
.width(100)
.height(100)
// 為笑臉圖像添加位移屬性,以translateY為參數(shù)
.translate({ y: this.translateY })
// 為笑臉圖像添加位置屬性,以imgPos為參數(shù)
.position(this.imgPos)
// 綁定觸摸事件
.onTouch((event: TouchEvent) => {
// 當(dāng)觸摸放開時,笑臉圖像位置還原
if (event.type == TouchType.Up) {
animateTo({
duration: 50,
delay: 0,
curve: curves.springMotion(),
onFinish: () => {
}
}, () => {
this.imgPos = { x: 125, y: 400 }
})
} else {
// 觸摸過程中觸發(fā)跟手動畫,同樣通過animateTo實現(xiàn)動畫效果
animateTo({
duration: 50,
delay: 0,
//設(shè)定跟手動畫曲線
curve: curves.responsiveSpringMotion(),
onFinish: () => {
}
}, () => {
// 根據(jù)觸點位置改變笑臉圖像位置,從而實現(xiàn)跟手動畫
this.imgPos = {
x: event.touches[0].screenX - 100 / 2,
y: event.touches[0].screenY - 100 / 2
}
})
}
})
}.width("100%").height("100%").backgroundColor('#A4AE77')
}
}