This commit is contained in:
2026-09-24 16:25:22 +08:00
commit 7428184f01
1198 changed files with 314515 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
## 1.0.02025-02-13
* 全端兼容
+83
View File
@@ -0,0 +1,83 @@
{
"id": "x-animation-s",
"displayName": "x-animation-s",
"version": "1.0.0",
"description": "x-animation-s",
"keywords": [
"x-animation-s"
],
"repository": "",
"engines": {
"HBuilderX": "^3.6.8"
},
"dcloudext": {
"type": "uts",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "",
"data": "",
"permissions": ""
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "u",
"aliyun": "u",
"alipay": "u"
},
"client": {
"Vue": {
"vue2": "u",
"vue3": "u"
},
"App": {
"app-android": "u",
"app-ios": "u",
"app-harmony": "u"
},
"H5-mobile": {
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
+206
View File
@@ -0,0 +1,206 @@
# x-animation-s
### 开发文档
[TMUI4.0文档](https://xui.tmui.design/)
[TMUI4.0组件库](https://ext.dcloud.net.cn/plugin?id=16369)
### 功能特色
这是原生动画,性能好,有3d旋转效果,给你的应用增彩。基于原生实现,非CSS样式动画,具有高性能和流畅的动画效果。
### 兼容性
| IOS | Android | WEB | 小程序 |
| --- | --- | --- | --- |
| 支持 | 支持 | 支持 | 支持 |
### 说明
这是tmui4.0|XUI的原生插件附赠插件。种子用户可免于购买。
### 使用前提
需要自定义基座运行,且安卓5.0+(含5.0)以上支持。
### API接口说明
#### 1. translate - 位移动画
```ts
interface XDANIMATION_TRANSLATE_OPTIONS {
ele: UniElement|null; // 目标元素
duration?: number; // 动画持续时间,默认1000ms
delay?: number; // 延迟执行时间,默认0ms
translation?: number; // 位移方向,默认0
from?: number; // 起始位置,默认360
len?: number; // 位移距离,默认360
loop?: number; // 循环次数,默认0
start?: Function; // 动画开始回调
end?: Function; // 动画结束回调
}
```
#### 2. rotate - 旋转动画
```ts
interface XDANIMATION_ROTATE_OPTIONS {
ele: UniElement|null; // 目标元素
duration?: number; // 动画持续时间,默认1000ms
delay?: number; // 延迟执行时间,默认0ms
from?: number; // 起始角度,默认0
deg?: number; // 旋转角度,默认360
loop?: number; // 循环次数,默认0
start?: Function; // 动画开始回调
end?: Function; // 动画结束回调
}
```
#### 3. scale - 缩放动画
```ts
interface XDANIMATION_SCALE_OPTIONS {
ele: UniElement|null; // 目标元素
duration?: number; // 动画持续时间,默认1000ms
delay?: number; // 延迟执行时间,默认0ms
direction?: number; // 缩放方向,默认2
scale?: number; // 目标缩放比例,默认1
from?: number; // 起始缩放比例,默认0
loop?: number; // 循环次数,默认0
start?: Function; // 动画开始回调
end?: Function; // 动画结束回调
}
```
#### 4. flip3D - 3D翻转动画
```ts
interface XDANIMATION_FLIP3D_OPTIONS {
ele: UniElement|null; // 目标元素
duration?: number; // 动画持续时间,默认1000ms
delay?: number; // 延迟执行时间,默认0ms
axis?: number; // 翻转轴,默认1
from?: number; // 起始角度,默认0
deg?: number; // 翻转角度,默认360
loop?: number; // 循环次数,默认0
cameraDistance?: number; // 摄像机距离,默认12
scaleZ?: number; // Z轴缩放,默认0.5
start?: Function; // 动画开始回调
end?: Function; // 动画结束回调
}
```
### 特别注意事项
1. **iOS平台3D翻转限制**
- iOS平台下,3D翻转角度只能在0-180度之间
- 如需实现360度翻转,需要分段执行:
1. 先执行0-180度翻转
2. 在回调中执行180-0度翻转
2. **生命周期回调**
- start:动画开始时触发
- end:动画结束时触发
- 可以在回调中执行连续动画或其他操作
### 使用示例
```vue
<template>
<x-sheet id="xta">
<view>动画目标元素</view>
</x-sheet>
</template>
<script setup>
import { xAnimationS } from '@/uni_modules/x-animation-s';
// iOS平台360度翻转示例
const flip360 = () => {
// #ifdef APP-IOS
xAnimationS.flip3D({
ele: uni.getElementById("xta"),
deg: 180,
from: 0,
duration: 500,
end: () => {
xAnimationS.flip3D({
ele: uni.getElementById("xta"),
deg: 0,
from: 180,
duration: 500
})
}
})
// #endif
// #ifndef APP-IOS
xAnimationS.flip3D({
ele: uni.getElementById("xta"),
deg: 360,
from: 0,
duration: 1000
})
// #endif
}
// 缩放示例
const scaleAnimation = () => {
xAnimationS.scale({
ele: uni.getElementById("xta"),
duration: 320,
direction: 2,
from: 0.6,
scale: 1
})
}
// 位移示例
const translateAnimation = () => {
xAnimationS.translate({
ele: uni.getElementById("xta"),
duration: 320,
translation: 0,
from: 0,
len: -100
})
}
// 旋转示例
const rotateAnimation = () => {
xAnimationS.rotate({
ele: uni.getElementById("xta"),
duration: 1000,
from: 0,
deg: 360
})
}
</script>
```
### 动画组合示例
```ts
// 连续动画示例:缩放-旋转-位移
const complexAnimation = () => {
xAnimationS.scale({
ele: uni.getElementById("xta"),
duration: 500,
from: 1,
scale: 1.2,
end: () => {
xAnimationS.rotate({
ele: uni.getElementById("xta"),
duration: 500,
deg: 180,
end: () => {
xAnimationS.translate({
ele: uni.getElementById("xta"),
duration: 500,
len: 100
})
}
})
}
})
}
```
@@ -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, // 0x,1y,2x,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')
}
}