大约一个月前,我们告诉您 我们如何在 Swift 中开发类似 Tinder 的 Koloda 。动画在开发者和设计师社区中证明是成功的,所以我们决定继续玩它。
在我们推出第一个更简单的 Koloda 动画版本后, 我们的设计师 Dmitry Goncharov 坚持实施他的下一个想法。此外,我们的 iOS 开发人员和第一个 Koloda 动画的创建者 Eugene Andreyev 承诺进一步自定义帧的计算,以便任何开发人员都可以基于我们的开源项目制作自己独特的组件。
所以这是我们关于 Koloda 故事的第二章。这次我们将讨论设计和开发。同时你也可以在 Dribbble 和 GitHub 上查看动画。
我们如何在 Pixate 中制作 Koloda 原型
德米特里·冈恰洛夫 (Dmitry Goncharov)
我受到类似 Tinder 的概念的启发,并决定详细阐述将 Koloda 变成不寻常的东西的最初想法。令人惊讶的是,几个小时后我想到了一个新概念。我的想法是摆脱一副纸牌并从背景中收集下一张纸牌。
我在 Photoshop 中设计了模型,并使用 Pixate 对其进行了原型制作。 Pixate 是类似于 InVision、Marvel、Origami、Form 等的设计工具。尽管在 Pixate 中制作原型比在 InVision 中花费更多时间,但结果看起来几乎就像一个真正的应用程序。我创建的原型完全按照我想要的方式再现了卡片的行为。
现在让我们谈谈这个过程。
Pixate 的主要工具集包括图层、动作套件和动画。在资产加载并位于画板上后,您可以开始在图层上工作,然后继续复制交互。
起初,我必须让卡片水平移动,一旦它们越过某条垂直线就飞离屏幕。我在一个简单的动画的帮助下做到了这一点,它可以在某些 if 条件下实现。我还让卡片在交互过程中改变了透明度并旋转了一点。
然后,我需要让一张新卡片看起来像是从背景中收集起来一样,所以必须拉伸和缩放它。我将原型的比例从 3.5 倍(当卡片仍在背景上时的尺寸)设置为 1 倍。
为了获得更好的效果,我添加了一些弹跳动画,仅此而已!原型已准备好进行开发。我想以我对 Pixate 的总体印象作为总结。
优点:
- 在移动设备上预览
- 简单的原型制作过程
- 无需具备动画基础知识的具体知识
- 原型看起来很像真正的 iOS 或 Android 应用程序
- 方便的项目共享(导出到电脑、外部链接或二维码)
缺点:
- 原型并不涵盖所有应用程序的功能,而是用于演示单独的功能和交互
- 单个画板无法容纳原型的所有屏幕
- 无法将原型导出为代码
- 网络应用程序有点问题
- 基本资产套件非常有限
- 没有动画时间轴(以防您习惯 After Effects)
尽管有这些缺点,Pixate 是一个很棒的工具,它可以让设计师创建原生的可点击原型,重现导航模式和屏幕之间的交互,但最重要的是,它可以帮助整个团队理解项目开发的总体方向。 您可以观看 Jared Lodwick 的教程 以了解有关 Pixate 的更多信息。
现在你对 Koloda 的原型设计有了一些了解,是时候谈谈我们是如何开发第二版动画的了!
[科洛达动画第2版]
我们如何开发 Koloda v.2
尤金·安德烈耶夫
Koloda 动画第一版和第二版的主要区别在于卡片布局。新版本中的前卡位于屏幕中间,后卡在背景上拉伸。另外,后卡不响应前卡的移动,在前卡刷完后以弹跳效果到达。
此外,Koloda 的第二个版本更容易构建,因为 Dima 在 Pixate 中制作了它的原型。首先,Pixate 允许我观察原型上的所有交互。其次,我可以访问 Pixate studio 查看所有应用的转换及其顺序,然后只需将它们传递到代码中,而无需手动调整任何内容。
最后,Koloda 的第二个版本是旅行应用程序的一部分,这与第一个完全关于摇滚乐的版本不同。
[Koloda 动画版 1]
KolodaView v.2 的实现
为了实现 Dima 的动画,我不得不以不同的方式放置卡片,所以我将 上一篇 文章 (在 KolodaView 实现段落中)描述的魔术方法 frameForCardAtIndex 放在公共接口中。
在 KolodaView 继承者中,我覆盖了该方法并按以下顺序放置卡片:
override func frameForCardAtIndex(index: UInt) -> CGRect {
if index == 0 {
let bottomOffset:CGFloat = defaultBottomOffset
let topOffset:CGFloat = defaultTopOffset
let xOffset:CGFloat = defaultHorizontalOffset
let width = CGRectGetWidth(self.frame ) - 2 * defaultHorizontalOffset
let height = width * defaultHeightRatio
let yOffset:CGFloat = topOffset
let frame = CGRect(x: xOffset, y: yOffset, width: width, height: height)
return frame
} else if index == 1 {
let horizontalMargin = -self.bounds.width * backgroundCardHorizontalMarginMultiplier
let width = self.bounds.width * backgroundCardScalePercent
let height = width * defaultHeightRatio
return CGRect(x: horizontalMargin, y: 0, width: width, height: height)
}
return CGRectZero
}
这里发生了什么?我们放置 frontCard 在 KolodaView 的中间,并用等于 1.5 的 scalePercent 拉伸背景卡片。
背景卡片的弹跳动画
由于背景卡带有弹跳效果并在移动时改变其透明度,因此我创建了一个新的委托方法:
override func frameForCardAtIndex(index: UInt) -> CGRect {
if index == 0 {
let bottomOffset:CGFloat = defaultBottomOffset
let topOffset:CGFloat = defaultTopOffset
let xOffset:CGFloat = defaultHorizontalOffset
let width = CGRectGetWidth(self.frame ) - 2 * defaultHorizontalOffset
let height = width * defaultHeightRatio
let yOffset:CGFloat = topOffset
let frame = CGRect(x: xOffset, y: yOffset, width: width, height: height)
return frame
} else if index == 1 {
let horizontalMargin = -self.bounds.width * backgroundCardHorizontalMarginMultiplier
let width = self.bounds.width * backgroundCardScalePercent
let height = width * defaultHeightRatio
return CGRect(x: horizontalMargin, y: 0, width: width, height: height)
}
return CGRectZero
}
在此方法中, 创建 POPAnimation 并将其传递给 Koloda。然后,Koloda 使用它在用户刷卡后动画帧变化。如果委托返回 nil ,则表示 Koloda 使用默认动画。
下面你可以在委托中看到这个方法的实现:
override func frameForCardAtIndex(index: UInt) -> CGRect {
if index == 0 {
let bottomOffset:CGFloat = defaultBottomOffset
let topOffset:CGFloat = defaultTopOffset
let xOffset:CGFloat = defaultHorizontalOffset
let width = CGRectGetWidth(self.frame ) - 2 * defaultHorizontalOffset
let height = width * defaultHeightRatio
let yOffset:CGFloat = topOffset
let frame = CGRect(x: xOffset, y: yOffset, width: width, height: height)
return frame
} else if index == 1 {
let horizontalMargin = -self.bounds.width * backgroundCardHorizontalMarginMultiplier
let width = self.bounds.width * backgroundCardScalePercent
let height = width * defaultHeightRatio
return CGRect(x: horizontalMargin, y: 0, width: width, height: height)
}
return CGRectZero
}
如何防止背景卡移动?
我还在新版的Koloda中添加了一个delegate方法:
override func frameForCardAtIndex(index: UInt) -> CGRect {
if index == 0 {
let bottomOffset:CGFloat = defaultBottomOffset
let topOffset:CGFloat = defaultTopOffset
let xOffset:CGFloat = defaultHorizontalOffset
let width = CGRectGetWidth(self.frame ) - 2 * defaultHorizontalOffset
let height = width * defaultHeightRatio
let yOffset:CGFloat = topOffset
let frame = CGRect(x: xOffset, y: yOffset, width: width, height: height)
return frame
} else if index == 1 {
let horizontalMargin = -self.bounds.width * backgroundCardHorizontalMarginMultiplier
let width = self.bounds.width * backgroundCardScalePercent
let height = width * defaultHeightRatio
return CGRect(x: horizontalMargin, y: 0, width: width, height: height)
}
return CGRectZero
}
如果返回 false 值,则表示交互动画已关闭,背景上的卡片不会与前面卡片的移动同时移动。
如果值为 false,则动画如下所示:
如果该值为 true,则如下所示:
希望您喜欢 Koloda 的第二个版本!检查一下:
另请阅读: