Skip to content

Commit

Permalink
用 SwiftUI 实现酷炫的颜色切换动画 (#6990)
Browse files Browse the repository at this point in the history
* 更新测试

* Revert "更新测试"

This reverts commit afb007d.

* 8 个值得了解的树形数据结构 (#6804)

* 8个值得了解的树形数据结构

8个值得了解的树形数据结构

* Update 8-Useful-Tree-Data-Structures-Worth-Knowing.md

* Update 8-useful-tree-data-structures-worth-knowing.md

Co-authored-by: sun <776766759@qq.com>

* 眼动跟踪和移动世界的最佳用户体验实践 (#6806)

* 眼动跟踪和移动世界的最佳用户体验实践

翻译完成

* 眼动跟踪和移动世界的最佳用户体验实践 #6806

谢谢指点~@xionglong58     @fanyijihua 根据第一轮校对意见修改完成

* 眼动追踪和移动世界的最佳用户体验实践

* 眼动追踪和移动世界的最佳用户体验实践

* 我并不讨厌箭头函数(#6610) (#6659)

* 我并不讨厌箭头函数(#6610)

* 我并不讨厌箭头函数(#6610) - 根据校对结果修改

* Update i-dont-hate-arrow-functions.md

Co-authored-by: 小添 <xiaotian@qunhemail.com>
Co-authored-by: sun <776766759@qq.com>

* 掌握 JavaScript 面试:什么是纯函数? (#6828)

* 掌握 JavaScript 面试:什么是纯函数?

掌握 JavaScript 面试:什么是纯函数?

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

Co-authored-by: lsvih <lsvih@qq.com>

* fix:文章翻译问题 (#6833)

* 用依赖注入来解耦你的代码 (#6823)

* translate(*): Part.1

* translate(*): Part.2

* translate(*): 完成翻译

* fix(*): 完成校对

* Create generator-functions-in-javascript.md (#6841)

* Create generator-functions-in-javascript.md

* Update generator-functions-in-javascript.md

* Create how-to-keep-your-dependencies-secure-and-up-to-date.md (#6843)

* Create how-to-keep-your-dependencies-secure-and-up-to-date.md

* Update how-to-keep-your-dependencies-secure-and-up-to-date.md

* Create deep-dive-into-react-fiber-internals.md (#6845)

* Create deep-dive-into-react-fiber-internals.md

* Update deep-dive-into-react-fiber-internals.md

* Update deep-dive-into-react-fiber-internals.md

* Update deep-dive-into-react-fiber-internals.md

* Create how-can-cloud-services-help-improve-your-businessess-efficiency.md (#6847)

* Create how-can-cloud-services-help-improve-your-businessess-efficiency.md

* Update how-can-cloud-services-help-improve-your-businessess-efficiency.md

* Create should-you-learn-vim-as-a-developer-in-2020.md (#6849)

* Go 发布新版 Protobuf API (#6827)

* Achieve translation

* 8 个值得了解的树形数据结构 (#6804)

* 8个值得了解的树形数据结构

8个值得了解的树形数据结构

* Update 8-Useful-Tree-Data-Structures-Worth-Knowing.md

* Update 8-useful-tree-data-structures-worth-knowing.md

Co-authored-by: sun <776766759@qq.com>

* 眼动跟踪和移动世界的最佳用户体验实践 (#6806)

* 眼动跟踪和移动世界的最佳用户体验实践

翻译完成

* 眼动跟踪和移动世界的最佳用户体验实践 #6806

谢谢指点~@xionglong58     @fanyijihua 根据第一轮校对意见修改完成

* 眼动追踪和移动世界的最佳用户体验实践

* 眼动追踪和移动世界的最佳用户体验实践

* 我并不讨厌箭头函数(#6610) (#6659)

* 我并不讨厌箭头函数(#6610)

* 我并不讨厌箭头函数(#6610) - 根据校对结果修改

* Update i-dont-hate-arrow-functions.md

Co-authored-by: 小添 <xiaotian@qunhemail.com>
Co-authored-by: sun <776766759@qq.com>

* 掌握 JavaScript 面试:什么是纯函数? (#6828)

* 掌握 JavaScript 面试:什么是纯函数?

掌握 JavaScript 面试:什么是纯函数?

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

* Update master-the-javascript-interview-what-is-a-pure-function.md

Co-authored-by: lsvih <lsvih@qq.com>

* Address comments

Co-authored-by: Amberlin1970 <37952468+Amberlin1970@users.noreply.github.com>
Co-authored-by: sun <776766759@qq.com>
Co-authored-by: Charlo <49369951+Charlo-O@users.noreply.github.com>
Co-authored-by: TiaossuP <tiaossup@yeah.net>
Co-authored-by: 小添 <xiaotian@qunhemail.com>
Co-authored-by: niayyy <yy761706@gmail.com>
Co-authored-by: lsvih <lsvih@qq.com>

* JSON.stringify() 的 5 个秘密特性 (#6793)

* Update 5-secret-features-of-json-stringify.md

* Update 5-secret-features-of-json-stringify.md

* Update 5-secret-features-of-json-stringify.md

* Update 5-secret-features-of-json-stringify.md

* Create high-speed-inserts-with-mysql.md (#6853)

* Create high-speed-inserts-with-mysql.md

* Update high-speed-inserts-with-mysql.md

* 组合软件:书 (#6832)

* Update composing-software-the-book.md

* Update composing-software-the-book.md

* Create 6-best-javascript-frameworks-in-2020.md (#6861)

* Create 6-best-javascript-frameworks-in-2020.md

* Update 6-best-javascript-frameworks-in-2020.md

* Update 6-best-javascript-frameworks-in-2020.md

* 2020 年用各大前端框架构建的 RealWorld 应用对比 (#6851)

* translation complete

* Update a-realworld-comparison-of-front-end-frameworks-2020.md

按照建议修改完成

* Update a-realworld-comparison-of-front-end-frameworks-2020.md

又修改了下破折号的格式

* Update a-realworld-comparison-of-front-end-frameworks-2020.md

修改了二级标题的显示问题

* Update a-realworld-comparison-of-front-end-frameworks-2020.md

添加相关个人信息

* Update a-realworld-comparison-of-front-end-frameworks-2020.md

Co-authored-by: lsvih <lsvih@qq.com>

* Create the-importance-of-why-docs.md (#6868)

* Create the-importance-of-why-docs.md

* Update the-importance-of-why-docs.md

* 不变性之道 (#6857)

* Update the-dao-of-immutability.md

* Update the-dao-of-immutability.md

* Update the-dao-of-immutability.md

* Update the-dao-of-immutability.md

* Update the-dao-of-immutability.md

* Update the-dao-of-immutability.md

Co-authored-by: lsvih <lsvih@qq.com>

* Create polymorphic-react-components.md (#6870)

* Create polymorphic-react-components.md

* Update polymorphic-react-components.md

* Update polymorphic-react-components.md

* Update polymorphic-react-components.md

* Create active-learning-in-machine-learning.md (#6872)

* Create kafka-vs-rabbitmq-why-use-kafka.md (#6874)

* Create kafka-vs-rabbitmq-why-use-kafka.md

* Update kafka-vs-rabbitmq-why-use-kafka.md

* Create i-built-an-app-that-uses-all-7-new-features-in-javascript-es2020.md (#6876)

* Create i-built-an-app-that-uses-all-7-new-features-in-javascript-es2020.md

* Update i-built-an-app-that-uses-all-7-new-features-in-javascript-es2020.md

* Update i-built-an-app-that-uses-all-7-new-features-in-javascript-es2020.md

* Update i-built-an-app-that-uses-all-7-new-features-in-javascript-es2020.md

* 云服务如何帮助你提高业务效率? (#6859)

* Update how-can-cloud-services-help-improve-your-businessess-efficiency.md

* Update how-can-cloud-services-help-improve-your-businessess-efficiency.md: revise according to proofreading suggestions

* Update how-can-cloud-services-help-improve-your-businessess-efficiency.md: revise according to Yinjias proofreading suggestions

* NestJS 实现基本用户认证和会话 (#6731)

* NestJS 实现基本用户认证和会话

NestJS 实现基本用户认证和会话

* fix:修改 NestJS 实现基本用户认证和会话

根据校对者意见,修改 NestJS 实现基本用户认证和会话

* Update nestjs-basic-auth-and-sessions.md

Co-authored-by: lsvih <lsvih@qq.com>

* 作为 2020 年的开发者,你应该学习 VIM 吗? (#6856)

* 更新测试

* Revert "更新测试"

This reverts commit afb007d.

* 作为2020年的开发者,你应该学习 VIM 吗?

* 校对更新

* 第二次校对修改

* 第三次校对修改

* Update TODO1/should-you-learn-vim-as-a-developer-in-2020.md

数字格式调整

Co-Authored-By: lsvih <lsvih@qq.com>

* Update TODO1/should-you-learn-vim-as-a-developer-in-2020.md

标题数字格式调整

Co-Authored-By: lsvih <lsvih@qq.com>

* 增加校对者名单

* 调整行数

* Update should-you-learn-vim-as-a-developer-in-2020.md

Co-authored-by: lsvih <lsvih@qq.com>

* MySQL 最佳实践—— 高效插入数据 (#6863)

* Finish translation

* Addressed comments

* 添加校对者信息

* Remove content with english

* Create combine-getting-started.md (#6883)

* Create combine-getting-started.md

* Update combine-getting-started.md

* Update combine-getting-started.md

* Create how-to-be-a-good-remote-developer.md (#6885)

* Create why-is-object-immutability-important.md (#6887)

* Create why-is-object-immutability-important.md

* Update why-is-object-immutability-important.md

* Create what-on-earth-is-the-shadow-dom-and-why-it-matters.md

* 2020 年排名前 6 位的 JavaScript 框架 (#6867)

* Update 6-best-javascript-frameworks-in-2020.md: Complete translation

* Update 6-best-javascript-frameworks-in-2020.md: revise according to 钱俊颖s and niayyys proofreading suggestions

* Update 6-best-javascript-frameworks-in-2020.md: add proofreaders' information

* JavaScript 风格元素 (#6878)

* JavaScript 风格元素

JavaScript 风格元素

* 翻译修改

* 修改标点符号

* 增加校对者信息

Co-authored-by: lsvih <lsvih@qq.com>

* 怎样让依赖库保持安全和最新 (#6864)

* 更新测试

* Revert "更新测试"

This reverts commit afb007d.

* 怎样让依赖库保持安全和最新

* 第一次校对提交(part)

* Create 5-best-practices-to-prevent-git-leaks.md (#6894)

* Create 5-best-practices-to-prevent-git-leaks.md

* Update 5-best-practices-to-prevent-git-leaks.md

* Create swiftui-3d-scroll-effect.md (#6896)

* Create swiftui-3d-scroll-effect.md

* Update swiftui-3d-scroll-effect.md

* Web 应用程序中的数据和 UI 分离 (#6794)

* Update separation-of-data-and-ui-in-your-web-app.md

* Update separation-of-data-and-ui-in-your-web-app.md

* fix:typo (#6903)

* 初译完成

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* Update TODO1/swiftui-animating-color-changes.md

Co-authored-by: lsvih <lsvih@qq.com>

* 增加校对者

Co-authored-by: Amberlin1970 <37952468+Amberlin1970@users.noreply.github.com>
Co-authored-by: sun <776766759@qq.com>
Co-authored-by: Charlo <49369951+Charlo-O@users.noreply.github.com>
Co-authored-by: TiaossuP <tiaossup@yeah.net>
Co-authored-by: 小添 <xiaotian@qunhemail.com>
Co-authored-by: niayyy <yy761706@gmail.com>
Co-authored-by: lsvih <lsvih@qq.com>
Co-authored-by: zoomdong <1344492820@qq.com>
Co-authored-by: 江不知 <448300947@qq.com>
Co-authored-by: 司徒公子 <todaycoder001@gmail.com>
Co-authored-by: jianhang <snowy.yu@foxmail.com>
Co-authored-by: Roc <qinrocdev@gmail.com>
Co-authored-by: Jessica <29631279+cyz980908@users.noreply.github.com>
Co-authored-by: Amy <46389309+febrainqu@users.noreply.github.com>
  • Loading branch information
15 people committed May 7, 2020
1 parent e2c21af commit b996928
Showing 1 changed file with 58 additions and 58 deletions.
116 changes: 58 additions & 58 deletions TODO1/swiftui-animating-color-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@
> * 原文作者:[Jean-Marc Boullianne](https://medium.com/@jboullianne)
> * 译文出自:[掘金翻译计划](https://github.com/xitu/gold-miner)
> * 本文永久链接:[https://github.com/xitu/gold-miner/blob/master/TODO1/swiftui-animating-color-changes.md](https://github.com/xitu/gold-miner/blob/master/TODO1/swiftui-animating-color-changes.md)
> * 译者:
> * 校对者:
> * 译者:[chaingangway](https://github.com/chaingangway)
> * 校对者:[lsvih](https://github.com/lsvih)
# SwiftUI: Animating Color Changes
# SwiftUI 实现酷炫的颜色切换动画

Time to spice up your color changes! You’re going to learn how to animate background color changes in SwiftUI using `Paths` and `AnimatableData`!
老铁们,是时候燥起来了!本文中我们将学习如何使用 SwiftUI 中的 `Paths` `AnimatableData` 来制作颜色切换动画。

![](https://cdn-images-1.medium.com/max/2000/0*ZiMbs5MNguBktfIt.gif)

![](https://cdn-images-1.medium.com/max/2000/0*Wc0gTdaBCBHCYpYL.gif)

What kind of color changing madness is this?!
这些快速切换的动画是怎么实现的呢?让我们来看下文吧!

#### Getting Started
#### 基础

The key to our background color changing magic is going to be creating our own custom SwiftUI `Shape` struct. We'll call it `SplashShape`. `Shape` structs utilize the function `path(in rect: CGRect) -> Path` to define what they look like. This is the function we'll be using to create the various animations.
要实现动画的关键是在 SwiftUI 中创建一个实现 `Shape` 协议的结构体。我们把它命名为 `SplashShape`。在 `Shape` 协议中,有一个方法叫做 `path(in rect: CGRect) -> Path`,这个方法可以用来设置图形的外观。我们就用这个方法来实现本文中的各种动画。

#### Create the SplashShape struct
#### 创建 SplashShape 结构体

Go ahead and create a new `Shape` struct called `SplashStruct`.
下面我们创建一个叫做 `SplashStruct` 的结构体,它继承于 `Shape` 协议。

```swift
import SwiftUI
Expand All @@ -34,13 +34,13 @@ struct SplashShape: Shape {
}
```

For starters we’ll be creating two animations. `leftToRight` and `rightToLeft` shown below.
我们首先创建两种动画类型:`leftToRight` `rightToLeft`,效果如下所示:

![`leftToRight` & `rightToLeft`](https://cdn-images-1.medium.com/max/2000/0*IhBr4_qhxe5FRnTN.gif)

#### SplashAnimation
#### Splash 动画

We will create an `enum` called `SplashAnimation` for our custom animations. This will allow us to easily add more animations in the future (see the end for more!).
我们创建一个名为 `SplashAnimation``枚举`来定义动画类型,便于以后更方便地扩展新动画(文章末尾可以验证!)。

```swift
import SwiftUI
Expand All @@ -58,7 +58,7 @@ struct SplashShape: Shape {
}
```

In our `path()` function we'll switch on which animation our shape is using and generate the required `Path` for the animation. But first, we must create variables to hold the animation type as well as the progress of the animation.
`path()` 方法中,我们可以选择需要使用的动画,并且返回动画的 `Path`。但是首先,我们必须创建变量来存储动画类型,记录动画过程。

```swift
import SwiftUI
Expand All @@ -79,11 +79,11 @@ struct SplashShape: Shape {
}
```

`progress` will be a value between `0` and `1`, which will detail how far we are through the animation of the color change. This will come in handy next when we write our `path()` function.
`progress` 的取值范围在 `0` `1` 之间,它代表整个动画的完成进度。当我们编写 `path()` 方法时,它就会派上用场。

#### Writing the path() function
#### 编写 path() 方法

As said earlier we need to figure out what type of animation we’re using in order to return the correct `Path`. Start off by writing a `switch` statement in your `path()` function using the `animationType` defined earlier.
跟之前说的一样,为了返回正确的 `Path`,我们需要明确正在使用哪一种动画。在 `path()` 方法中编写 `switch` 语句,并且用上我们之前定义的 `animationType`

```swift
func path(in rect: CGRect) -> Path {
Expand All @@ -96,11 +96,11 @@ func path(in rect: CGRect) -> Path {
}
```

As of right now, this will return empty paths. We need to actually create the functions to animate the paths.
现在这个方法只会返回空 paths。我们需要创建产生真实动画的方法。

#### Create The Animation Functions
#### 实现动画方法

Below your `path()` function, create two new functions called `leftToRight()` and `rightToLeft()` for each type of animation. Within each function, we will create a `Path` in the shape of a rectangle that will grow over time according to our `progress` variable.
`path()` 方法的下面,创建两个新的方法:`leftToRight()` `rightToLeft()`,每个方法表示一种动画类型。在每个方法体内,我们会创建一个矩形形状的 `Path`,它会根据 `progress` 变量的值随时间发生变换。

```swift
func leftToRight(rect: CGRect) -> Path {
Expand All @@ -124,7 +124,7 @@ func rightToLeft(rect: CGRect) -> Path {
}
```

Then utilize the two new functions in your `path()` function above.
然后在 `path()` 方法中调用上面两个新方法。

```swift
func path(in rect: CGRect) -> Path {
Expand All @@ -137,9 +137,9 @@ func path(in rect: CGRect) -> Path {
}
```

#### AnimatableData
#### 动画数据

In order to make sure Swift knows how to animate our `Shape` when the `progress` variable is changed, we need to specify which variable is animating. Just below our `progress` and `animationType` variables, define `animatableData`. It's a variable based on the [`Animatable` protocol](https://developer.apple.com/documentation/swiftui/animatable) which helps SwiftUI know how to animate views when they change.
为了确保 Swift 知道在更改 `progress `变量时如何对 `Shape` 进行动画处理,我们需要指定一个响应动画的变量。在 `progress` `animationType` 变量下面,定义 `animatableData`。这是一个基于[`Animatable` 协议](https://developer.apple.com/documentation/swiftui/animatable) 的变量,它可以通知 SwiftUI 在数据改变时,对视图进行动画处理。

```swift
var progress: CGFloat
Expand All @@ -153,11 +153,11 @@ var animatableData: CGFloat {

![`SplashShape` animating as `progress` changes.](https://cdn-images-1.medium.com/max/2000/0*8vr8fNf-Fa86z6XF.gif)

#### Animating the Color Change
#### 颜色切换时产生动画

Up to now we’ve created a `Shape` which will animate over time. Next we need to add this shape to a view and automatically animate it when the view's color changes. This is where `SplashView` comes in to play. We're going to create a `SplashView` to automatically update the `progress` variable of `SplashShape`. When `SplashView` receives a new `Color` it triggers the animation.
到目前为止,我们已经创建了一个 `Shape`,它将随着时间的变化而变化。接下来,我们需要将它添加到视图中,并在视图颜色改变时自动对其进行动画处理。这时候我们引入 `SplashView`。我们将创建一个 `SplashView` 来自动更新 `SplashShape``progress` 变量。当 `SplashView` 接收到新的 `Color` 时,它将触发动画。

Get started by creating the `SplashView` struct.
首先,我们创建 `SplashView` 结构体。

```swift
import SwiftUI
Expand All @@ -171,9 +171,9 @@ struct SplashView: View {
}
```

Remember our `SplashShape` takes a `SplashAnimation` enum as a parameter so we'll need to add this as a parameter to our `SplashView`. In addition, we're animating the background color change of the view, so we'll need to take in a `Color` as well. Our initializer is detailed below.
`SplashShape` 需要使用 `SplashAnimation` 枚举作为参数,所以我们会把它作为参数传递给 `SplashView`。另外,我们要在视图的背景颜色变化时设置动画,所以我们也要传递 `Color` 参数。这些细节会在我们的初始化方法中详细说明。

`ColorStore` is a custom ObservableObject. It is used to recieve `Color` updates in the `SplashView` struct, so that we can initiate the `SplashShape` animation, and ultimately the background color change. We'll show how that works in a second.
`ColorStore` 是自定义的 ObservableObject。它用来监听 `SplashView` 结构体中 `Color` 值的改变,以便我们可以初始化 `SplashShape` 动画,并最终改变背景颜色。我们稍后展示它的工作原理。

```swift
struct SplashView: View {
Expand Down Expand Up @@ -204,9 +204,9 @@ class ColorStore: ObservableObject {
}
```

#### Creating the SplashView body
#### 构建 SplashView body

Inside the `body` variable we need to return a `Rectangle` set to the current color of the `SplashView`. Then using the `ColorStore` Obseravble Object defined earlier, we can receive color updates to animate our view.
`body` 内部,我们需要返回一个 `Rectangle`,它和 `SplashView` 当前的颜色保持一致。然后使用之前定义的 `ColorStore`,以便于我们接收更新的颜色值来驱动动画。

```swift
var body: some View {
Expand All @@ -218,13 +218,13 @@ var body: some View {
}
```

When changing the colors, we need some way to keep track of the color that the `SplashView` is being changed to, as well as the progress. We'll define the `layers` variable in order to do this.
当颜色改变时,我们需要记录 `SplashView` 中正在改变的颜色和进度。为此,我们定义 `layers` 变量。

```
@State var layers: [(Color,CGFloat)] = [] // New Color & Progress
```

Now back inside our `body` variable we need to add the newly received `Colors` to the `layers` variable. When we add them, we set the progress to `0` since they were just added. Then, over the course of half a second we animate their progress to `1`.
现在回到 `body` 变量内部,我们给 `layers` 变量添加新接收的 `Colors` 。添加的时候我们把进度设置为 `0`。然后,在半秒之内的动画过程中,我们把进度设置为 `1`

```swift
var body: some View {
Expand All @@ -241,7 +241,7 @@ var body: some View {
}
```

As of right now, this will add the new colors to the` layers` variable, but they aren't displayed on top of the `SplashView`. To do this we need to display each layer as an overlay on the `Rectangle` inside the `body` variable.
现在在这段代码中,`layers` 变量中添加了更新后的颜色,但是颜色并没有展示出来。为了展示颜色,我们需要在 `body` 变量内部为 `Rectangle` 的每一个图层添加一个覆盖层。

```swift
var body: some View {
Expand All @@ -268,9 +268,9 @@ var body: some View {
}
```

#### Give it a Run
#### 测试效果

Using the code below you can give it a run inside an emulator. What this does, is when the button inside `ContentView` is pressed, it advances the `index` used to select the `SplashView` color, which triggers an update to the `ColorStore` inside. This make the `SplashView` add a `SplashShape` layer and animate it's addition to the view.
你可以在模拟器中运行下面的代码。这段代码的意思是,当你点击 `ContentView` 中的按钮时,它会计算 `index` 来选择 `SplashView` 中的颜色,同时也会触发 `ColorStore` 内部的更新。所以,当 `SplashShape` 图层添加到 `SplashView` 时,就会触发动画。

```swift
import SwiftUI
Expand Down Expand Up @@ -302,11 +302,11 @@ struct ContentView: View {

![Color Changing Goodness!](https://cdn-images-1.medium.com/max/2000/0*0cplu29bi4dyHzkt.gif)

#### Not Finished Yet!
#### 还没有完成!

We’re missing one thing. AS of right now, we’re continuously adding layer upon layer to our `SplashView`. We need to make sure we delete those layers after they finish animating and are displayed.
我们还有一个功能没实现。现在我们持续地把图层添加到 `SplashView` 上,但是没有删除它们。因此,我们需要在动画完成时把这些图层清理掉。

Inside your `onReceive()` function inside your `SplashView` struct's `body` variable, make the following change:
`SplashView` 结构体 `body` 变量的 `onReceive()` 方法内部,做如下改变:

```swift
.onReceive(self.colorStore.$color) { color in
Expand All @@ -322,25 +322,25 @@ Inside your `onReceive()` function inside your `SplashView` struct's `body` vari
}
```

This makes sure we delete old entries to the `layers` array and that our `SplashView` is showing the correct background color based on the latest update.
这行代码能让我们删除 `layers` 数组中使用过的值,并确保 `SplashView` 基于最新更新的值显示正确的背景色。

#### Show us What You Made!
#### 展示成果!

Have you completed one of my tutorials? Send me a screenshot or drop me a link to the project. [TrailingClosure.com](https://trailingclosure.com) will be featuring user’s work! Find us on Twitter [@TrailingClosure](https://twitter.com/TrailingClosure), or email us at [howdy@TrailingClosure.com](mailto:howdy@trailingclosure.com)
您完成了本教程的案例吗?您可以给我发一个截图或者链接来展示你的成果。[TrailingClosure.com](https://trailingclosure.com) 将会为用户的成果制作专题。您可以通过 Twitter [@TrailingClosure](https://twitter.com/TrailingClosure)联系我们,或者给我们发邮件 [howdy@TrailingClosure.com](mailto:howdy@trailingclosure.com)

![](https://cdn-images-1.medium.com/max/2000/0*vuSb0VxT6pvGpp9z.gif)

#### Source Code Posted on GitHub
#### GitHub 源码

Checkout the [source code](https://github.com/jboullianne/SplashView) for this tutorial on my Github! Full source code for both `SplashShape` and `SplashView` are included, in addition to the examples shown. .... But wait, there's more!
您可以在我的 Github 上查看本教程的[源代码](https://github.com/jboullianne/SplashView)!除了显示的示例外,还包括 `SplashShape` ` SplashView` 的完整源代码。 ....但是等等,还有更多!

#### EXTRA CREDIT!
#### 彩蛋!

If you’re familiar with my previous tutorials, you know I love extra credit 😉. I said in the beginning there would be more animations. This is the moment you’ve been waiting for…. **drum roll**.
如果你熟悉我之前的教程,你应该了解我喜欢彩蛋 😉。在本文开头,我说过会实现更多动画。此刻终于来了…… **击鼓**…。

## SplashAnimation 🥳
## Splash 动画 🥳

Wooohoo!! Remember this? I told you we’d come back to it to add more animation types.
哈哈哈!!还记得吗?我说过会添加更多动画种类。

```swift
enum SplashAnimation {
Expand Down Expand Up @@ -372,13 +372,13 @@ func path(in rect: CGRect) -> Path {
}
```

I know what you’re thinking… **Whoa, that’s a lot of extra credit…**. Don’t fret. By modifying our `path()` function inside `SplashShape`, and creating just a few more functions, we'll be animating like no one's business.
你肯定会想…… **哇, 彩蛋也太多了……**。不必苦恼。我们只需要在 `SplashShape``path()` 方法中添加几个方法,就能搞定。

Let’s take this animation by animation
下面我们逐个动画来搞定…

#### topToBottom & bottomToTop
#### topToBottom bottomToTop 动画

Much like `leftToRight` and `rightToLeft` these functions create a path which starts from the bottom or top of the shape and grows over time using the `progress` variable.
这些方法与 `leftToRight` `rightToLeft` 非常相似,它们从 shape 的底部或顶部开始创建 path ,并使用 `progress` 变量随时间对其进行变换。

```swift
func topToBottom(rect: CGRect) -> Path {
Expand All @@ -404,13 +404,13 @@ func bottomToTop(rect: CGRect) -> Path {

![](https://cdn-images-1.medium.com/max/2000/0*R5UO4dzgtvlUUjtC.gif)

#### circle
#### circle 动画

If you remember some of your grade school geometry, you’ll know the Pythagorean Theorem. `a^2 + b^2 = c^2`
如果你还记得小学几何知识,就应该了解勾股定理。`a^2 + b^2 = c^2`

![`c` is the radius of the final circle our path needs to draw](https://cdn-images-1.medium.com/max/2100/0*taOHhdEX-GycqkbL.png)

`a` and `b` can be considered our rectangle's `height` and `width`. This allows us to solve for `c`, the radius of the circle that is required to cover the entirety of the rectangle. We can build the circular path from this and grow it over time using the `progress` variable.
`a` `b` 可以视为矩形的 `高度``宽度`,我们能够根据它们求得 `c`,即覆盖整个矩形所需的圆的半径。我们以此为基础构建圆的 path,并使用 `progress` 变量随时间对它进行变换。

```swift
func circle(rect: CGRect) -> Path {
Expand All @@ -431,13 +431,13 @@ func circle(rect: CGRect) -> Path {

![Animating Using a Circle Path](https://cdn-images-1.medium.com/max/2000/0*a4qFyDe5jvcD-B1J.gif)

#### angle
#### angle 动画

This one is a little more involved. You need to calculate the slope of the angle using the tangent. Then create a line with the given slope. You’ll plot this line as a right triangle as you move the line across the rectangle. See the picture below. The various colored lines represent the line moving over time to cover the entire rectangle.
这个动画知识点有点多。你需要使用切线计算角度的斜率,然后根据这个斜率创建一条直线。在矩形上移动这条直线时,根据它来绘制一个直角三角形。参见下图,各种彩色的线表示该线随时间移动时,覆盖整个矩形的状态。

![The line moves in order from the red, blue, green, then purple. to cover the rectangle](https://cdn-images-1.medium.com/max/2000/0*ogi8WYEI-T3-GsWh.png)

The function is as follows:
方法如下:

```swift
func angle(rect: CGRect, angle: Angle) -> Path {
Expand Down Expand Up @@ -487,9 +487,9 @@ func angle(rect: CGRect, angle: Angle) -> Path {

![Angles 45°, 135°, 225°, 315°](https://cdn-images-1.medium.com/max/2000/0*gxQtfGVNpOr50amB.gif)

#### Support Future Tutorials Like This One!
#### 请支持我!

Please consider subscribing using this [link](https://trailingclosure.com/signup/). If you aren’t reading this on [TrailingClosure.com](https://trailingclosure.com/), please come check us out sometime!
您可以用此[链接](https://trailingclosure.com/signup)进行订阅。如果您不是在 [TrailingClosure.com](https://trailingclosure.com/)上阅读本文,以后可以来逛逛!

> 如果发现译文存在错误或其他需要改进的地方,欢迎到 [掘金翻译计划](https://github.com/xitu/gold-miner) 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 **本文永久链接** 即为本文在 GitHub 上的 MarkDown 链接。
Expand Down

0 comments on commit b996928

Please sign in to comment.