美文网首页
第 2 章:设计 COSMOS

第 2 章:设计 COSMOS

作者: sing_crystal | 来源:发表于2016-05-15 21:27 被阅读0次

    原文链接
    作者:C4 开源项目
    译者:Crystal Sun
    全部章节请关注此文集C4教程翻译
    校对后的内容请看这里

    3月11日,我得了一个机会,可以写一篇教程,发表在知名网站上。所以,我开始和 Jake 讨论一些能够设计、开发、发布的概念,能够抓住 C4 Swift 版本的要点,学习如何使用这个新系统来创建动画...想到:很多基础的动画出现,然后组合成一个优雅的界面,我们看了很多 UI 视频,然后头脑风暴。

    Jake 想到了一个点子:

    ...中间出现了一个实体圆圈,点击后,稍微缩小一下(原来的90%),然后从中心接着放射出八个圆圈,每个圆圈都比之前的圆圈大一点,最外层的圆圈里有不同的图标,点击叉号关闭所有的圆圈,回到初始状态

    于是我们看了很多的视频。

    讨论概念。

    好像行得通。

    运行程序。

    这就是我们的工作方式。

    1. 模拟和测试

    实际的应用比较简单,尽管有很多组件,设计交互界面、背景,可能花费一些时间调整,同样的,正是应用还是简单,尽管这些调整比较复杂,不过从创建到完成,这个过程能给我们提供最好的教程素材。

    Jake 展示的设计稿只有一个页面,里面有一个炫酷的动画菜单,多层视差背景。我看了一下,思考如何才能让两个组件合并起来。

    2. 背景

    背景部分的工作比较容易分解,主要就是很多不同内容的图层在按照不同的速度移动。

    里面有:

    1. 大星星
    2. 小星星
    3. 连接星星的线
    4. 三个背景星星层
    5. 两个星云层

    这完全可以做到,在和 Jake 沟通之后,我写了一个清单列出我需要他定义的一些东西:

    1. 角度/指示器动画
    2. 单个的星座
    3. 三层前景风格 + 运动效果
    4. 三层 星星 背景风格 + 运动效果(incl. # of stars 是什么意思?)
    5. 两层幸运背景风格 + 运动效果

    第一步,得到 layer 的数量,同时获取视差角度...需要八个,所以我先用是个来测试一下实际的效果。

    本章的代码只是我在真正开发之前的一些测试展示效果,所以当你看完这章后,记得删掉在本章添加的所有代码。

    class WorkSpace: CanvasController {
        //创建一个空的数组变量,用来添加 layers
        var layers = [UIScrollView]()
    
        override func setup() {
            //当 layer 数量小于 10时,执行循环体里的代码
            repeat {
                //创建一个 layer,它的 frame 值和 canvas 的 frame 值一样
                let layer = UIScrollView(frame: view.frame)
                //设置每层 layer 内容的大小,高度为 0 ,防止屏幕垂直滚动
                layer.contentSize = CGSizeMake(layer.frame.size.width * 10, 0)
                //把 layer 添加到 canvas 上以及数组里
                canvas.add(layer)
                layers.append(layer)
            } while layers.count < 10
        }
    }
    

    挺简单的吧,使用的工程的文件正是前一章中的,我在 WorkSpace 文件中添加一个 repeat 循环体,来创建新的 layer,添加到 canvas 上,直到创建完 10 layer 为止。每创建一个 layer,我都会把 layer 的 contentSize 设置的超级大(文本中,是 canvas 的二十倍宽)。设置 contentSize 的高度为 0,这样就不会垂直滚动了。

    在这时,如果我运行应用,我会什么都看不到,所以我修改一下循环体里代码,给每个 layer 增加一个 label 控件。

    class WorkSpace: CanvasController {
        //创建空的数组变量,用来存储 layer
        var layers = [InfiniteScrollView]()
    
        override func setup() {
            //当 layer 数量小于 10时,执行循环体里的代码
            repeat {
                //创建一个 layer,它的 frame 值和 canvas 的 frame 值一样
                let layer = InfiniteScrollView(frame: view.frame)
                //设置每层 layer 内容的大小,高度为 0 ,防止屏幕垂直滚动
                layer.contentSize = CGSizeMake(layer.frame.size.width * 10, 0)
                //把 layer 添加到 canvas 上以及数组里
                canvas.add(layer)
                layers.append(layer)
    
                //创建一个中心点变量,用来定位这些 label
                var center = Point(24,canvas.height/2.0)
                //计算 layer 的数量(因为我们要加最后一个 layer,从 10 开始倒序添加)
                let layerNumber = 10 - layers.count
                //创建字体,字号是当前 layer 的数量
                let font = Font(name: "AvenirNext-DemiBold", size:Double(layers.count+1) * 8.0)!
                //创建运行循环体知道每个 layer 都有一个 label
                repeat {
                    //创建一个 label
                    let label = TextShape(text: "\(layerNumber)", font: font)!
                    //居中
                    label.center = center
                    //更新中心点的位置
                    center.x += 130.0
                    //把 layer 添加到数组里
                    layer.add(label)
                } while center.x < Double(layer.contentSize.width)
            } while layers.count < 10
        }
    }
    

    修改原来的设置,加入一个内嵌的 repeat 循环体,直到全部 layer 的包含一个 label —— 每个 label 基于所在的 layer 编号。

    现在运行程序,应用里会出现 label 控件,不过!如果我滚动界面,只有一个 layer 在滚动...

    注意观察大星星和小星星

    2.2 三层近景风格 + 运动效果

    接下来定义三层近景 layer 里的星星怎么样运动。Jake 的想法是有一个星星移动的地方,所以我们决定使用三层 layer:大星星、小星星、和线。当应用中出现某个特定的符号时,当前的星星需要出现在特定符号的右边,接着所有的东西都在快速移动,从一个星座到另外一个星座的时候,出现非常短的线状动画。

    2.3 三层 星星 背景风格 + 运动效果

    接下来需要定义背景里有多少星星在动,大约是最上面 layer 的 5%、15%、20%。对每层有多少星星也有一个大概的猜测。

    2.4 两层星云层背景风格 + 运动效果

    继续,Jake 定义了星云和光晕的外表以及如何移动。这一步甚至比上一步还要简单,因为光晕几乎不懂,星云层大约是 10% 的速度。

    2.5 角度/指示器动画

    最后一个界面会在屏幕顶部出现一条竖线,with a longer dash every 20 dashes。接着,每个星座到达屏幕的中心位置时,都会出现一个更长的白线,在星座符号的下方:

    2.6 最后

    最后一件事,写一个清单列出即将要开发的不同的 layer,在他无限的好意下,Jake 发给我下图:

    3. 菜单

    菜单看起挺简单,实际上不然。唯一需要我搞懂的就是我们给这些星座符合设计什么样的动画效果。

    Jake 想用这些符号作为星座的基本外形

    实际上,给它们添加动画效果这事简单,难的地方在于创造它们,因为我们希望它们有自己的贝塞尔路径,创建的过程确实痛苦的,因为我们不知道他们的路径点,像是 IllUstrator 这样的软件也不给我们权限获取数据,还有,我不想写一个 SVG 导出器,那也太多余了。

    那么,我们该怎么办呢?

    使用 PaintCode 画出外形,接着添加曲线轨迹,保存到 Core Graphics 代码里,如下:

    UIBezierPath* bezier2Path = UIBezierPath.bezierPath;
    [bezier2Path moveToPoint: CGPointMake(250, 200)];
    [bezier2Path addLineToPoint: CGPointMake(150, 200)];
    [bezier2Path addCurveToPoint: CGPointMake(100, 150) controlPoint1: CGPointMake(122.4, 200) controlPoint2: CGPointMake(100, 177.6)];
    ...
    [bezier2Path closePath];
    

    当我把代码换成下面这样后:

    let bezier = Path()
    
    bezier.moveToPoint(Point(250,200))
    bezier.addLineToPoint(Point(150,200))
    bezier.addCurveToPoint(Point(100,150), control1:Point(122.4,200), control2:Point(100,177.6))
    ...
    

    事情开始变得更清晰,更容易处理了。现在我还需要得到星座符号的外形添加到 C4 代码里,无需费太多力就能实现我们想要实现的效果。

    比如,让 shape 的外形完全和要求的一样:

    shape.strokeEnd = 1.0
    

    3.1 红线

    走到这一步,我准备创建菜单了,因此需要下面的红线,标注菜单上所有元素的具体的位置、尺寸等等。

    Jake 的工作做的真棒,给我准备了这张图:

    4. 该进行下一章了

    基本的视觉概念都解释了,
    现在该做一些实际的开发工作了。不过,在职之前,我总结了一些必须要表明的问题:

    1. 定义外形 - 我会复用很多外形,也会给它们添加动画效果,我会用自定义的贝塞尔曲线路径,而不是单单导入图片资源。
    2. 复杂的动画序列 - 会有非常复杂的动画序列和调速,直到得到正确的菜单外展内收的效果。
    3. 定义手势交互 - 我想让手势交互越简单约好,当然了还要独一无二。
    4. 视差 + 无限滚动视图 - 必须给应用增加视差,我需要非常小心处理,开发完成后,应用的性能表现要非常高才行。

    记得删除掉 WorkSpace.swift 文件里的测试代码...只有一个空的 setup() 方法。

    继续下一章!

    本文由 SwiftGG 翻译组翻译,已经获得作者翻译授权。

    相关文章

      网友评论

          本文标题:第 2 章:设计 COSMOS

          本文链接:https://www.haomeiwen.com/subject/rmpprttx.html