交互设计的核心—Override & Data

什么是Override?

在Framer X中,当您想向画布元素添加代码(定义为您绘制的不是代码的任何东西)时,必须使用Override。您可以在属性面板中的代码下找到Override。只需选择任何对象并附加所需的Override。您可以通过单击“编辑代码”来编辑替代项,您会发现默认情况下我们包含了许多示例。

image.png

静态Override

在您的设计画布中,给一个白色的设计对象添加如下的Override。

  1. import { Override } from "framer"
  2. export function ChangeBackground(): Override {
  3. return {
  4. background: "yellow",
  5. }
  6. }

image.png

此时,在预览窗口中白色的矩形变为了黄色。

动态Override

通过Override,您可以使画布中的元素动起来

image.png

import { Override } from "framer"

export function ChangeTop(props): Override {
    return {
        top: props.top + 50,
    }
}


(关于这里的props,可以使用组件库的FramerSpy来查看可以通过props传递的内容)

Override中的props

截屏2019-12-07下午10.25.04.png
(上面这个图 FrameSpy的使用示意图,这个可以在framer商店中下载,注意名字是— FrameSpy —,
该组件主要可以查看code或者design组件的jsx代码)

这里我们展开聊一下props。
首先,据我目前所知,props可以获取被应用该Override的一些基础属性。
下面是我自己总计的一些,当然你们也可以去探索,

image.png

export function App(props):Override{
   return{
      onTap(){
         console.log(props.something)
      }
   }
}
//该方法可以测试你想要的props属性是否有,或则对不对。
  • props.width
  • props.height
  • props.name 图层默认的名字Frame,此时jsx里面的name没有,需要手动更改图层的名字才可以调用该属性。
  • props.top & props.bottom 这两个属性是相对的,当图层处于画布中间偏上的时候,top属性有值,bottom为undifined,反之亦然。
  • props.left & props.right 同上
  • props.background
  • props.background.src 这里主要是设计组件用图片做背景的时候用。应用的时候也要注意
export function App():Override{
  return{
   background:{src:data.background}
  }
}

事件

通过Override,使用事件,用一个设计组件去触发另一个或者另外几个设计组件。
framer X api里面的事件有:

  • hover、tap、pan、drag、scroll

1.gif

import * as React from "react"
import { Override, Data } from "framer"

const data = Data({ rotate: 0 })

export function Button(props): Override {
    return {
        onTap() {
            data.rotate += 90
        },
    }
}

export function Rotate(props): Override {
    return {
        animate: { rotate: data.rotate },
    }
}

上面这些都只是官网的部分案例。之后,会补充更多的案例。

语法

Imports and exports-导入和导出

始终确保顶部有一个React导入(否则JSX / TSX文件将不起作用)这个只是code组件用的,override一般不用。

import * as React from "react"

然后从framer中导入所需的内容,最常见的就是 Frame 、 Scroll 、 Page

import { Frame, Scroll, Page, useCycle } from "framer"

两个code组件中,传递组件。简单点说,就是可以从一个code组件中,导入另一个code组件。

export const name = "Koen" // In myFile.jsx

import { name } from "./myFile"

当然,你也可以导入设计画布中的组件。(前提是,画布中的设计元素必须变成组件。)

import { Todo } from "./canvas"

Variables-声明变量

您仍然可以使用var,但现代版本为let。意思是是“让它成为……”。

let name = "Koen"

如果您知道此变量永远不会更改(可以始终使用此变量),则可以使用const。

const name = "Koen"
name = "Ben" // Big fat error; you cannot change a const variable

Functions-功能

ES6有多种编写函数的方法。您可以在这里研究原因,但我将使其保持简单;它们通常是完全相同的,您可以选择最喜欢的一个。

function square(value) { return value * value }

const square = (value) => { return value * value }

最后一个具有快捷方式选项。注意如何跳过方括号并返回:

const square = (value) => value * value // Exactly the same as above

这与JSX组件(请参阅下文)非常有效,我们将其称为匿名函数:

<Frame onCalculate={(value) => value * value} />

<Frame onClick={() => console.log("Hello")} /> // A real world example

工具

为什么是.tsx文件?

为了使Framer能够始终如一地工作,它需要了解您的代码。这样,它可以在您键入时为您捕获错误,提供非常好的自动完成功能,并始终同步文档。

为此,我们依靠TypeScript,这是Microsoft的一个项目,它将所有这些功能添加到标准JavaScript中。除了扩展及其出色的功能之外,您永远不必真正考虑这一点,因为它添加的所有内容都是可选的。

这就是.tsx中的T所代表的意思。x代表JSX,即组件使用的HTML样式语法。

如何处理真实数据

从本地文件导入JSON

这听起来容易得多。首先,让我们制作一个简单的JSON数据文件 :person.json

{
  persons: [
    {"name": "Koen", "age": 36},
    {"name": "Aroa", "age": 25},
    {"name": "Sara", "age": 28}
  ]
}

现在,将其保存在您打算在其中使用的任何代码文件旁边,然后将其导入:

import { persons } from "./persons.json"

从远程API获取

甚至更容易,您可以将fetch API与await一起使用:

const response = await fetch('https://api.com/persons');
const persons = await response.json();

我如何使用Git?

当你选择单击file的时候,同时按住OPtion键,会出现 save as的选项,然后选择 .framerfx格式,其实这个格式就是一个文件夹。

image.png

这种格式有什么用呢?这个是结合 Framer Bridge ,可以把自己创建的代码组件(带property controls的那种)传到framer 组件商店里面。这样其他的人就可以下载你的组件了。

如何通过npm丰富framer的功能?

例如导入我们常用的一个包,styled-components 。或者是可以导入antd的组件使用。

styled-components 一种更好的css样式工具

在framer中,其实有4种写css样式的方法。

//第一种 使用frame,官方的API
<Frame width={6} height={6}/> 

//第二种 使用内链style
<div style={{width:6px,height:6px}}> </div>

//第三种 使用外联链style 
const style = {
   width:6,
   height:6
}
<div style={style}> </div>

//第四种 就是styled-components啦
这个需要安装styled-components,然后引用

import styled from 'styled-components'

const Name = styled.div`
   width:6px;
   height:6px
`
<Name />

以下是如何在我们的项目中安装styled-components,并使用它。

  1. file —> show project folder 打开我们项目所在的目录
  2. 拖拽任意一个文件到VS code中
  3. 在vs code中打开项目的目录,并进入它
  4. 打开terminal,输入 npm install —save styled-components 来安装(使用npm前要安装node.js)
  5. 进入framer中使用
import * as React from "react"
import styled from "styled-components"

const Name = styled.div`
    width:100px;
    height:100px;
    background:pink
`
export function App() {
    return <Name />
}

ScreenFlo1w.mp4 (8.63MB)

以上就是如何在framer中通过npm安装自己需要的东西啦!

antd

这个呢,本来是开发人员用于快速搭建网站中后台的。同时他也有,antd-mobile 有很多预制的组件。
对于我们使用Framer X来说,我们可以用它的组件,快速搭建Web端或者移动端一些比较负责的交互。
一起来看看吧。

官网地址:antd

我们以一个简单的时间选择来讲。这个在framer中做,还是比较复杂的。

  1. 按照上面安装styled-components的方法,来安装antd
  2. npm install antd-mobile —save 安装移动端的框架
  3. 在framer中的code组件中引用。
npm install antd-mobile --save //terminal
import * as React from "react"
import "antd-mobile/dist/antd-mobile.css" //这个是antd的样式,必须导入
//接下来我们看需导入组件
import { PickerView, WhiteSpace } from "antd-mobile"

const seasons = [
    [
        {
            label: "2013",
            value: "2013",
        },
        {
            label: "2014",
            value: "2014",
        },
        {
            label: "2015",
            value: "2015",
        },
        {
            label: "2016",
            value: "2016",
        },
    ],
    [
        {
            label: "春",
            value: "春",
        },
        {
            label: "夏",
            value: "夏",
        },
    ],
]

const season = [
    {
        label: "春",
        value: "春",
    },
    {
        label: "夏",
        value: "夏",
    },
]

const province = [
    {
        label: "北京",
        value: "01",
        children: [
            {
                label: "东城区",
                value: "01-1",
            },
            {
                label: "西城区",
                value: "01-2",
            },
            {
                label: "崇文区",
                value: "01-3",
            },
            {
                label: "宣武区",
                value: "01-4",
            },
        ],
    },
    {
        label: "浙江",
        value: "02",
        children: [
            {
                label: "杭州",
                value: "02-1",
                children: [
                    {
                        label: "西湖区",
                        value: "02-1-1",
                    },
                    {
                        label: "上城区",
                        value: "02-1-2",
                    },
                    {
                        label: "江干区",
                        value: "02-1-3",
                    },
                    {
                        label: "下城区",
                        value: "02-1-4",
                    },
                ],
            },
            {
                label: "宁波",
                value: "02-2",
                children: [
                    {
                        label: "xx区",
                        value: "02-2-1",
                    },
                    {
                        label: "yy区",
                        value: "02-2-2",
                    },
                ],
            },
            {
                label: "温州",
                value: "02-3",
            },
            {
                label: "嘉兴",
                value: "02-4",
            },
            {
                label: "湖州",
                value: "02-5",
            },
            {
                label: "绍兴",
                value: "02-6",
            },
        ],
    },
]
//class 前面还需要加上  export
//这样framer外面的组件才能看到。
export class PickerViewExample extends React.Component {
    state = {
        value: null,
    }
    onChange = value => {
        console.log(value)
        this.setState({
            value,
        })
    }
    onScrollChange = value => {
        console.log(value)
    }
    render() {
        return (
            <div>
                <PickerView
                    onChange={this.onChange}
                    onScrollChange={this.onScrollChange}
                    value={this.state.value}
                    data={seasons}
                    cascade={false}
                />
                <WhiteSpace />
                <WhiteSpace />
                <PickerView data={season} cascade={false} />
                <WhiteSpace />
                <WhiteSpace />
                <PickerView data={province} value={["02", "02-1", "02-1-1"]} />
            </div>
        )
    }
}

//这里最下面的需要删除
//然后发现木有 --
//啥也没有??? 这个好像是一个bug 重启打开就好了 我也不知道为啥
//boom!好啦
//我也不知道为啥?通过npm引入外部组件,总是一开始有点小问题
//重启就好啦 看看我们的成果吧

//一个基础版的样式就OK了 接下来我们修改他。
//修改的原则是:先看看官方给的API 刚刚那里就是我们可以修改的地方
//刚刚位置放错了 哈哈
//ok 啦
//这个难度比较高了,需要懂得react的逻辑 这样才能基于别人的基础山修改。
//over!!!

未命2.mp4 (38.16MB)