Tweener 2.1.1

Tweener 2.1.1

Alejandro Ramirez Varela 维护。



Tweener 2.1.1

Swift Tweener

Swift 动画引擎,创造更强大、更具创造力的应用。

Logo

该项目是基于CocoaTweener纯 Swift 重新编写的

先决条件

  • Swift 5.0

功能

声明式和链式语法

现在,使用声明式语法和 Tweener 链接,创建一个 Tweener

Tween(myView)
.duration(1.0)
.ease(.inOutCubic)
.to(
    .key(\.alpha, 1.0),
    .key(\.frame, CGRect(x:20.0,
                         y:20.0,
                         width:UIScreen.main.bounds.width - 40,
                         height:UIScreen.main.bounds.width - 40)),
    .key(\.backgroundColor!, .red)//NOTE:This property is an optional, add ! to keypath.
)
.onComplete { print("Tween complete") }
.after()//Creates a new tween after with same target and properties.
.duration(1.0)
.ease(Ease.outBounce)
.to(
    .key(\.alpha, 0.25),
    .key(\.frame, CGRect(x:20.0, y:20.0, width:100.0, height:100.0)),
    .key(\.backgroundColor!, .blue)
)
.play()

创建 Timeline

Timeline(
    
    //Place tweens here, separated by commas.
    
    //Tween 1
    Tween(myView)
    .ease(.inOutQuad)
    .to(.key(\.center, .zero) )
    .onStart {
        self.flipX(inverted: true)
    }
    .onComplete { print("Tween 1 complete") },
    
    //Tween 2
    Tween(myView)
    .to(.key(\.center, self.center) )
    .onStart {
        self.flipY()
    }
    .onComplete { print("Tween 2 complete") }
    
    //Etc....
)
.play()

视图扩展

为了使其更加友好,现在包含 UIView 和 NSView 的扩展,带有预定义动画,只需在视图实例中调用单个函数即可使用。

.spring()                     
.zoomIn()
.zoomOut()
.pop()
.fadeIn()
.fadeOut()
.flyLeft()
.flyRight()
.flyTop()
.flyBottom()
.slideLeft()
.slideRight()
.slideTop()
.slideBottom()
.flipX()
.flipY()
.shake()
.jiggle()
.bounce()
.swing()
.spin()
.loop()

View's extensions

任何对象类型支持

要为其他类型和自定义类型添加支持,假设有一个这样的结构体

public struct Vector3{
    var x, y, z: Double
    func buffer() -> [Double] { return [x, y, z] }
    static func zero() -> Vector3 { return Vector3(x:0.0, y:0.0, z:0.0) }
    static var random: Vector3 {
         return Vector3( x:.random(in: 0...1.0),
                         y:.random(in: 0...1.0),
                         z:.random(in: 0...1.0)
         )
    }
}

Tweener 基于 Double 数组,因此你必须告诉它如何将对象转换为数组以及如何从数组转换回对象。

Tweener.addType(
                toType:{ values in return Vector3(x:values[0], y:values[1], z:values[2]) },
                toArray:{ point in return point.buffer() }
                )

现在,你可以对 'Vector3' 类型对象进行动画。

Tween(myInstance)
.to(.key(\.myVec3Property, .random))
.play()

MacOS 支持

此版本包含 macOS 支持和示例。

Mac samples

安装

使用 Cocoapods 安装

要集成安装,请使用此 gem 安装 Cocoa Pods

$ gem install cocoapods

现在,将 Tweener 添加到您的 Podfile

pod 'Tweener', '~> 2.1.1'

要安装依赖,请运行此命令

pod install

使用 Carthage 安装

要集成安装,请使用 brew 安装 Carthage

$ brew update
$ brew install carthage

现在,将 Tweener 添加到您的 Cartfile

github "alexrvarela/SwiftTweener" ~> 2.1.1

要安装依赖,请运行此命令

$ carthage update

最后,将 Tweener.framework 拖放到您的 Xcode 项目中

使用 Swift 包管理器安装

要安装,请将依赖项添加到您的 Package.swift

dependencies: [
    .package(url: "https://github.com/alexrvarela/SwiftTweener.git", .upToNextMajor(from: "2.1.1"))
]

手动安装

下载、构建并将Tweener.framework复制到您的Xcode项目中。

用法

将Tweener引擎导入到您的项目中

import Tweener

默认情况下,可以动画化以下任何类型的属性:整型、浮点型、双精度浮点型、CGFloat、CGPoint、CGRect、UIColor、CGAffineTransform、CATransform3D

首先设置初始状态

myView.alpha = 0.25
myView.frame = CGRect(x:20, y:20, width:50, height:50)
myView.backgroundColor = .blue

创建并添加一个简单的Tweener

Tween(myView)
.duration(1.0)//One second
.ease(.inOutCubic)
.to(
    .key(\.alpha, 1.0),
    .key(\.frame,CGRect(x:20, y:20, width:250, height:250)),
    .key(\.backgroundColor!, .red)
)
.play()

或者使用'from'和'to'键

Tween(myView)
.duration(1.0)//One second
.ease(.inOutCubic)
.from(
    .key(\.alpha, 0.25),
    .key(\.frame, CGRect(x:20, y:20, width:50, height:50)),
    .key(\.backgroundColor!, .blue)
)
.to(
    .key(\.alpha, 1.0),
    .key(\.frame,CGRect(x:20, y:20, width:250, height:250)),
    .key(\.backgroundColor!, .red)
)
.play()

要从引擎中删除一个Tweener,只需调用stop()方法。

myTween.stop()

Simple tween

链式调用Tweener

要创建并链式调用具有相同目标和工作属性的新Tweener,只需调用.after()方法。

    let firstTween = Tween(myViewInstance)
    // This creates and chains a new tween whith time delay after 'firstTween'.
    let secondTween = firstTween.after()
    //This plays firstTween and secondTween.
    secondTween.play()

要创建并链式调用具有不同目标和类型的新Tweener,请将第二个Tweener作为参数传入。

    let firstTween = Tween(myViewInstance)
    let secondTween = Tween(otherViewInstance)
    // This chains booth and sets the second one after first one.
    firstTween.after(secondTween)
    //This plays firstTween and secondTween.
    secondTween.play()

您可以根据需要链式调用任意数量的Tweener。

Tweener处理程序

使用块处理程序与您的代码互动

myTween.onStart {
    self.backgroundColor = .green
}

myTween.onUpdate {
    doAnything()
}

myTween.onComplete {
    self.backgroundColor = .red
}

myTween.onOverwrite {
    self.backgroundColor = .blue
}

Handlers

在Engine中删除和暂停现有Tweener

您可以暂停、恢复和删除现有的Tweener

对于所有现有的Tweener

Tweener.pauseAllTweens()
Tweener.resumeAllTweens()
Tweener.removeAllTweens()

按目标

Tweener.pauseTweens(target:myView)
Tweener.resumeTweens(target:myView)
Tweener.removeTweens(target:myView)

按目标的具体属性

Tweener.pauseTweens(target:myView, keys:[\UIView.backgroundColor, \UIView.alpha])
Tweener.resumeTweens(target:myView, keys:[\UIView.backgroundColor, \UIView.alpha])
Tweener.removeTweens(target:myView, keys:[\UIView.backgroundColor, \UIView.alpha])

发挥您的创意!

触摸点样本

Touch

拖拽视图样本

Drag

暂停Tweener样本

Background animations

缓动

本引擎基于Robert Penner的缓动方程

Easing curves

创建一个自定义的缓动方程

extension Ease{
    public static let custom = Ease(equation:{ (t, b, c, d) in
        //Play with code here!
        if t < d/2 {return Ease.inBack.equation(t*2, b, c/2, d)}
        return Ease.outElastic.equation((t*2)-d, b+c/2, c/2, d)
    })
}

然后使用它

Tween(myView)
    .ease(.custom)
    .to(.key(\.frame, CGRect(x:20.0, y:20.0, width:280.0, height:280.0)))
    .play()

时间轴

添加补间动画还是使用时间轴动画?

这取决于你想做什么,补间动画只将动画“移动”到目标值,默认设置总是从当前值开始,这使你的App更具动态性;每个补间动画在动画完成后立即被销毁。

时间轴存储每个补间的“起始”和“结束”值,包含一系列可重用的补间;要创建时间轴并添加补间,请使用下面的代码

let myTimeline = Timeline()
.add(
    myTween1, 
    myTween2
    //etc...
)
.play()

你可以与时间轴的播放模式进行交互,默认值是单次播放,动画完成后停止;要更改时间轴的播放模式

循环,永远重复

myTimeline.playMode(.loop)

Loop

ping-pong,向前和向后

myTimeline.playMode(.pingPong)

Ping Pong

要从引擎中移除时间轴,只需调用stop()方法。

myTimeline.stop()

使用UIScrollView控制时间轴来执行视差滚动效果

Timeline scroll

时间轴检查器

您可以使用时间轴检查器来调试和编辑补间动画

实时可视化补间动画

Visualize Tweens in real time!

编辑补间动画

Edit Tweens Scale timeline editor

要创建时间轴检查器

let myInspector = TimelineInspector(timeline:myTimeline)
addSubview(myInspector)

PDFImageView

使用带有图像流依赖关系的PDFImageView,并轻松导入你的矢量资源,忘记将文件导出为SVG和其他格式iOS提供了对PDF的本地支持,使用CoreGraphics,该类只需在UIImageView中渲染一个PDF文件

要从App bundle加载名为“bee.pdf”的资产

let myAsset = PDFImageView(bundlename:"bee")
addSubview(myAsset)

你可以用一个简单的属性增大或减小你的资源大小

myAsset.scale = 1.5

目标

使用Aims创建更复杂、更令人印象深刻的动画

Aims

PathAim

使用路径控制运动

Path aim Text path aim

let myPathAim = PathAim(target:myAsset)
myPathAim.path = myBezierPath

要改变路径上的位置,请更改此属性值

myPathAim.interpolation = 0.5

并简单地动画化路径插值

Tween(myPathAim) 
.from(.key(\.interpolation, 0.0))
.to(.key(\.interpolation, 1.0))
.play()

您可以使用此简单的脚本将路径导出为代码,从Illustrator中:https://github.com/alexrvarela/generatePathCode

RotationAim

动画任何视图的旋转

Rotation aim

let myRotationAim = RotationAim(target:myView)

Tween(myRotationAim)
.from(.key(\.angle, 90.0))
.to(.key(\.angle, 360.0))
.play()

ArcAim

创建弧形动画

Arc aims

let myArcAim = ArcAim(target:myView)

//Set desired radius
myArcAim.radius = 100.0

//Animate arc angle
Tween(myArcAim)
.from(.key(\.arcAngle, 0.0))
.to(.key(\.arcAngle, 360.0))
.play()

StringAim

动画文本过渡

String aims

//Create string aim
let stringAim = StringAim(target:myUILabel, keyPath:\UILabel.text)
stringAim.from = "hello"
stringAim.to = "hola"

//Set initial interpolation
stringAim.interpolation = 0.0

//Animate, using timeline to repeat forever.
Timeline(

    //Create tween with StringAim target and animate interpolation.
    Tween(stringAim)
    .delay(0.5)
    .duration(0.5)
    .from(.key(\.interpolation, 0.0))
    .to(.key(\.interpolation, 1.0))
    .onComplete { self.swapText() }
    
)
.mode(.loop)
.play()

玩转所有功能,结合不同的Aim类型

Mix different aims

TweenVisualizer

实时可视化所有缓动和时间线

创建一个TweenVisualizer并将其附加到Tweener的更新循环中

let visualizer = TweenVisualizer()
visualizer.center = viewController.view.center
Tweener.addVisualizer(visualizer)

//Add to UIView
addSubview(visualizer)

要从不更新循环中分离可视化器,请使用此代码

Tweener.removeVisualizer(visualizer)

Visualizer

您还可以根据需要拖动、缩放和调整可视化器的大小,只需拖动右下角即可调整大小:Drag Pinch Resize

此库被创建出来是为了给UI元素增添动态,如果您想要制作更为复杂的动画,我建议您使用Lottie来实现。

贡献

欢迎提交pull请求!下一个版本将包括:SwiftUI示例、watchOs和tvOs示例以及单元测试。

作者

  • Alejandro Ramírez Varela - 初始工作 - alexrvarela

许可证

本项目使用MIT许可证 - 请参阅LICENSE文件以获取详细信息。

感谢