leaferjs / ui

一款好用的 Canvas 渲染引擎,革新的体验。高效绘图 、UI 交互(小游戏、互动应用、组态)、图形编辑。
https://www.leaferjs.com
MIT License
2.32k stars 81 forks source link

在 leafer-ui 中集成 rough.js #141

Open x-tropy opened 3 months ago

x-tropy commented 3 months ago

希望用 leafer pen 方法画出 rough.js 的效果,但是和理想效果稍微有点差别: image

左侧为集成后,右侧为 rough.js 直出效果。

如果想两种效果一致,是 pen.setStyle 需要做哪些设置吗?

import { useEffect, useRef } from 'react'

const initLeaferApp = async (root: HTMLElement) => {
  try {
    // [1] 未集成
    const { RoughCanvas } = await import('roughjs/bin/canvas')
    const rc = new RoughCanvas(
      document.getElementById('rough-root') as HTMLCanvasElement
    )
    const gen = rc.generator
    const rect = gen.rectangle(100, 200, 200, 100)
    rc.draw(rect)

    // [2] 集成后
    const { App, Pen } = await import('leafer-ui')
    await import('@leafer-in/editor')
    const app = new App({
      view: root,
      editor: {},
    })
    const pen = new Pen()
    pen.setStyle({ fill: 'black' })
    rect.sets[0].ops.reduce((pen, action) => {
      if (action.op === 'move') {
        pen.moveTo(action.data[0], action.data[1])
      } else if (action.op === 'bcurveTo') {
        pen.bezierCurveTo(
          action.data[0],
          action.data[1],
          action.data[2],
          action.data[3],
          action.data[4],
          action.data[5]
        )
      }
      return pen
    }, pen)
    app.tree.add(pen)
  } catch (error) {
    console.error('Error importing module:', error)
  }
}

export default function LeaferComponent() {
  const leaferRoot = useRef<HTMLDivElement | null>(null)
  useEffect(() => {
    if (!leaferRoot.current) return
    initLeaferApp(leaferRoot.current)
  }, [])

  return (
    <div style={{ display: 'flex', flexDirection: 'row' }}>
      <div
        ref={leaferRoot}
        style={{
          border: '1px solid black',
          height: '500px',
          width: '500px',
        }}
      ></div>
      <canvas
        id="rough-root"
        width={500}
        height={500}
        style={{ border: '1px solid black' }}
      ></canvas>
    </div>
  )
}
x-tropy commented 3 months ago

或者能否提供一些别的实现思路?例如让 roughjs 给出画好的 svg,然后 leafer 把 svg 添加进来

x-tropy commented 3 months ago

这张对比图看得更明显: image

leaferjs commented 3 months ago

第一种方式:leafer支持将原生canvas绘图方法转换为路径数据,可以尝试将 rough.js 的绘图过程 转为 leafer的路径试试

https://leaferjs.com/ui/guide/path/PathCreator.html

第二种方式:使用自定义元素,采用原生context对接rough.js,不过需要自己计算元素的boxBounds

https://leaferjs.com/ui/guide/custom/context.html