日拱一卒:Leva 编辑器组件库

1,137 阅读4分钟

什么是 Leva

Leva 是一套开箱即用的编辑器组件库,可以快速开发编辑器控制面板。 image.png 相关链接:

如何使用

Leva 的使用非常简单,导入 useControls即可,leva 会自动根据变量属性渲染合适的输入类型,以下面的 demo 为例:

import { useControls } from 'leva';

export default () => {
  const { name, aNumber } = useControls({ aNumber: 0, name: 'World' });

  return (
    <div>
      Hey {name}, hello! {aNumber}
    </div>
  );
};

渲染后如下: image.png

输入控件

Leva 默认开箱提供了不少默认输入控件,它会使用你的变量名作为 Label,如果你想要自己控制 Label 可以查看下面的属性控制。

String 字符串

const { name } = useControls({
  name: 'world',
})

截屏2023-07-22 17.52.03.png

Select 选择器

const {select} = useControls({
  select: {
      options: {
        'Hello World': 'helloWorld',
        'Leva is awesome!': 'leva',
      },
      value: 'helloWorld',
    }
  )

image.png

Number 数字

默认两位小数

const { number } = useControls({
  number: 4,
})

image.png

Range 取值范围

数值的取值范围,可以指定当前值,最小值,最大值和步长。

const { range } = useControls({
  range: {
    max: 10,
    min: 0,
    step: 1,
    value: 4,
  },
})

image.png

Color 颜色

颜色可以用两种方式指定,一个 #16进制值,和一个 rgba的对象:

const colors = useControls({
  rgb: '#fff',
  rgba: { a: 0.4, b: 125, g: 106, r: 200 },
})

截屏2023-07-22 17.54.26.png

Boolean 开关

const { boolean } = useControls({ boolean: true })

image.png

Interval 区间

包括两个区间值。

const { interval } = useControls({
  interval: {
    max: 10,
    min: 0,
    // initial value of 4, 5
    value: [4, 5],
  },
})

image.png

Button 按钮

你可以在面板中渲染按钮,通过 get 方法获取面板表单的值。

import { button } from 'leva';

const { myInterval } = useControls({
  foo: button((get) => alert(`Number value is ${get('number').toFixed(2)}`)),
})

image.png

ButtonGroup 按钮组

const presets = buttonGroup({
  label: 'Presets',
  opts: {
    '0.25': () => store.set({ number: 0.25 }, true),
    '0.5': () => store.set({ number: 0.5 }, true),
    '1': () => store.set({ number: 1 }, true),
    '2': () => store.set({ number: 2 }, true),
    '3': () => store.set({ number: 3 }, true),
  },
});

image.png

Vector 向量

向量分为二维和三维向量,可以通过直接给定二维数组或者有两个属性的 object 指定:

const { position } = useControls({
  vector: { x: 0, y: 0 },
  boxSize: [10, 20],
})

image.png 左侧的驾驶杆可以通过 invertY或者 false 来倒置 Y 轴和关闭,step 可指定驾驶杆的步长。

 position: {
    value: { x: 0, y: 0 },
    joystick: 'invertY',
    step: 0.1,
  },
  boxSize: {
    value: [10, 20],
    joystick: false,
    step: 1,
  },

三维向量类似,只不过多一个维度,设置更多维度的话 Leva 会报错。

vec3: {
  x: 0,
  y: 2,
  z: 1.5,
},
anotherVec3: [3, 1, 1],

image.png

文件夹

基础使用

useControls第一个参数若是 string 类型则作为文件夹名称:

 const otherValues = useControls('Another Folder', {
   foo: 0,  
   bar: false,
 })

截屏2023-07-22 17.47.25.png

样式和行为控制

第三个参数可以提供选项控制文件夹的样式和行为:

 const otherValues = useControls(
    'Another Folder',
    {
      bar: false,
      foo: 0,
    },
    {
      collapsed: true,
      color: 'purple',
    },
  );

截屏2023-07-22 17.51.10.png

辅助工具

你也可以通过 floder工具方法来创建文件夹:

向量: folder({ boxSize: [10, 20, 30], vector: { x: 0, y: 0 } }),

image.png

嵌套文件夹

floder 下可以添加更多 folder:

     向量: folder({
        boxSize: [10, 20, 30],
        second: folder({ number: 0 }),
        vector: { x: 0, y: 0 },
      }),

截屏2023-07-22 18.07.23.png

控制顺序

folder 的第二参数可以传入属性,order 可以控制顺序,数值越大顺序越靠后,order 也可以控制非文件夹的控件。

     向量: folder({
        boxSize: [10, 20, 30],
        second: folder({ number: 0 }, { collapsed: true, order: 1 }),
        vector: { x: 0, y: 0 },
      }),

输入受控

你可以向useControlshook 传入函数,此时返回值类型为 [values, set, get],你可以通过 values , set, get 函数分别用于获取当前值,设置值,获取值。

  const [values, set, get] = useControls(() => ({
    counter: { step: 1, value: 0 },
    username: 'Mario',
  }));

...

     <Button
        onClick={() => {
          set({ counter: get('counter') + 1 });
        }}
      >
        添加1
      </Button>

属性控制

Label 标签

const val = useControls({
    color: { label: '颜色', value: '#f00' },
    opacity: { label: '透明度', value: 0.5 },
    size: { label: '尺寸', value: { height: 300, width: 200 } },
    string: { label: 'My string', value: 'hello' },
  });

Hint 提示

 const values = useControls({
   color: { value: '#f00', hint: 'Used for important content' },
   position: { value: [0, 0, 0], hint: 'Position of the object relative to the screen' },  })

按需渲染

使用 render方法按需渲染:

 const [values, set, get] = useControls(() => ({
    color: { label: '颜色', render: (get) => get('showColor'), value: '#f00' },
    counter: { step: 1, value: 0 },
    opacity: { label: '透明度', value: 0.5 },
    showColor: { label: '显示颜色', value: true },
    size: { label: '尺寸', value: { height: 300, width: 200 } },
    string: { label: 'My string', value: 'hello' },
    username: 'Mario',
  }));

面板控制

引入 Leva 组件可以控制面板属性:

 <Leva
    fill // 占满容器
    flat // 扁平化
    hideCopyButton //隐藏复制按钮
    neverHide // 不被隐藏
    titleBar={{ drag: false, title: '示例面板' }}
  />

插件

除了基础控件之外 Leva 还提供了一些额外的复杂输入插件,比如贝塞尔曲线,日期控件等。 image.png 使用方式:

import { bezier } from '@leva-ui/plugin-bezier';

const { curve } = useControls({ curve: bezier() });

Demo 实例

你可以访问:demo.vidol.chat/ 查看 Demo 实例: image.png