Files
2026-09-24 16:25:22 +08:00

264 lines
8.2 KiB
Kotlin

package uts.sdk.modules.utsXdxdAnimation
import android.view.View
import android.animation.ObjectAnimator
import android.animation.Animator
import android.animation.AnimatorInflater
import android.graphics.Path
import android.animation.AnimatorSet
import android.animation.AnimatorListenerAdapter
import android.animation.TimeInterpolator
import android.view.animation.LinearInterpolator
import android.animation.ValueAnimator
class xdAnimation private constructor() {
val runningAnimators = mutableListOf<Animator>()
companion object {
// 平移动画
fun translate(
view: View,
duration: Long = 1000,
delay: Long = 0,
translation : Int = 0, //0平行移x,1平移y,2平移x,y
fromLen:Float = 0f,
len:Float = 0f,
loop: Int = 0,
start: (() -> Unit)? = null,
end: (() -> Unit)? = null
) {
val animator = when (translation) {
1 -> { // Y轴平移
ObjectAnimator.ofFloat(view, "translationY", fromLen, len)
}
2 -> { // XY轴同时平移
val path = Path().apply {
moveTo(fromLen, fromLen)
lineTo(len, len)
}
ObjectAnimator.ofFloat(view, View.X, View.Y, path)
}
else -> { // X轴平移
ObjectAnimator.ofFloat(view, "translationX", fromLen, len)
}
}
// animator.repeatMode = ObjectAnimator.RESTART
if (loop == -1) {
animator.repeatCount = ObjectAnimator.INFINITE
} else {
animator.repeatCount = loop
}
animator.duration = duration
animator.startDelay = delay
animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
start?.invoke()
}
override fun onAnimationEnd(animation: Animator) {
end?.invoke()
}
})
animator.start()
}
// 旋转动画
fun rotate(
view: View,
duration: Long = 1000,
delay: Long = 0,
fromDeg: Float = 0f,
deg: Float = 360f,
loop: Int = 0,
start: (() -> Unit)? = null,
end: (() -> Unit)? = null
) {
val animator = ObjectAnimator.ofFloat(view, "rotation", fromDeg, deg)
animator.repeatMode = ObjectAnimator.RESTART
if (loop == -1) {
animator.repeatCount = ObjectAnimator.INFINITE
} else {
animator.repeatCount = loop
}
animator.interpolator = LinearInterpolator()
animator.duration = duration
animator.startDelay = delay
animator.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
start?.invoke()
}
override fun onAnimationEnd(animation: Animator) {
end?.invoke()
}
})
animator.start()
// runningAnimators.add(animator)
}
// 3D翻转动画
fun flip3D(
view: View,
duration: Long = 1000,
delay: Long = 0,
axis: Int = 1, // 0: X轴, 1: Y轴
fromDeg: Float = 0f, // 旋转角度
deg: Float = 180f, // 旋转角度
loop: Int = 0,
cameraDistance: Float = 8f, // 控制视角距离,默认值更合理
scaleZ: Float = 0.8f, // 控制Z轴缩放,默认值更自然
start: (() -> Unit)? = null,
end: (() -> Unit)? = null
) {
view.pivotX = if (axis == 0) view.width / 2f else view.pivotX
view.pivotY = if (axis == 1) view.height / 2f else view.pivotY
val rotateProperty = if (axis == 0) "rotationX" else "rotationY"
val rotateFrom = fromDeg
val rotateTo = deg
val rotateAnimator = ObjectAnimator.ofFloat(view, rotateProperty, rotateFrom, rotateTo)
val scaleZAnimator = ObjectAnimator.ofFloat(view, "scale", scaleZ, scaleZ)
rotateAnimator.repeatMode = ObjectAnimator.RESTART
if (loop == -1) {
rotateAnimator.repeatCount = ObjectAnimator.INFINITE
} else {
rotateAnimator.repeatCount = loop
}
val animatorSet = AnimatorSet()
animatorSet.playTogether(rotateAnimator, scaleZAnimator)
animatorSet.duration = duration
animatorSet.startDelay = delay
animatorSet.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
start?.invoke()
// 使用传入的参数控制摄像机距离
view.cameraDistance = view.width * cameraDistance
}
override fun onAnimationEnd(animation: Animator) {
end?.invoke()
}
})
animatorSet.start()
}
/**
* 清除视图上的所有动画
* @param view 需要清除动画的视图
* @param reset 是否重置视图属性到初始状态
*/
fun clearAnimations(
view: View,
reset: Boolean = true
) {
view.animate().cancel()
view.clearAnimation()
// 如果需要重置视图属性
if (reset) {
// 重置所有变换
view.translationX = 0f
view.translationY = 0f
view.scaleX = 1f
view.scaleY = 1f
view.rotation = 0f
view.rotationX = 0f
view.rotationY = 0f
view.alpha = 1f
// 重置视角距离
view.cameraDistance = 0f
}
}
fun scale(
view: View,
duration: Long = 1000,
delay: Long = 0,
direction: Int = 0, // 0: 水平缩放, 1: 竖直翻转,2:x,y缩放,
fromScale: Float = 0f,
scale: Float = 1f,
loop: Int = 0,
start: (() -> Unit)? = null,
end: (() -> Unit)? = null
) {
when (direction) {
1 -> { // Y轴缩放
val scaleY = ObjectAnimator.ofFloat(view, "scaleY", fromScale, scale)
scaleY.duration = duration
scaleY.startDelay = delay
// scaleY.interpolator = LinearInterpolator()
if (loop == -1) {
scaleY.repeatCount = ObjectAnimator.INFINITE
} else {
scaleY.repeatCount = loop
}
scaleY.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
start?.invoke()
}
override fun onAnimationEnd(animation: Animator) {
end?.invoke()
}
})
scaleY.start()
}
2 -> { // XY轴同时缩放
val scaleX = ObjectAnimator.ofFloat(view, "scaleX", fromScale, scale)
val scaleY = ObjectAnimator.ofFloat(view, "scaleY", fromScale, scale)
// 为每个动画单独设置循环
if (loop == -1) {
scaleX.repeatCount = ObjectAnimator.INFINITE
scaleY.repeatCount = ObjectAnimator.INFINITE
} else {
scaleX.repeatCount = loop
scaleY.repeatCount = loop
}
val animatorSet = AnimatorSet()
animatorSet.playTogether(scaleX, scaleY)
animatorSet.duration = duration
animatorSet.startDelay = delay
// animatorSet.interpolator = LinearInterpolator()
animatorSet.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
start?.invoke()
}
override fun onAnimationEnd(animation: Animator) {
end?.invoke()
}
})
animatorSet.start()
}
else -> { // X轴缩放
val scaleX = ObjectAnimator.ofFloat(view, "scaleX", fromScale, scale)
// scaleX.interpolator = LinearInterpolator()
scaleX.duration = duration
scaleX.startDelay = delay
if (loop == -1) {
scaleX.repeatCount = ObjectAnimator.INFINITE
} else {
scaleX.repeatCount = loop
}
scaleX.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
start?.invoke()
}
override fun onAnimationEnd(animation: Animator) {
end?.invoke()
}
})
scaleX.start()
}
}
}
}
}