1
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"minSdkVersion": "21"
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// import UniversalBlurHelper from 'uts.sdk.modules.utsXdBlur.UniversalBlurHelper';
|
||||
import Color from 'android.graphics.Color';
|
||||
import { hexToRgb } from '../libs/color.uts'
|
||||
import View from 'android.view.View';
|
||||
|
||||
import xdAnimation from 'uts.sdk.modules.utsXdxdAnimation.xdAnimation';
|
||||
import {XDANIMATION_FLIP3D_OPTIONS,XDANIMATION_TRANSLATE_OPTIONS,XDANIMATION_ROTATE_OPTIONS,XDANIMATION_SCALE_OPTIONS} from "../interface.uts"
|
||||
|
||||
|
||||
export class xAnimationS {
|
||||
public static translate(opts:XDANIMATION_TRANSLATE_OPTIONS){
|
||||
if(opts.ele == null) return
|
||||
let view = (opts.ele as UniElement).getAndroidView()! as View
|
||||
let duration_s = (opts?.duration??1000).toLong()
|
||||
let delay_s = (opts?.delay??0).toLong()
|
||||
let translation_s = (opts?.translation??0).toInt()
|
||||
let fromlen_s = (opts?.from??360).toFloat()
|
||||
let len_s = (opts?.len??360).toFloat()
|
||||
let loop_s = (opts?.loop??0).toInt()
|
||||
xdAnimation.translate(view,duration_s,delay_s,translation_s,fromlen_s,len_s,loop_s,opts?.start,opts?.end)
|
||||
}
|
||||
public static rotate(opts:XDANIMATION_ROTATE_OPTIONS){
|
||||
if(opts.ele == null) return
|
||||
let view = (opts.ele as UniElement).getAndroidView()! as View
|
||||
let duration_s = (opts?.duration??1000).toLong()
|
||||
let delay_s = (opts?.delay??0).toLong()
|
||||
let from_s = (opts?.from??0).toFloat()
|
||||
let deg_s = (opts?.deg??360).toFloat()
|
||||
let loop_s = (opts?.loop??0).toInt()
|
||||
xdAnimation.rotate(view,duration_s,delay_s,from_s,deg_s,loop_s,opts?.start,opts?.end)
|
||||
}
|
||||
public static scale(opts:XDANIMATION_SCALE_OPTIONS){
|
||||
if(opts.ele == null) return
|
||||
let view = (opts.ele as UniElement).getAndroidView()! as View
|
||||
let duration_s = (opts?.duration??1000).toLong()
|
||||
let delay_s = (opts?.delay??0).toLong()
|
||||
let direction_s = (opts?.direction??2).toInt()
|
||||
let scale_s = (opts?.scale??1).toFloat()
|
||||
let from_s = (opts?.from??0).toFloat()
|
||||
|
||||
let loop_s = (opts?.loop??0).toInt()
|
||||
xdAnimation.scale(view,duration_s,delay_s,direction_s,from_s,scale_s,loop_s,opts?.start,opts?.end)
|
||||
}
|
||||
public static flip3D(opts:XDANIMATION_FLIP3D_OPTIONS){
|
||||
if(opts.ele == null) return
|
||||
let view = (opts.ele as UniElement).getAndroidView()! as View
|
||||
let duration_s = (opts?.duration??1000).toLong()
|
||||
let delay_s = (opts?.delay??0).toLong()
|
||||
let axis_s = (opts?.axis??1).toInt()
|
||||
let from_s = (opts?.from??0).toFloat()
|
||||
let deg_s = (opts?.deg??360).toFloat()
|
||||
let loop_s = (opts?.loop??0).toInt()
|
||||
let cameraDistance_s = (opts?.cameraDistance??12).toFloat()
|
||||
let scaleZ_s = (opts?.scaleZ??0.5).toFloat()
|
||||
xdAnimation.flip3D(view,duration_s,delay_s,axis_s,from_s,deg_s,loop_s,cameraDistance_s,scaleZ_s,opts?.start,opts?.end)
|
||||
}
|
||||
public static clearAnimations(ele:UniElement|null,reset:boolean = true){
|
||||
if(ele == null) return
|
||||
let view = (ele as UniElement).getAndroidView()! as View
|
||||
xdAnimation.clearAnimations(view,reset)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { XDANIMATION_FLIP3D_OPTIONS, XDANIMATION_TRANSLATE_OPTIONS, XDANIMATION_ROTATE_OPTIONS, XDANIMATION_SCALE_OPTIONS } from "../interface.uts"
|
||||
|
||||
/**
|
||||
* 截止 4.76 官方未提供鸿蒙下实现节点获取的方法,因此暂无法兼容鸿蒙。
|
||||
*/
|
||||
|
||||
export class xAnimationS {
|
||||
public static translate(opts : XDANIMATION_TRANSLATE_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
// let view = (opts.ele as UniElement).getAndroidView()! as View
|
||||
let duration_s = (opts?.duration ?? 1000).toLong()
|
||||
let delay_s = (opts?.delay ?? 0).toLong()
|
||||
let translation_s = (opts?.translation ?? 0).toInt()
|
||||
let fromlen_s = (opts?.from ?? 360).toFloat()
|
||||
let len_s = (opts?.len ?? 360).toFloat()
|
||||
let loop_s = (opts?.loop ?? 0).toInt()
|
||||
}
|
||||
public static rotate(opts : XDANIMATION_ROTATE_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
// let view = (opts.ele as UniElement).getAndroidView()! as View
|
||||
let duration_s = (opts?.duration ?? 1000).toLong()
|
||||
let delay_s = (opts?.delay ?? 0).toLong()
|
||||
let from_s = (opts?.from ?? 0).toFloat()
|
||||
let deg_s = (opts?.deg ?? 360).toFloat()
|
||||
let loop_s = (opts?.loop ?? 0).toInt()
|
||||
}
|
||||
public static scale(opts : XDANIMATION_SCALE_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
// let view = (opts.ele as UniElement).getAndroidView()! as View
|
||||
let duration_s = (opts?.duration ?? 1000).toLong()
|
||||
let delay_s = (opts?.delay ?? 0).toLong()
|
||||
let direction_s = (opts?.direction ?? 2).toInt()
|
||||
let scale_s = (opts?.scale ?? 1).toFloat()
|
||||
let from_s = (opts?.from ?? 0).toFloat()
|
||||
|
||||
let loop_s = (opts?.loop ?? 0).toInt()
|
||||
}
|
||||
public static flip3D(opts : XDANIMATION_FLIP3D_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
// let view = (opts.ele as UniElement).getAndroidView()! as View
|
||||
let duration_s = (opts?.duration ?? 1000).toLong()
|
||||
let delay_s = (opts?.delay ?? 0).toLong()
|
||||
let axis_s = (opts?.axis ?? 1).toInt()
|
||||
let from_s = (opts?.from ?? 0).toFloat()
|
||||
let deg_s = (opts?.deg ?? 360).toFloat()
|
||||
let loop_s = (opts?.loop ?? 0).toInt()
|
||||
let cameraDistance_s = (opts?.cameraDistance ?? 12).toFloat()
|
||||
let scaleZ_s = (opts?.scaleZ ?? 0.5).toFloat()
|
||||
}
|
||||
public static clearAnimations(ele : UniElement | null, reset : boolean = true) {
|
||||
if (ele == null) return
|
||||
// let view = (ele as UniElement).getAndroidView()! as View
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"deploymentTarget": "12"
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
// import UniversalBlurHelper from 'uts.sdk.modules.utsXdBlur.UniversalBlurHelper';
|
||||
|
||||
import { hexToRgb } from '../libs/color.uts'
|
||||
import {XDANIMATION_FLIP3D_OPTIONS,XDANIMATION_TRANSLATE_OPTIONS,XDANIMATION_ROTATE_OPTIONS,XDANIMATION_SCALE_OPTIONS} from "../interface.uts"
|
||||
import { UIView } from 'UIKit';
|
||||
import { CGFloat } from 'CoreFoundation';
|
||||
import { CABasicAnimation } from "QuartzCore";
|
||||
|
||||
export class xAnimationS {
|
||||
public static translate(opts:XDANIMATION_TRANSLATE_OPTIONS){
|
||||
if(opts.ele == null) return
|
||||
let view = (opts.ele as UniElement).getIOSView()! as UIView
|
||||
let duration_s = ((opts.duration==null?1000:(opts.duration!))/1000).toDouble()
|
||||
let delay_s = ((opts.delay==null?0:(opts.delay!))/1000).toDouble()
|
||||
let translation_s = (opts.translation==null?0:(opts.translation!)).toInt()
|
||||
let from_s = new CGFloat((opts.from==null?0:(opts.from!)))
|
||||
let len_s = new CGFloat(opts.len==null?0:(opts.len!))
|
||||
let loop_s = (opts.loop==null?0:(opts.loop!)).toInt()
|
||||
|
||||
|
||||
xdAnimation.translate(
|
||||
view=view,
|
||||
duration=duration_s,
|
||||
delay=delay_s,
|
||||
translation=translation_s,
|
||||
fromLen=from_s,
|
||||
len=len_s,
|
||||
loop=loop_s,
|
||||
start=opts.start,
|
||||
end=opts.end
|
||||
)
|
||||
}
|
||||
public static rotate(opts:XDANIMATION_ROTATE_OPTIONS){
|
||||
if(opts.ele == null) return
|
||||
let view = (opts.ele as UniElement).getIOSView()! as UIView
|
||||
let duration_s = ((opts.duration==null?1000:(opts.duration!))/1000).toDouble()
|
||||
let delay_s = ((opts.delay==null?0:(opts.delay!))/1000).toDouble()
|
||||
let from_s = new CGFloat((opts.from==null?0:(opts.from!)))
|
||||
let deg_s = new CGFloat(opts.deg==null?360:(opts.deg!))
|
||||
let loop_s = (opts.loop==null?0:(opts.loop!)).toInt()
|
||||
|
||||
xdAnimation.rotate(
|
||||
view=view,
|
||||
duration=duration_s,
|
||||
delay=delay_s,
|
||||
fromDeg=from_s,
|
||||
deg=deg_s,
|
||||
loop=loop_s,
|
||||
start=opts.start,
|
||||
end=opts.end
|
||||
)
|
||||
}
|
||||
public static scale(opts:XDANIMATION_SCALE_OPTIONS){
|
||||
if(opts.ele == null) return
|
||||
let view = (opts.ele as UniElement).getIOSView()! as UIView
|
||||
let duration_s = ((opts.duration==null?1000:(opts.duration!))/1000).toDouble()
|
||||
let delay_s = ((opts.delay==null?0:(opts.delay!))/1000).toDouble()
|
||||
let direction_s = (opts.direction==null?2:(opts.direction!)).toInt()
|
||||
let from_s = new CGFloat((opts.from==null?0:(opts.from!)))
|
||||
let scale_s = new CGFloat(opts.scale==null?1:(opts.scale!))
|
||||
let loop_s = (opts.loop==null?0:(opts.loop!)).toInt()
|
||||
|
||||
xdAnimation.scale(
|
||||
view=view,
|
||||
duration=duration_s,
|
||||
delay=delay_s,
|
||||
direction = direction_s,
|
||||
fromScale=from_s,
|
||||
scale=scale_s,
|
||||
loop=loop_s,
|
||||
start=opts.start,
|
||||
end=opts.end
|
||||
)
|
||||
|
||||
}
|
||||
public static flip3D(opts:XDANIMATION_FLIP3D_OPTIONS){
|
||||
if(opts.ele == null) return
|
||||
let view = (opts.ele as UniElement).getIOSView()! as UIView
|
||||
let duration_s = ((opts.duration==null?1000:(opts.duration!))/1000).toDouble()
|
||||
let delay_s = ((opts.delay==null?0:(opts.delay!))/1000).toDouble()
|
||||
let axis_s = (opts.axis==null?1:(opts.axis!)).toInt()
|
||||
let from_s = new CGFloat((opts.from==null?0:(opts.from!)))
|
||||
let deg_s = new CGFloat(opts.deg==null?360:(opts.deg!))
|
||||
let cameraDistance_s = new CGFloat((opts.cameraDistance==null?12:(opts.cameraDistance!)))
|
||||
let scaleZ_s = new CGFloat(opts.scaleZ==null?0.5:(opts.scaleZ!))
|
||||
let loop_s = (opts.loop==null?0:(opts.loop!)).toInt()
|
||||
|
||||
|
||||
xdAnimation.flip3D(
|
||||
view=view,
|
||||
duration=duration_s,
|
||||
delay=delay_s,
|
||||
axis = axis_s,
|
||||
fromDeg=from_s,
|
||||
deg=deg_s,
|
||||
loop=loop_s,
|
||||
cameraDistance=cameraDistance_s,
|
||||
scaleZ=scaleZ_s,
|
||||
start=opts.start,
|
||||
end=opts.end
|
||||
)
|
||||
|
||||
}
|
||||
public static clearAnimations(ele:UniElement|null,reset:boolean = true){
|
||||
if(ele == null) return
|
||||
let view = (ele as UniElement).getIOSView()! as UIView
|
||||
// xdAnimation.clearAnimations(view,reset)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
import UIKit
|
||||
import QuartzCore
|
||||
|
||||
// 动画代理类,用于回调
|
||||
class AnimationDelegate: NSObject, CAAnimationDelegate {
|
||||
var start: (() -> Void)?
|
||||
var end: (() -> Void)?
|
||||
|
||||
init(start: (() -> Void)?, end: (() -> Void)?) {
|
||||
self.start = start
|
||||
self.end = end
|
||||
}
|
||||
|
||||
func animationDidStart(_ anim: CAAnimation) {
|
||||
start?()
|
||||
}
|
||||
|
||||
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
|
||||
end?()
|
||||
}
|
||||
}
|
||||
|
||||
// 扩展CGFloat以支持角度到弧度的转换
|
||||
extension CGFloat {
|
||||
func toRadians() -> CGFloat {
|
||||
return self * .pi / 180.0
|
||||
}
|
||||
}
|
||||
|
||||
class xdAnimation {
|
||||
// 平移动画
|
||||
static func translate(
|
||||
view: UIView,
|
||||
duration: TimeInterval = 1.0,
|
||||
delay: TimeInterval = 0,
|
||||
translation: Int = 0, // 0平行移x,1平移y,2平移x,y
|
||||
fromLen: CGFloat = 0,
|
||||
len: CGFloat = 0,
|
||||
loop: Int = 0,
|
||||
start: (() -> Void)? = nil,
|
||||
end: (() -> Void)? = nil
|
||||
) {
|
||||
let timingFunction: CAMediaTimingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
||||
// 创建动画
|
||||
let animation: CAPropertyAnimation
|
||||
|
||||
switch translation {
|
||||
case 1: // Y轴平移
|
||||
let basicAnimation = CABasicAnimation(keyPath: "transform.translation.y")
|
||||
basicAnimation.fromValue = fromLen
|
||||
basicAnimation.toValue = len
|
||||
animation = basicAnimation
|
||||
|
||||
case 2: // XY轴同时平移
|
||||
let keyframeAnimation = CAKeyframeAnimation(keyPath: "position")
|
||||
let path = CGMutablePath()
|
||||
let startPoint = CGPoint(x: view.frame.origin.x + fromLen, y: view.frame.origin.y + fromLen)
|
||||
let endPoint = CGPoint(x: view.frame.origin.x + len, y: view.frame.origin.y + len)
|
||||
path.move(to: startPoint)
|
||||
path.addLine(to: endPoint)
|
||||
keyframeAnimation.path = path
|
||||
animation = keyframeAnimation
|
||||
|
||||
default: // X轴平移
|
||||
let basicAnimation = CABasicAnimation(keyPath: "transform.translation.x")
|
||||
basicAnimation.fromValue = fromLen
|
||||
basicAnimation.toValue = len
|
||||
animation = basicAnimation
|
||||
}
|
||||
|
||||
// 设置基本属性
|
||||
animation.duration = duration
|
||||
animation.beginTime = CACurrentMediaTime() + delay
|
||||
animation.timingFunction = timingFunction // 设置时间曲线
|
||||
animation.isRemovedOnCompletion = false // 动画结束后不要移除
|
||||
animation.fillMode = .forwards // 保持动画最后一帧
|
||||
|
||||
// 设置循环
|
||||
if loop == -1 {
|
||||
animation.repeatCount = .infinity
|
||||
} else {
|
||||
animation.repeatCount = Float(loop)
|
||||
}
|
||||
|
||||
// 添加动画
|
||||
CATransaction.begin()
|
||||
CATransaction.setCompletionBlock {
|
||||
end?()
|
||||
}
|
||||
start?()
|
||||
view.layer.add(animation, forKey: "translation")
|
||||
CATransaction.commit()
|
||||
}
|
||||
|
||||
static func rotate(view: UIView,
|
||||
duration: TimeInterval = 1.0,
|
||||
delay: TimeInterval = 0.0,
|
||||
fromDeg: CGFloat = 0.0,
|
||||
deg: CGFloat = 360.0,
|
||||
loop: Int = 0,
|
||||
start: (() -> Void)? = nil,
|
||||
end: (() -> Void)? = nil) {
|
||||
|
||||
// 创建旋转动画
|
||||
let timingFunction: CAMediaTimingFunction = CAMediaTimingFunction(name: .linear)
|
||||
let rotation = CABasicAnimation(keyPath: "transform.rotation")
|
||||
rotation.fromValue = fromDeg * .pi / 180.0 // 将度数转为弧度
|
||||
rotation.toValue = deg * .pi / 180.0 // 将度数转为弧度
|
||||
rotation.duration = duration
|
||||
rotation.beginTime = CACurrentMediaTime() + delay
|
||||
rotation.isCumulative = true
|
||||
rotation.timingFunction = timingFunction // 设置时间曲线
|
||||
rotation.isRemovedOnCompletion = false // 动画结束后不要移除
|
||||
rotation.fillMode = .forwards // 保持动画最后一帧
|
||||
|
||||
// 设置循环次数
|
||||
if loop == -1 {
|
||||
rotation.repeatCount = .infinity
|
||||
} else {
|
||||
rotation.repeatCount = Float(loop)
|
||||
}
|
||||
|
||||
// 开始时的回调
|
||||
if let startAction = start {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
||||
startAction()
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 CATransaction 来处理动画完成后的回调
|
||||
CATransaction.begin()
|
||||
|
||||
// 设置动画完成时的回调
|
||||
CATransaction.setCompletionBlock {
|
||||
end?()
|
||||
}
|
||||
|
||||
// 添加动画到视图的层上
|
||||
view.layer.add(rotation, forKey: "rotationAnimation")
|
||||
|
||||
// 提交事务
|
||||
CATransaction.commit()
|
||||
}
|
||||
|
||||
// 缩放动画
|
||||
static func scale(view: UIView,
|
||||
duration: TimeInterval = 1.0,
|
||||
delay: TimeInterval = 0.0,
|
||||
direction: Int = 0,
|
||||
fromScale: CGFloat = 0.0,
|
||||
scale: CGFloat = 1.0,
|
||||
loop: Int = 0,
|
||||
start: (() -> Void)? = nil,
|
||||
end: (() -> Void)? = nil) {
|
||||
|
||||
// 创建动画集合
|
||||
var scaleAnimations = [CABasicAnimation]()
|
||||
|
||||
switch direction {
|
||||
case 1: // 竖直缩放 (Y轴)
|
||||
let scaleY = CABasicAnimation(keyPath: "transform.scale.y")
|
||||
scaleY.fromValue = fromScale
|
||||
scaleY.toValue = scale
|
||||
scaleAnimations = [scaleY]
|
||||
|
||||
case 2: // XY轴同时缩放
|
||||
let scaleX = CABasicAnimation(keyPath: "transform.scale.x")
|
||||
scaleX.fromValue = fromScale
|
||||
scaleX.toValue = scale
|
||||
|
||||
let scaleY = CABasicAnimation(keyPath: "transform.scale.y")
|
||||
scaleY.fromValue = fromScale
|
||||
scaleY.toValue = scale
|
||||
|
||||
scaleAnimations = [scaleX, scaleY]
|
||||
|
||||
default: // 水平缩放 (X轴)
|
||||
let scaleX = CABasicAnimation(keyPath: "transform.scale.x")
|
||||
scaleX.fromValue = fromScale
|
||||
scaleX.toValue = scale
|
||||
scaleAnimations = [scaleX]
|
||||
}
|
||||
|
||||
// 设置动画属性
|
||||
for animation in scaleAnimations {
|
||||
animation.duration = duration
|
||||
animation.beginTime = CACurrentMediaTime() + delay
|
||||
animation.isCumulative = true
|
||||
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) // 设置时间曲线
|
||||
animation.isRemovedOnCompletion = false // 动画结束后不要移除
|
||||
animation.fillMode = .forwards // 保持动画最后一帧
|
||||
|
||||
if loop == -1 {
|
||||
animation.repeatCount = .infinity
|
||||
} else {
|
||||
animation.repeatCount = Float(loop)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 使用 CATransaction 来管理动画的开始和结束
|
||||
CATransaction.begin()
|
||||
|
||||
// 动画开始时的回调
|
||||
if let startAction = start {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
||||
startAction()
|
||||
}
|
||||
}
|
||||
|
||||
// 设置动画完成时的回调
|
||||
CATransaction.setCompletionBlock {
|
||||
end?()
|
||||
}
|
||||
|
||||
// 添加动画到视图的层上
|
||||
var i=0
|
||||
for animation in scaleAnimations {
|
||||
view.layer.add(animation, forKey: "scaleAnimation"+i.toString())
|
||||
i+=1;
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
CATransaction.commit()
|
||||
}
|
||||
private func deg2rad(_ degree: CGFloat) -> CGFloat {
|
||||
return degree * .pi / 180
|
||||
}
|
||||
|
||||
// 3D翻转动画
|
||||
static func flip3D(
|
||||
view: UIView,
|
||||
duration: TimeInterval = 1.0,
|
||||
delay: TimeInterval = 0.0,
|
||||
axis: Int = 1,
|
||||
fromDeg: CGFloat = 0.0, // 旋转角度
|
||||
deg: CGFloat = 180.0, // 旋转角度
|
||||
loop: Int = 0,
|
||||
cameraDistance: CGFloat = 8.0,
|
||||
scaleZ: CGFloat = 0.8,
|
||||
start: (() -> Void)? = nil,
|
||||
end: (() -> Void)? = nil) {
|
||||
|
||||
let adjustedDeg: CGFloat = deg
|
||||
// 设置3D透视效果
|
||||
var transform = CATransform3DIdentity
|
||||
transform.m34 = -1.0 / cameraDistance
|
||||
view.layer.transform = transform
|
||||
|
||||
// 根据旋转轴选择旋转方式
|
||||
var rotationTransform: CATransform3D
|
||||
if axis == 1 { // 绕Y轴旋转
|
||||
rotationTransform = CATransform3DMakeRotation(fromDeg.toRadians(), 0, 1, 0)
|
||||
} else { // 绕X轴旋转
|
||||
rotationTransform = CATransform3DMakeRotation(fromDeg.toRadians(), 1, 0, 0)
|
||||
}
|
||||
|
||||
// 设置初始角度
|
||||
view.layer.transform = rotationTransform
|
||||
|
||||
// 执行动画
|
||||
UIView.animate(
|
||||
withDuration: duration,
|
||||
delay: delay,
|
||||
options: [.curveLinear],
|
||||
animations: {
|
||||
start?() // 执行开始时的回调
|
||||
// 计算目标角度
|
||||
let finalTransform: CATransform3D
|
||||
if axis == 1 { // 绕Y轴旋转
|
||||
finalTransform = CATransform3DMakeRotation(adjustedDeg.toRadians(), 0, 1, 0)
|
||||
} else { // 绕X轴旋转
|
||||
finalTransform = CATransform3DMakeRotation(adjustedDeg.toRadians(), 1, 0, 0)
|
||||
}
|
||||
|
||||
// 添加Z轴缩放效果
|
||||
let scaleTransform = CATransform3DScale(finalTransform, 1, 1, scaleZ)
|
||||
view.layer.transform = scaleTransform
|
||||
},
|
||||
completion: { finished in
|
||||
if loop > 1 {
|
||||
// 如果需要循环,递归调用
|
||||
flip3D(
|
||||
view: view,
|
||||
duration: duration,
|
||||
delay: delay,
|
||||
axis: axis,
|
||||
fromDeg: adjustedDeg,
|
||||
deg: fromDeg,
|
||||
loop: loop - 1,
|
||||
cameraDistance: cameraDistance,
|
||||
scaleZ: scaleZ,
|
||||
start: start,
|
||||
end: end
|
||||
)
|
||||
} else {
|
||||
end?() // 执行结束时的回调
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
export type XDANIMATION_TRANSLATE_OPTIONS = {
|
||||
/** 播放元素 */
|
||||
ele : UniElement|null,
|
||||
/** 播放时间 */
|
||||
duration?: number,
|
||||
/** 延迟 */
|
||||
delay?: number,
|
||||
/** 0平行移x,1平移y,2平移x,y */
|
||||
translation?: number,
|
||||
/** 起始位置 */
|
||||
from?: number,
|
||||
/** 移动的距离 */
|
||||
len?: number,
|
||||
/** 播放次数,-1循环永久播放,0表示1次,依次类推 */
|
||||
loop?: number,
|
||||
/** 开始回调 */
|
||||
start?: (() => void)|null,
|
||||
/** 结束回调 */
|
||||
end?: (() => void)
|
||||
}
|
||||
|
||||
export type XDANIMATION_ROTATE_OPTIONS = {
|
||||
/** 播放元素 */
|
||||
ele : UniElement|null,
|
||||
/** 播放时间 */
|
||||
duration?: number,
|
||||
/** 延迟 */
|
||||
delay?: number,
|
||||
/** 起始角度,默认是0 */
|
||||
from?: number,
|
||||
/** 旋转的角度 */
|
||||
deg?: number,
|
||||
/** 播放次数,-1循环永久播放,0表示1次,依次类推 */
|
||||
loop?: number,
|
||||
/** 开始回调 */
|
||||
start?: (() => void)|null,
|
||||
/** 结束回调 */
|
||||
end?: (() => void)
|
||||
}
|
||||
export type XDANIMATION_SCALE_OPTIONS = {
|
||||
/** 播放元素 */
|
||||
ele : UniElement|null,
|
||||
/** 播放时间 */
|
||||
duration?: number,
|
||||
/** 延迟 */
|
||||
delay?: number,
|
||||
/** 0缩放x,1缩放y,2缩放x,y */
|
||||
direction?: number,
|
||||
/** 缩放起始值,默认是0 */
|
||||
from?:number,
|
||||
/** 缩放的值 */
|
||||
scale?: number,
|
||||
/** 播放次数,-1循环永久播放,0表示1次,依次类推 */
|
||||
loop?: number,
|
||||
/** 开始回调 */
|
||||
start?: (() => void)|null,
|
||||
/** 结束回调 */
|
||||
end?: (() => void)
|
||||
}
|
||||
export type XDANIMATION_FLIP3D_OPTIONS = {
|
||||
/** 播放元素 */
|
||||
ele : UniElement|null,
|
||||
/** 播放时间 */
|
||||
duration?: number,
|
||||
/** 延迟 */
|
||||
delay?: number,
|
||||
/** 0: X轴, 1: Y轴 */
|
||||
axis?: number,
|
||||
/** 起始角度,默认是0 */
|
||||
from?: number,
|
||||
/** 旋转角度 */
|
||||
deg?: number,
|
||||
/** 播放次数,-1循环永久播放,0表示1次,依次类推 */
|
||||
loop?: number,
|
||||
/** 视角距离 */
|
||||
cameraDistance?: number,
|
||||
/** Z轴缩放 */
|
||||
scaleZ?: number,
|
||||
/** 开始回调 */
|
||||
start?: (() => void)|null,
|
||||
/** 结束回调 */
|
||||
end?: (() => void)
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
type RGBA = { r : number, g : number, b : number, a : number }
|
||||
export function hexToRgb(sColors : string) : RGBA | null {
|
||||
if (sColors == "") {
|
||||
return { r: 0, g: 0, b: 0, a: 0 } as RGBA
|
||||
}
|
||||
let reg = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8})$/;
|
||||
let sColor : string = sColors.toLowerCase();
|
||||
|
||||
if (sColor != '' && reg.test(sColor)) {
|
||||
|
||||
if (sColor.length == 4) {
|
||||
let sColorNew = "#";
|
||||
for (let i = 1; i < 4; i += 1) {
|
||||
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
|
||||
}
|
||||
sColor = sColorNew;
|
||||
}
|
||||
|
||||
//处理六位的颜色值
|
||||
let sColorChange : number[] = [];
|
||||
sColorChange.push(parseInt(sColor.substring(1, 3), 16));
|
||||
sColorChange.push(parseInt(sColor.substring(3, 5), 16));
|
||||
sColorChange.push(parseInt(sColor.substring(5, 7), 16));
|
||||
if (sColor.length == 9) {
|
||||
sColorChange.push(parseInt(sColor.substring(7, 9), 16) / 255);
|
||||
}
|
||||
return {
|
||||
r: sColorChange[0],
|
||||
g: sColorChange[1],
|
||||
b: sColorChange[2],
|
||||
a: sColorChange.length == 4 ? sColorChange[3] : 1
|
||||
} as RGBA
|
||||
} else if (/^(rgb|RGB|rgba|RGBA)/.test(sColor)) {
|
||||
let arr : string[] = sColor.replace(/(?:\(|\)|rgba|rgb|RGB|RGBA)*/g, "").split(",")
|
||||
|
||||
let p : number[] = arr.map((val : string) : number => parseInt(val));
|
||||
if (p.length < 3) {
|
||||
return {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
a: 1
|
||||
} as RGBA
|
||||
}
|
||||
if (p.length == 3) {
|
||||
arr.push('1')
|
||||
}
|
||||
|
||||
return {
|
||||
r: p[0],
|
||||
g: p[1],
|
||||
b: p[2],
|
||||
a: parseFloat(arr[3])
|
||||
} as RGBA
|
||||
} else {
|
||||
return {
|
||||
r: 0,
|
||||
g: 0,
|
||||
b: 0,
|
||||
a: 1
|
||||
} as RGBA
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { hexToRgb } from '../libs/color.uts'
|
||||
import { xdAnimation } from './xdAnimation.uts';
|
||||
export { XDANIMATION_FLIP3D_OPTIONS, XDANIMATION_TRANSLATE_OPTIONS, XDANIMATION_ROTATE_OPTIONS, XDANIMATION_SCALE_OPTIONS } from "../interface.uts"
|
||||
|
||||
|
||||
export class xAnimationS {
|
||||
public static translate(opts : XDANIMATION_TRANSLATE_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
let view = opts.ele as HTMLElement
|
||||
let duration_s = (opts?.duration ?? 1000)
|
||||
let delay_s = (opts?.delay ?? 0)
|
||||
let translation_s = (opts?.translation ?? 0)
|
||||
let fromlen_s = (opts?.from ?? 360)
|
||||
let len_s = (opts?.len ?? 360)
|
||||
let loop_s = (opts?.loop ?? 0)
|
||||
console.log(view)
|
||||
xdAnimation.translate(view, duration_s, delay_s, translation_s, fromlen_s, len_s, loop_s, opts?.start, opts?.end)
|
||||
}
|
||||
public static rotate(opts : XDANIMATION_ROTATE_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
let view = opts.ele as HTMLElement
|
||||
let duration_s = (opts?.duration ?? 1000)
|
||||
let delay_s = (opts?.delay ?? 0)
|
||||
let from_s = (opts?.from ?? 0)
|
||||
let deg_s = (opts?.deg ?? 360)
|
||||
let loop_s = (opts?.loop ?? 0)
|
||||
xdAnimation.rotate(view, duration_s, delay_s, from_s, deg_s, loop_s, opts?.start, opts?.end)
|
||||
}
|
||||
public static scale(opts : XDANIMATION_SCALE_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
let view = opts.ele as HTMLElement
|
||||
let duration_s = (opts?.duration ?? 1000)
|
||||
let delay_s = (opts?.delay ?? 0)
|
||||
let direction_s = (opts?.direction ?? 2)
|
||||
let scale_s = (opts?.scale ?? 1)
|
||||
let from_s = (opts?.from ?? 0)
|
||||
|
||||
let loop_s = (opts?.loop ?? 0)
|
||||
xdAnimation.scale(view, duration_s, delay_s, direction_s, from_s, scale_s, loop_s, opts?.start, opts?.end)
|
||||
}
|
||||
public static flip3D(opts : XDANIMATION_FLIP3D_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
let view = opts.ele as HTMLElement
|
||||
let duration_s = (opts?.duration ?? 1000)
|
||||
let delay_s = (opts?.delay ?? 0)
|
||||
let axis_s = (opts?.axis ?? 1)
|
||||
let from_s = (opts?.from ?? 0)
|
||||
let deg_s = (opts?.deg ?? 360)
|
||||
let loop_s = (opts?.loop ?? 0)
|
||||
let cameraDistance_s = (opts?.cameraDistance ?? 12)
|
||||
let scaleZ_s = (opts?.scaleZ ?? 0.5)
|
||||
xdAnimation.flip3D(view, duration_s, delay_s, axis_s, from_s, deg_s, loop_s, cameraDistance_s, scaleZ_s, opts?.start, opts?.end)
|
||||
}
|
||||
public static clearAnimations(ele : UniElement | null, reset : boolean = true) {
|
||||
if (ele == null) return
|
||||
let view = ele as HTMLElement
|
||||
xdAnimation.clearAnimations(view,reset)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
let tid = 25
|
||||
export class xdAnimation {
|
||||
|
||||
public static translate(
|
||||
view : HTMLElement,
|
||||
duration : number = 1000,
|
||||
delay : number = 0,
|
||||
translation : number = 0, //0平行移x,1平移y,2平移x,y
|
||||
fromLen : number = 0, // 起始位置
|
||||
len : number = 0, // 移动的距离
|
||||
loop : number = 0,//-1永久播放动画,0循环1次,依次类推
|
||||
start : (() => void) | null = null,
|
||||
end : (() => void) | null = null
|
||||
) {
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
// 设置初始位置
|
||||
if (translation === 0) {
|
||||
view.style.transform = `translateX(${fromLen}px)`;
|
||||
|
||||
} else if (translation === 1) {
|
||||
view.style.transform = `translateY(${fromLen}px)`;
|
||||
} else if (translation === 2) {
|
||||
view.style.transform = `translate(${fromLen}px, ${fromLen}px)`;
|
||||
}
|
||||
|
||||
function starttras() {
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${duration}ms`;
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${delay}ms`;
|
||||
if (translation === 0) {
|
||||
console.log(fromLen, len)
|
||||
view.style.transform = `translateX(${len}px)`;
|
||||
} else if (translation === 1) {
|
||||
view.style.transform = `translateY(${len}px)`;
|
||||
} else if (translation === 2) {
|
||||
view.style.transform = `translate(${len}px, ${len}px)`;
|
||||
}
|
||||
|
||||
// 动画开始回调
|
||||
if (start) start();
|
||||
}
|
||||
// 设置动画结束后的位置
|
||||
if (delay == 0) {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, 50);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, duration);
|
||||
}
|
||||
let _this = this;
|
||||
// 动画结束后的处理
|
||||
clearTimeout(tid)
|
||||
tid = setTimeout(function() {
|
||||
if (loop === -1) {
|
||||
// 永久循环
|
||||
_this.translate(view, duration, delay, translation, fromLen, len, loop, start, end);
|
||||
} else if (loop > 0) {
|
||||
// 有限循环
|
||||
_this.translate(view, duration, delay, translation, fromLen, len, loop - 1, start, end);
|
||||
} else {
|
||||
// 动画结束回调
|
||||
if (end) end();
|
||||
}
|
||||
}, duration);
|
||||
|
||||
}
|
||||
|
||||
public static scale(
|
||||
view : HTMLElement,
|
||||
duration : number = 1000,
|
||||
delay : number = 0,
|
||||
direction : number = 0, // 0: 水平缩放, 1: 竖直翻转,2:x,y缩放,
|
||||
fromScale : number = 0, // 起始位置
|
||||
scale : number = 0, // 移动的距离
|
||||
loop : number = 0,//-1永久播放动画,0循环1次,依次类推
|
||||
start : (() => void) | null = null,
|
||||
end : (() => void) | null = null
|
||||
) {
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
// 设置初始位置
|
||||
function setValue(value : number) {
|
||||
if (direction === 0) {
|
||||
view.style.transform = `scaleX(${value})`;
|
||||
|
||||
} else if (direction === 1) {
|
||||
view.style.transform = `scaleY(${value})`;
|
||||
} else if (direction === 2) {
|
||||
view.style.transform = `scale(${value}, ${value})`;
|
||||
}
|
||||
}
|
||||
setValue(fromScale)
|
||||
function starttras() {
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${duration}ms`;
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${delay}ms`;
|
||||
setValue(scale)
|
||||
// 动画开始回调
|
||||
if (start) start();
|
||||
}
|
||||
// 设置动画结束后的位置
|
||||
if (delay == 0) {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, 50);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, delay);
|
||||
}
|
||||
let _this = this;
|
||||
// 动画结束后的处理
|
||||
|
||||
clearTimeout(tid)
|
||||
tid = setTimeout(function() {
|
||||
if (loop === -1) {
|
||||
// 永久循环
|
||||
_this.scale(view, duration, delay, direction, fromScale, scale, loop, start, end);
|
||||
} else if (loop > 0) {
|
||||
// 有限循环
|
||||
_this.scale(view, duration, delay, direction, fromScale, scale, loop - 1, start, end);
|
||||
} else {
|
||||
// 动画结束回调
|
||||
if (end) end();
|
||||
}
|
||||
}, duration);
|
||||
|
||||
}
|
||||
|
||||
public static rotate(
|
||||
view : HTMLElement,
|
||||
duration : number = 1000,
|
||||
delay : number = 0,
|
||||
fromDeg : number = 0, // 起始位置
|
||||
deg : number = 0, // 移动的距离
|
||||
loop : number = 0,//-1永久播放动画,0循环1次,依次类推
|
||||
start : (() => void) | null = null,
|
||||
end : (() => void) | null = null
|
||||
) {
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
// 设置初始位置
|
||||
function setValue(value : number) {
|
||||
view.style.transform = `rotate(${value}deg)`;
|
||||
}
|
||||
setValue(fromDeg)
|
||||
function starttras() {
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${duration}ms`;
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${delay}ms`;
|
||||
setValue(deg)
|
||||
// 动画开始回调
|
||||
if (start) start();
|
||||
}
|
||||
// 设置动画结束后的位置
|
||||
if (delay == 0) {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, 50);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, delay);
|
||||
}
|
||||
let _this = this;
|
||||
|
||||
clearTimeout(tid)
|
||||
tid = setTimeout(function() {
|
||||
if (loop === -1) {
|
||||
// 永久循环
|
||||
_this.rotate(view, duration, delay, fromDeg, deg, loop, start, end);
|
||||
} else if (loop > 0) {
|
||||
// 有限循环
|
||||
_this.rotate(view, duration, delay, fromDeg, deg, loop - 1, start, end);
|
||||
} else {
|
||||
// 动画结束回调
|
||||
if (end) end();
|
||||
}
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
||||
public static flip3D(
|
||||
view : HTMLElement,
|
||||
duration : number = 1000,
|
||||
delay : number = 0,
|
||||
axis : number = 1, // 0: X轴, 1: Y轴
|
||||
fromDeg : number = 0, // 起始位置
|
||||
deg : number = 0, // 移动的距离
|
||||
loop : number = 0,//-1永久播放动画,0循环1次,依次类推
|
||||
cameraDistance : number = 8, // 控制视角距离,默认值更合理
|
||||
scaleZ : number = 0.8, // 控制Z轴缩放,默认值更自然
|
||||
start : (() => void) | null = null,
|
||||
end : (() => void) | null = null
|
||||
) {
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
// 设置透视视角
|
||||
view.style.perspective = `${cameraDistance}px`;
|
||||
view.style.transformStyle = "preserve-3d";
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
// 设置初始角度
|
||||
function setValue(value : number) {
|
||||
if (axis === 0) {
|
||||
view.style.transform = `rotateX(${value}deg) scaleZ(${scaleZ})`;
|
||||
} else if (axis === 1) {
|
||||
view.style.transform = `rotateY(${value}deg) scaleZ(${scaleZ})`;
|
||||
}
|
||||
}
|
||||
|
||||
setValue(fromDeg)
|
||||
|
||||
// 设置动画结束后的角度
|
||||
setTimeout(() => {
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${delay}ms`;
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${duration}ms`;
|
||||
setValue(deg)
|
||||
// 动画开始回调
|
||||
if (start) start();
|
||||
}, delay || 50);
|
||||
|
||||
let _this = this;
|
||||
|
||||
clearTimeout(tid)
|
||||
tid = setTimeout(function() {
|
||||
if (loop === -1) {
|
||||
// 永久循环
|
||||
_this.flip3D(view, duration, delay, axis, fromDeg, deg, loop, cameraDistance, scaleZ, start, end);
|
||||
} else if (loop > 0) {
|
||||
// 有限循环
|
||||
_this.flip3D(view, duration, delay, axis, fromDeg, deg, loop - 1, cameraDistance, scaleZ, start, end);
|
||||
} else {
|
||||
// 动画结束回调
|
||||
if (end) end();
|
||||
}
|
||||
}, duration);
|
||||
|
||||
}
|
||||
public static clearAnimations(view : HTMLElement, _ : boolean = true) {
|
||||
view.style.removeProperty('transform')
|
||||
view.style.removeProperty('transition-delay')
|
||||
view.style.removeProperty('transition-duration')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { hexToRgb } from '../libs/color.uts'
|
||||
import { xdAnimation } from './xdAnimation.uts';
|
||||
export { XDANIMATION_FLIP3D_OPTIONS, XDANIMATION_TRANSLATE_OPTIONS, XDANIMATION_ROTATE_OPTIONS, XDANIMATION_SCALE_OPTIONS } from "../interface.uts"
|
||||
|
||||
|
||||
export class xAnimationS {
|
||||
public static translate(opts : XDANIMATION_TRANSLATE_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
let view = opts.ele as HTMLElement
|
||||
let duration_s = (opts?.duration ?? 1000)
|
||||
let delay_s = (opts?.delay ?? 0)
|
||||
let translation_s = (opts?.translation ?? 0)
|
||||
let fromlen_s = (opts?.from ?? 360)
|
||||
let len_s = (opts?.len ?? 360)
|
||||
let loop_s = (opts?.loop ?? 0)
|
||||
xdAnimation.translate(view, duration_s, delay_s, translation_s, fromlen_s, len_s, loop_s, opts?.start, opts?.end)
|
||||
}
|
||||
public static rotate(opts : XDANIMATION_ROTATE_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
let view = opts.ele as HTMLElement
|
||||
let duration_s = (opts?.duration ?? 1000)
|
||||
let delay_s = (opts?.delay ?? 0)
|
||||
let from_s = (opts?.from ?? 0)
|
||||
let deg_s = (opts?.deg ?? 360)
|
||||
let loop_s = (opts?.loop ?? 0)
|
||||
xdAnimation.rotate(view, duration_s, delay_s, from_s, deg_s, loop_s, opts?.start, opts?.end)
|
||||
}
|
||||
public static scale(opts : XDANIMATION_SCALE_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
let view = opts.ele as HTMLElement
|
||||
let duration_s = (opts?.duration ?? 1000)
|
||||
let delay_s = (opts?.delay ?? 0)
|
||||
let direction_s = (opts?.direction ?? 2)
|
||||
let scale_s = (opts?.scale ?? 1)
|
||||
let from_s = (opts?.from ?? 0)
|
||||
|
||||
let loop_s = (opts?.loop ?? 0)
|
||||
xdAnimation.scale(view, duration_s, delay_s, direction_s, from_s, scale_s, loop_s, opts?.start, opts?.end)
|
||||
}
|
||||
public static flip3D(opts : XDANIMATION_FLIP3D_OPTIONS) {
|
||||
if (opts.ele == null) return
|
||||
let view = opts.ele as HTMLElement
|
||||
let duration_s = (opts?.duration ?? 1000)
|
||||
let delay_s = (opts?.delay ?? 0)
|
||||
let axis_s = (opts?.axis ?? 1)
|
||||
let from_s = (opts?.from ?? 0)
|
||||
let deg_s = (opts?.deg ?? 360)
|
||||
let loop_s = (opts?.loop ?? 0)
|
||||
let cameraDistance_s = (opts?.cameraDistance ?? 12)
|
||||
let scaleZ_s = (opts?.scaleZ ?? 0.5)
|
||||
xdAnimation.flip3D(view, duration_s, delay_s, axis_s, from_s, deg_s, loop_s, cameraDistance_s, scaleZ_s, opts?.start, opts?.end)
|
||||
}
|
||||
public static clearAnimations(ele : UniElement | null, reset : boolean = true) {
|
||||
if (ele == null) return
|
||||
let view = ele as HTMLElement
|
||||
xdAnimation.clearAnimations(view,reset)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
export class xdAnimation {
|
||||
public static translate(
|
||||
view : HTMLElement,
|
||||
duration : number = 1000,
|
||||
delay : number = 0,
|
||||
translation : number = 0, //0平行移x,1平移y,2平移x,y
|
||||
fromLen : number = 0, // 起始位置
|
||||
len : number = 0, // 移动的距离
|
||||
loop : number = 0,//-1永久播放动画,0循环1次,依次类推
|
||||
start : (() => void) | null = null,
|
||||
end : (() => void) | null = null
|
||||
) {
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
view.style.transitionTimingFunction = 'linear'
|
||||
// 设置初始位置
|
||||
if (translation === 0) {
|
||||
view.style.transform = `translateX(${fromLen}px)`;
|
||||
|
||||
} else if (translation === 1) {
|
||||
view.style.transform = `translateY(${fromLen}px)`;
|
||||
} else if (translation === 2) {
|
||||
view.style.transform = `translate(${fromLen}px, ${fromLen}px)`;
|
||||
}
|
||||
|
||||
function starttras() {
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${duration}ms`;
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${delay}ms`;
|
||||
if (translation === 0) {
|
||||
console.log(fromLen, len)
|
||||
view.style.transform = `translateX(${len}px)`;
|
||||
} else if (translation === 1) {
|
||||
view.style.transform = `translateY(${len}px)`;
|
||||
} else if (translation === 2) {
|
||||
view.style.transform = `translate(${len}px, ${len}px)`;
|
||||
}
|
||||
|
||||
// 动画开始回调
|
||||
if (start) start();
|
||||
}
|
||||
// 设置动画结束后的位置
|
||||
if (delay == 0) {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, 50);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, delay);
|
||||
}
|
||||
let _this = this;
|
||||
// 动画结束后的处理
|
||||
view.addEventListener('transitionend', () => {
|
||||
if (loop === -1) {
|
||||
// 永久循环
|
||||
_this.translate(view, duration, delay, translation, fromLen, len, loop, start, end);
|
||||
} else if (loop > 0) {
|
||||
// 有限循环
|
||||
_this.translate(view, duration, delay, translation, fromLen, len, loop - 1, start, end);
|
||||
} else {
|
||||
// 动画结束回调
|
||||
if (end) end();
|
||||
}
|
||||
}, { once: true });
|
||||
}
|
||||
|
||||
public static scale(
|
||||
view : HTMLElement,
|
||||
duration : number = 1000,
|
||||
delay : number = 0,
|
||||
direction : number = 0, // 0: 水平缩放, 1: 竖直翻转,2:x,y缩放,
|
||||
fromScale : number = 0, // 起始位置
|
||||
scale : number = 0, // 移动的距离
|
||||
loop : number = 0,//-1永久播放动画,0循环1次,依次类推
|
||||
start : (() => void) | null = null,
|
||||
end : (() => void) | null = null
|
||||
) {
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
view.style.transitionTimingFunction = 'linear'
|
||||
// 设置初始位置
|
||||
function setValue(value : number) {
|
||||
if (direction === 0) {
|
||||
view.style.transform = `scaleX(${value})`;
|
||||
|
||||
} else if (direction === 1) {
|
||||
view.style.transform = `scaleY(${value})`;
|
||||
} else if (direction === 2) {
|
||||
view.style.transform = `scale(${value}, ${value})`;
|
||||
}
|
||||
}
|
||||
setValue(fromScale)
|
||||
function starttras() {
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${duration}ms`;
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${delay}ms`;
|
||||
setValue(scale)
|
||||
// 动画开始回调
|
||||
if (start) start();
|
||||
}
|
||||
// 设置动画结束后的位置
|
||||
if (delay == 0) {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, 50);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, delay);
|
||||
}
|
||||
let _this = this;
|
||||
// 动画结束后的处理
|
||||
view.addEventListener('transitionend', () => {
|
||||
if (loop === -1) {
|
||||
// 永久循环
|
||||
_this.scale(view, duration, delay, direction, fromScale, scale, loop, start, end);
|
||||
} else if (loop > 0) {
|
||||
// 有限循环
|
||||
_this.scale(view, duration, delay, direction, fromScale, scale, loop - 1, start, end);
|
||||
} else {
|
||||
// 动画结束回调
|
||||
if (end) end();
|
||||
}
|
||||
}, { once: true });
|
||||
}
|
||||
|
||||
public static rotate(
|
||||
view : HTMLElement,
|
||||
duration : number = 1000,
|
||||
delay : number = 0,
|
||||
fromDeg : number = 0, // 起始位置
|
||||
deg : number = 0, // 移动的距离
|
||||
loop : number = 0,//-1永久播放动画,0循环1次,依次类推
|
||||
start : (() => void) | null = null,
|
||||
end : (() => void) | null = null
|
||||
) {
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
view.style.transitionTimingFunction = 'linear'
|
||||
// 设置初始位置
|
||||
function setValue(value : number) {
|
||||
view.style.transform = `rotate(${value}deg)`;
|
||||
}
|
||||
setValue(fromDeg)
|
||||
function starttras() {
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${duration}ms`;
|
||||
view.style.transitionTimingFunction = 'linear'
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${delay}ms`;
|
||||
setValue(deg)
|
||||
// 动画开始回调
|
||||
if (start) start();
|
||||
}
|
||||
// 设置动画结束后的位置
|
||||
if (delay == 0) {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, 50);
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
starttras()
|
||||
}, delay);
|
||||
}
|
||||
let _this = this;
|
||||
// 动画结束后的处理
|
||||
view.addEventListener('transitionend', () => {
|
||||
if (loop === -1) {
|
||||
// 永久循环
|
||||
_this.rotate(view, duration, delay, fromDeg, deg, loop, start, end);
|
||||
} else if (loop > 0) {
|
||||
// 有限循环
|
||||
_this.rotate(view, duration, delay, fromDeg, deg, loop - 1, start, end);
|
||||
} else {
|
||||
// 动画结束回调
|
||||
if (end) end();
|
||||
}
|
||||
}, { once: true });
|
||||
}
|
||||
|
||||
|
||||
public static flip3D(
|
||||
view : HTMLElement,
|
||||
duration : number = 1000,
|
||||
delay : number = 0,
|
||||
axis : number = 1, // 0: X轴, 1: Y轴
|
||||
fromDeg : number = 0, // 起始位置
|
||||
deg : number = 0, // 移动的距离
|
||||
loop : number = 0,//-1永久播放动画,0循环1次,依次类推
|
||||
cameraDistance : number = 8, // 控制视角距离,默认值更合理
|
||||
scaleZ : number = 0.8, // 控制Z轴缩放,默认值更自然
|
||||
start : (() => void) | null = null,
|
||||
end : (() => void) | null = null
|
||||
) {
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
view.style.transitionTimingFunction = 'linear'
|
||||
// 设置透视视角
|
||||
view.style.perspective = `${cameraDistance}px`;
|
||||
view.style.transformStyle = "preserve-3d";
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${0}ms`;
|
||||
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${0}ms`;
|
||||
// 设置初始角度
|
||||
function setValue(value : number) {
|
||||
if (axis === 0) {
|
||||
view.style.transform = `rotateX(${value}deg) scaleZ(${scaleZ})`;
|
||||
} else if (axis === 1) {
|
||||
view.style.transform = `rotateY(${value}deg) scaleZ(${scaleZ})`;
|
||||
}
|
||||
}
|
||||
|
||||
setValue(fromDeg)
|
||||
|
||||
// 设置动画结束后的角度
|
||||
setTimeout(() => {
|
||||
// 设置动画延迟
|
||||
view.style.transitionDelay = `${delay}ms`;
|
||||
// 设置动画持续时间
|
||||
view.style.transitionDuration = `${duration}ms`;
|
||||
setValue(deg)
|
||||
// 动画开始回调
|
||||
if (start) start();
|
||||
}, delay || 50);
|
||||
|
||||
let _this = this;
|
||||
// 动画结束后的处理
|
||||
view.addEventListener('transitionend', () => {
|
||||
if (loop === -1) {
|
||||
// 永久循环
|
||||
_this.flip3D(view, duration, delay, axis, fromDeg, deg, loop, cameraDistance, scaleZ, start, end);
|
||||
} else if (loop > 0) {
|
||||
// 有限循环
|
||||
_this.flip3D(view, duration, delay, axis, fromDeg, deg, loop - 1, cameraDistance, scaleZ, start, end);
|
||||
} else {
|
||||
// 动画结束回调
|
||||
if (end) end();
|
||||
}
|
||||
}, { once: true });
|
||||
}
|
||||
public static clearAnimations(view : HTMLElement, _ : boolean = true) {
|
||||
view.style.removeProperty('transform')
|
||||
view.style.removeProperty('transition-delay')
|
||||
view.style.removeProperty('transition-duration')
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user