diff --git a/README.md b/README.md index e7b19a5..ae636d3 100644 --- a/README.md +++ b/README.md @@ -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! @@ -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/ diff --git a/README.zh_CN.md b/README.zh_CN.md index 4e0e28d..7d85369 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -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) @@ -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/