Framer学习备忘手册:类和模块的应用

写在前面的话

Framer用来上手原型的优点不必多说,缺点对设计师来说可能就是coffeescript的学习曲线比较陡,和样式、结构、事件代码分离的常规界面开发不同,Framer里面所有代码全部掺杂在一起,相当不利于整理和组织。虽然注释和代码折叠等技巧可以一定程度增加代码的可读性,但到真正进阶到利用class和module去管理项目的代码的时候,才能从本质上解决复杂项目代码冗余不利于阅读管理等问题。下面的文章分享自Framer社区的一名UI设计师Tess Gadd,通过她分享总结可以帮助我们改进Framer工作流。原文链接点击这里查看。

 

正文部分:

 

这部分文章是我Framer学习小抄系列的一部分,系列的其它清单如下:

MMP各位,事情搞大了。我们将要建「类和模块」了。该死!但是我想说,静一静。它没有听上去那样复杂。即便像我这样一位只会复制粘贴的灵魂搬运工,都能够驾驭他们。(某种程度…)

在这张备忘单中,我们将介绍:

  1. 什么是类?什么是模块?
  2. 如何创建一个类
  3. 创建默认态
  4. 在同个类中添加多个图层
  5. 添加新的属性
  6. 功能和事件
  7. 在初始化范围外设置属性(Getters和Setters)
  8. 制作一个模块
  9. 例子
  10. 哪些资源帮助我们继续学习

当然如果你还没有framer 的话,建议去先下载个试用版。

 

1.什么是类?什么是模块

 

你知道PageComponent(翻页组件) ,ScrollComponent(纵向滑屏组件) ,SliderComponent(滑块组件) ?对,他们都是Framer内置的类。

太好了。那对你来说意味着什么?基本上来说,通过构建自己的类,你可以在不同的场景中重复使用相同的代码。

这有助于保持同一个原型的一致性(或跨多个原型),并且可以避免重写整段的代码以实现同一类功能。

模块是我们用来保存和组织我们的类的文件。想象一下,你在同一个Framer文件中有10个类 – 这将是很抓狂的事情!因此,通过将我们的类放入模块中,整个项目工程文件将保持得更整洁,并且还可以使我们更轻松地将它们迁移到未来的项目中。

 

2.如何创建一个类

创建一个最基本的类,你需要做三件事情;

  1. 定义一个类
  2. 创建一个构造函数
  3. 创建一个super

然后调用你的类。

大多数情况下,您可以在开始创建自己的代码之前复制和粘贴这些代码块。(但是您需要更改MyNewAndImprovedLayer的名称

class MyNewAndImprovedLayer extends Layer
   constructor: (@options={}) ->
      super @options
thing = new MyNewAndImprovedLayer

专业提示:看看它怎么命名的:extends Layer?你可以通过起类似extends ScrollComponent或其他名字去命名你的组件。比如我用extends TextLayer去命名一个通用的文本标签。

 

创建类要遵循的规则注意事项:始终用驼峰式CamelCase命名规则。例如,不要命名你的类为button ,而是Button。用TextField取代Textfield。这样它就不会与其他图层混淆。

3.创建默认态

所以,在我们开始之前要了解有两种类型的默认值设定。一种能够在声明类之后再次修改默认值,而另一类则不可以。

至于怎么区分,要归结于  ?==

在下面的例子中,我在类里用一个=来赋值thing背景颜色为黑色。类以外不能修改它。请注意,在下面的示例中,thing的背景颜色不是蓝色。

 

class MyNewAndImprovedLayer extends Layer
   constructor: (@options={}) ->
      @options.backgroundColor = "#000"
      super @options
thing = new MyNewAndImprovedLayer
   backgroundColor: "blue"
thing.center()

 

 

另一示例,我用一个 ?= 来赋值thing背景颜色试试。这是你发现类以外可以重新修改它。然而代码几乎是一样

 

class MyNewAndImprovedLayer extends Layer
   constructor: (@options={}) ->
      @options.backgroundColor ?= "#000"
      super @options
thing = new MyNewAndImprovedLayer
   backgroundColor: "blue"
thing.center()

 

 

专业提示:想要在同一个构造函数里设定多个默认值,可以参考下面的案例,这种方法也可以在类外修改它们的默认属性。

class MyNewAndImprovedLayer extends Layer
   constructor: (@options={}) ->
      _.defaults @options,
         backgroundColor : "#000"
         height: 48
         borderRadius : 2
      super @options
thing = new MyNewAndImprovedLayer
   backgroundColor: "#00aeff"

4.在同个类中添加多个图层

你可知道如何在滑块组件中将滑块旋钮引用为slider.knob. ?这种写法就是引用滑块组件中的一个图层。

要创建可以在类之外访问的图层,请在图层名称前添加一个符号@。在下面的这个例子中,我们为一个按钮创建一个新的文本层。

注意:你只能在super之后为其新增的图层定义父级以及它的位置。

 

class Button extends Layer
  constructor: (@options={}) ->
     @options.backgroundColor ?= "#000"
     @options.height = 44
     @label = new TextLayer
        fontSize: 16
     super @options
     @label.parent = @
     @label.center()
button = new Button
button.center()
button.label.text = "Hello there"

5.添加新的属性

你可曾注意到滑块组件有个min和max的属性值,但是别组件没有,其实这就是被添加的新属性。

在这个例子中,我们将制作一个非常非常粗糙的版本的TextLayer 。属性mySuperSexyFont并不代表任何意义(事实上,在这个例子中,你可以用HotPants代替它,它不会有任何改变。

 class SimpleTextLayer extends Layer
   constructor: (@options={}) ->
      @options.backgroundColor = "000"
      @options.mySuperSexyFont ?= "'Source Sans', sans serif"
      @options.html = @options.text
      @options.style =
         fontFamily : @options.mySuperSexyFont
         textAlign: "center"
         lineHeight: "200px"
      super @options
myText = new SimpleTextLayer
   text: "hello"
   mySuperSexyFont: "'Roboto', sans serif"
myText.center()

6.功能和事件

当然还可以在类的构造函数中构建事件,与正常功能函数不同,使用  : =>取代= ->。但可能把它建在类外面会更加简洁和有用。

class Button extends Layer
   constructor: (@options={}) ->
      @options.backgroundColor = "#F14676"
      super @options
      #event
      @.onMouseOver @Hover
      @.onMouseOut @HoverOff
   #function
   Hover: =>
      @.brightness = 70
   HoverOff: =>
      @.brightness = 100
button = new Button
button.center()

7.在初始化范围外设置属性(Getters和Setters)

所以你可以在类里面添加新的属性 – 但你以后如何修改它们?通过输入Getters和Setter。

在下面的这个例子中,我们设置要启用的类的默认值。在后面的原型中,我们可能想要更改它的类为禁用态- 在下面情况下,它是通过onClick 触发修改的。

class Button extends Layer
   constructor: (@options={}) ->
      @options.disabled ?= false
      @options.backgroundColor = "000"
      if @options.disabled is true
         @options.opacity = 0.5
      super @options
   @define 'disabled',
      get: -> 
         @options.disabled
      set: (value) -> 
         @options.disabled = value
         if @options.disabled is true
            @opacity = 0.5
         else
            @opacity = 1
Button = new Button
deactiveButton = new TextLayer
   text: "deactive"
deactiveButton.onClick ->
 Button.disabled = true

 

8. 创建模块

制作模块很容易 – 当然是针对单一的静态模块。有两种方法可以建立一个模块,这取决于你拥有的类的数量。如果你只有一个类,请选择方法1,如果您有更多选择方法2。

当然,在这之前首先下载Sublime

1.如果你在模块中只有一个类

在这个例子中,我们将制作一个“按钮”模块。

  1. 下载Sublime后,将你的类从Framer复制并粘贴到Sublime新建的空白文档中。
  2. class Button extends Layer或什么的修改成class exports.Button extends Layer
  3. 将你的Sublime文件保存为与你的类相同的名称(完全相同)。例如,如果你将’name’类名称Button保存为Button的模块名称。
  4. 接下来,创建一个新的Framer文件并将模块放入module文件夹中。
  5. 现在确保你的模块格式为coffeescript。你可以通过右键单击该文件并将其重命名为Button .coffee来完成此操作
  6. 现在切换到你的Framer文件并在文件顶部添加{Button} = require "Button"
  7. 然后只需要调用你的类 button = new Button

2.如果你的模块有两个或更多的类

在这个例子中,我们将制作一个包含多种不同表单域组件的模块。这将有助于在整个公司内保持不同原型的一致性。

  1. 下载Sublime后,将你的classES复制并粘贴到新建空白页面中。
  2. 对于你拥有的class textField extends Layer或任何其他实例,请将其更改为class exports.textField extends Layer 。为你要导入的每个类执行此操作。
  3. 将Sublime文件保存为与你的文件中的任何类不重名的命名。下面这个例子,我们将使用MaterialComponents
  4. 接下来创建一个新的Framer文件并将模块放入module的文件夹中。
  5. 现在确保你的模块格式为coffeescript。你可以通过右键单击该文件并将其重命名为例如MaterialComponents.coffee来执行此操作
  6. 现在切换到你的Framer文件并且在你的文件顶部添加MaterialComponents = require 。注意与仅仅导入一个类的方式不同。
  7. 现在通过button = new MaterialComponents.Button或者formField = new MaterialComponents.TextField 来调用类。注意你如何调用必须的模块和类。

9.实例

Button Class

这是一个在Framer内部申明按钮类的实例——代码没有收进Module。

https://framer.cloud/NQIYw

 

Button Module

还是按钮类?没错,只是这次代码合进了Module文件里。

https://framer.cloud/lWKTD

 

MaterialComponents Module

这是一个稍加复杂的模块,虽然bug比较多,但对于学习如何将多个类封装在一个模块里来说是一个很好的示例。点击这里阅读更多。

10.哪些资源帮助我们继续学习

自己独立学习思考不是一件容易的事情,下面这两篇文章在我一路学习过来给了我很多启发。希望他们同样能够帮到你。

 

开发一个成帧器模块

Framer中的类,循环和数组

刷牙君

View posts by 刷牙君
处女座设计师一枚,涉及的专业领域视觉,交互,前端。

Leave a Reply

Your email address will not be published. Required fields are marked *