Skip to content

Commit

Permalink
feat: lesson7
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoiver committed Apr 25, 2024
1 parent caef2b1 commit 98e7adb
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 74 deletions.
80 changes: 43 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,34 @@

What is an Infinite Canvas? The term "infinite" in [infinitecanvas] is described as follows:

- High scalability. Users can freely organize content structures in a non-linear fashion.
- Zooming. Emulates the "zoom in" to get an overview and "zoom out" to observe details as in the real world.
- Direct manipulation. Provides intuitive editing capabilities for basic shapes, including moving, grouping, and modifying styles.
- High scalability. Users can freely organize content structures in a non-linear fashion.
- Zooming. Emulates the "zoom in" to get an overview and "zoom out" to observe details as in the real world.
- Direct manipulation. Provides intuitive editing capabilities for basic shapes, including moving, grouping, and modifying styles.

The [infinitecanvas] showcases numerous examples ranging from design tools to creative boards, including some well-known products such as: [Figma], [Modyfi], [rnote], [tldraw], [excalidraw] and so on.

As a front-end developer, I am very interested in the rendering technologies involved. Although tldraw, excalidraw, and others generally use more user-friendly technologies like Canvas2D/SVG, there are also many editors and design tools in the JS and Rust ecosystems that use more low-level rendering technologies for 2D graphics with GPU acceleration to achieve better performance and experience:

- [Figma] uses a tile-based rendering engine written in C++, compiled into WASM and then calls WebGL for rendering.
- [Modyfi] uses [wgpu] from the Rust ecosystem, also compiled into WASM and then calls WebGL2 for rendering.
- [Zed] uses GPUI to render rectangles, shadows, text, images, and other UI elements.
- [Vello] and [xilem] experimentally use Compute Shader for 2D rendering.
- [Figma] uses a tile-based rendering engine written in C++, compiled into WASM and then calls WebGL for rendering.
- [Modyfi] uses [wgpu] from the Rust ecosystem, also compiled into WASM and then calls WebGL2 for rendering.
- [Zed] uses GPUI to render rectangles, shadows, text, images, and other UI elements.
- [Vello] and [xilem] experimentally use Compute Shader for 2D rendering.

Therefore, in this tutorial, I hope to implement the following features:

- Use [@antv/g-device-api] as a hardware abstraction layer, supporting WebGL1/2 and WebGPU.
- Referencing [mapbox] and [Figma], attempt to use tile-based rendering.
- Use SDF (Signed Distance Field) rendering for circles, ellipses, rectangles, etc.
- GPU-accelerated text and Bezier curve rendering.
- Use [rough.js] to support hand-drawn styles.
- Use CRDT (Conflict-free Replicated Data Type) to support collaborative [Yjs].
- Use [@antv/g-device-api] as a hardware abstraction layer, supporting WebGL1/2 and WebGPU.
- Referencing [mapbox] and [Figma], attempt to use tile-based rendering.
- Use SDF (Signed Distance Field) rendering for circles, ellipses, rectangles, etc.
- GPU-accelerated text and Bezier curve rendering.
- Use [rough.js] to support hand-drawn styles.
- Use CRDT (Conflict-free Replicated Data Type) to support collaborative [Yjs].

I hope to rewrite the rendering part of the canvas with Rust in the future, but the current project completion is still relatively low:

- [wgpu] is a very reliable hardware abstraction layer, which can even implement the backend for [piet].
- Shaders can basically be reused.
- Hand-drawn styles can use [rough-rs].
- [y-crdt] is the Rust implementation of [Yjs].
- [wgpu] is a very reliable hardware abstraction layer, which can even implement the backend for [piet].
- Shaders can basically be reused.
- Hand-drawn styles can use [rough-rs].
- [y-crdt] is the Rust implementation of [Yjs].

Let's get started!

Expand All @@ -50,41 +50,47 @@ pnpm run dev

## Lesson 1

- A hardware abstraction layer based on WebGL1/2 and WebGPU.
- Canvas API design.
- Implementing a simple plugin system.
- Implementing a rendering plugin based on the hardware abstraction layer.
- A hardware abstraction layer based on WebGL1/2 and WebGPU.
- Canvas API design.
- Implementing a simple plugin system.
- Implementing a rendering plugin based on the hardware abstraction layer.

## Lesson 2

- Adding shapes to the canvas.
- Drawing a circle using SDF.
- Anti Aliasing.
- Dirty flag design pattern.
- Adding shapes to the canvas.
- Drawing a circle using SDF.
- Anti Aliasing.
- Dirty flag design pattern.

## Lesson 3

- Transformations. Make shapes support pan, zoom, rotate, and skew transformations.
- Scene graph.
- Transformations. Make shapes support pan, zoom, rotate, and skew transformations.
- Scene graph.

## Lesson 4

- What is a Camera?
- Projection transformation.
- Camera transformation.
- Camera animation. Using Landmark transition between different camera states.
- What is a Camera?
- Projection transformation.
- Camera transformation.
- Camera animation. Using Landmark transition between different camera states.

## Lesson 5

- Drawing straight lines using Line Geometry or screen-space techniques.
- Drawing dots grid.
- Drawing straight lines using Line Geometry or screen-space techniques.
- Drawing dots grid.

## Lesson 6

- Implement an event system compatible with DOM Event API.
- How to pick a circle.
- Implement a drag-and-drop plugin based on our event system.
- Support for pinch zoom gestures.
- Implement an event system compatible with DOM Event API.
- How to pick a circle.
- Implement a drag-and-drop plugin based on our event system.
- Support for pinch zoom gestures.

# Lesson 7

- Developing Web UI with Lit and Shoelace
- Implementing a canvas component
- Implementing a zoom toolbar component

[infinitecanvas]: https://infinitecanvas.tools/
[Figma]: https://madebyevan.com/figma/building-a-professional-design-tool-on-the-web/
Expand Down
80 changes: 43 additions & 37 deletions README.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,35 @@

什么是无限画布?[infinitecanvas] 对“无限”的描述如下:

- 高扩展性。用户可以以非线形的形式自由组织内容结构。
- 缩放。模拟真实世界中的“放大”纵览全局和“缩小”观察细节。
- 直接操作。提供对于基础图形的直观编辑能力,包括移动、成组、修改样式等。
- 实时协作。
- 高扩展性。用户可以以非线形的形式自由组织内容结构。
- 缩放。模拟真实世界中的“放大”纵览全局和“缩小”观察细节。
- 直接操作。提供对于基础图形的直观编辑能力,包括移动、成组、修改样式等。
- 实时协作。

你一定见过甚至使用过各种包含无限画布的应用,[infinitecanvas] 上就展示了从设计工具到创意画板在内的众多案例,其中不乏一些知名产品包括 [Figma][Modyfi][rnote][tldraw][excalidraw]等等。

作为一个前端,我对其中涉及到的渲染技术很感兴趣。尽管 [tldraw][excalidraw] 等普遍使用易用性更高的 Canvas2D / SVG 技术,但 JS 和 Rust 生态中也有很多编辑器、设计工具使用更底层的渲染技术对 2D 图形进行 GPU 加速,以获得更好的性能和体验:

- [Figma] 使用 C++ 编写了一个 tile-based 的渲染引擎,编译成 WASM 后调用 WebGL 渲染
- [Modyfi] 使用了 Rust 生态中的 [wgpu],同样编译成 WASM 后调用 WebGL2 渲染
- [Zed] 使用 GPUI 渲染矩形、阴影、文本、图片等 UI。
- [vello][xilem] 实验性地使用了 Compute Shader 进行 2D 渲染。
- [Figma] 使用 C++ 编写了一个 tile-based 的渲染引擎,编译成 WASM 后调用 WebGL 渲染
- [Modyfi] 使用了 Rust 生态中的 [wgpu],同样编译成 WASM 后调用 WebGL2 渲染
- [Zed] 使用 GPUI 渲染矩形、阴影、文本、图片等 UI。
- [vello][xilem] 实验性地使用了 Compute Shader 进行 2D 渲染。

因此在这个教程中,我希望实现以下特性:

- 使用 [@antv/g-device-api] 作为硬件抽象层,支持 WebGL1/2 和 WebGPU。
- 参考 [mapbox][Figma],尝试使用 Tile-based 渲染。
- 使用 SDF 渲染圆、椭圆、矩形等。
- GPU 加速的文本和贝塞尔曲线渲染。
- 使用 [rough.js] 支持手绘风格。
- 使用 CRDT 支持协同 [Yjs]
- 使用 [@antv/g-device-api] 作为硬件抽象层,支持 WebGL1/2 和 WebGPU。
- 参考 [mapbox][Figma],尝试使用 Tile-based 渲染。
- 使用 SDF 渲染圆、椭圆、矩形等。
- GPU 加速的文本和贝塞尔曲线渲染。
- 使用 [rough.js] 支持手绘风格。
- 使用 CRDT 支持协同 [Yjs]

未来我希望将画布的渲染部分用 Rust 重写,目前项目的完成度还比较低:

- [wgpu] 是非常可靠的硬件抽象层,甚至可以为 [piet] 实现后端。
- Shader 基本可以复用。
- 手绘风格可以使用 [rough-rs]
- [y-crdt][Yjs] 的 Rust 实现。
- [wgpu] 是非常可靠的硬件抽象层,甚至可以为 [piet] 实现后端。
- Shader 基本可以复用。
- 手绘风格可以使用 [rough-rs]
- [y-crdt][Yjs] 的 Rust 实现。

![rust stack](/images/rust.png)

Expand All @@ -53,40 +53,46 @@ pnpm run dev

## 课程 1

- 基于 WebGL1/2 和 WebGPU 的硬件抽象层
- 画布 API 设计
- 实现一个简单的插件系统
- 基于硬件抽象层实现一个渲染插件
- 基于 WebGL1/2 和 WebGPU 的硬件抽象层
- 画布 API 设计
- 实现一个简单的插件系统
- 基于硬件抽象层实现一个渲染插件

## 课程 2

- 向画布中添加图形
- 使用 SDF 绘制一个圆形
- 反走样
- 向画布中添加图形
- 使用 SDF 绘制一个圆形
- 反走样

## 课程 3

- 变换。让图形支持平移、缩放、旋转、斜切变换。
- 场景图。
- 变换。让图形支持平移、缩放、旋转、斜切变换。
- 场景图。

## 课程 4

- 相机是什么?
- 投影变换。
- 相机变换。通过一个插件实现平移、旋转和缩放功能。
- 相机动画。平滑过渡到任意相机状态。
- 相机是什么?
- 投影变换。
- 相机变换。通过一个插件实现平移、旋转和缩放功能。
- 相机动画。平滑过渡到任意相机状态。

## 课程 5

- 绘制直线网格。使用 Line Geometry 或者屏幕空间技术。
- 绘制点网格。
- 绘制直线网格。使用 Line Geometry 或者屏幕空间技术。
- 绘制点网格。

## 课程 6

- 参考 DOM API 实现事件系统
- 如何拾取一个圆形
- 实现一个拖拽插件
- 支持双指缩放手势
- 参考 DOM API 实现事件系统
- 如何拾取一个圆形
- 实现一个拖拽插件
- 支持双指缩放手势

## 课程 7

- 使用 Lit 和 Shoelace 开发 Web UI
- 实现画布组件,监听页面宽高变换
- 实现缩放组件

[infinitecanvas]: https://infinitecanvas.tools/
[Figma]: https://madebyevan.com/figma/building-a-professional-design-tool-on-the-web/
Expand Down

0 comments on commit 98e7adb

Please sign in to comment.