Skip to content

Commit 71aa990

Browse files
committed
feat: init lesson001
0 parents  commit 71aa990

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+29717
-0
lines changed

.editorconfig

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# EditorConfig is awesome: http://EditorConfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
# Unix-style newlines with a newline ending every file
7+
[*]
8+
end_of_line = lf
9+
charset = utf-8
10+
insert_final_newline = true
11+
trim_trailing_whitespace = true
12+
indent_style = space
13+
indent_size = 2
14+
15+
[Makefile]
16+
indent_style = tab
17+
indent_size = 1
18+
19+
[*.md]
20+
trim_trailing_whitespace = false
21+
indent_size = 4

.eslintignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
coverage
2+
es
3+
lib
4+
dist
5+
node_modules
6+
examples
7+
rust
8+
__tests__

.eslintrc.cjs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module.exports = {
2+
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
3+
4+
globals: {
5+
window: true,
6+
document: true,
7+
module: true,
8+
},
9+
10+
rules: {
11+
'no-fallthrough': 0,
12+
'no-empty': 0,
13+
'no-param-reassign': 0,
14+
'no-redeclare': 'off',
15+
'no-useless-escape': 'off',
16+
'no-case-declarations': 'off',
17+
'no-constant-condition': 'off',
18+
'@typescript-eslint/no-duplicate-enum-values': 'off',
19+
'@typescript-eslint/no-empty-interface': 'off',
20+
'@typescript-eslint/no-shadow': 0,
21+
'@typescript-eslint/no-parameter-properties': 0,
22+
'@typescript-eslint/ban-ts-comment': 0,
23+
'@typescript-eslint/no-empty-function': 0,
24+
'@typescript-eslint/no-invalid-this': 0,
25+
'@typescript-eslint/no-use-before-define': [
26+
'error',
27+
{ functions: false, classes: false },
28+
],
29+
'@typescript-eslint/no-redeclare': ['error'],
30+
'@typescript-eslint/no-unused-vars': [
31+
'error',
32+
{
33+
args: 'none',
34+
ignoreRestSiblings: true,
35+
},
36+
],
37+
},
38+
};

.gitignore

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.DS_Store
2+
node_modules
3+
es
4+
lib
5+
dist
6+
examples/dist
7+
rust/target
8+
coverage
9+
10+
# tests
11+
__tests__/integration/**/*-diff.png
12+
__tests__/integration/**/*-actual.png
13+
test-results
14+
playwright-report

.husky/commit-msg

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
npx --no-install commitlint --edit "$1"

.husky/pre-commit

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
4+
npx lint-staged

.markdownlint.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"default": true,
3+
"no-inline-html": false,
4+
"line-length": false,
5+
"single-h1": false,
6+
"first-line-h1": false,
7+
"no-empty-links": false,
8+
"no-duplicate-heading": false,
9+
"link-fragments": false,
10+
"code-block-style": false,
11+
"MD003": {
12+
"style": "atx"
13+
},
14+
"front-matter": {
15+
"type": "yaml"
16+
}
17+
}

.markdownlintignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
**/CHANGELOG.md

.prettierignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
es
2+
lib
3+
dist
4+
tsconfig.json

.prettierrc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"semi": true,
3+
"singleQuote": true,
4+
"trailingComma": "all",
5+
"bracketSpacing": true,
6+
"arrowParens": "always"
7+
}

README.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# An Infinite Canvas Tutorial
2+
3+
What is an Infinite Canvas? The term "infinite" in [infinitecanvas] is described as follows:
4+
5+
- High scalability. Users can freely organize content structures in a non-linear fashion.
6+
- Zooming. Emulates the "zoom in" to get an overview and "zoom out" to observe details as in the real world.
7+
- Direct manipulation. Provides intuitive editing capabilities for basic shapes, including moving, grouping, and modifying styles.
8+
9+
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.
10+
11+
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:
12+
13+
- [Figma] uses a tile-based rendering engine written in C++, compiled into WASM and then calls WebGL for rendering.
14+
- [Modyfi] uses [wgpu] from the Rust ecosystem, also compiled into WASM and then calls WebGL2 for rendering.
15+
- [Zed] uses GPUI to render rectangles, shadows, text, images, and other UI elements.
16+
- [Vello] and [xilem] experimentally use Compute Shader for 2D rendering.
17+
18+
Therefore, in this tutorial, I hope to implement the following features:
19+
20+
- Use [@antv/g-device-api] as a hardware abstraction layer, supporting WebGL1/2 and WebGPU.
21+
- Referencing [mapbox] and [Figma], attempt to use tile-based rendering.
22+
- Use SDF (Signed Distance Field) rendering for circles, ellipses, rectangles, etc.
23+
- GPU-accelerated text and Bezier curve rendering.
24+
- Use [rough.js] to support hand-drawn styles.
25+
- Use CRDT (Conflict-free Replicated Data Type) to support collaborative [Yjs].
26+
27+
I hope to rewrite the rendering part of the canvas with Rust in the future, but the current project completion is still relatively low:
28+
29+
- [wgpu] is a very reliable hardware abstraction layer, which can even implement the backend for [piet].
30+
- Shaders can basically be reused.
31+
- Hand-drawn styles can use [rough-rs].
32+
- [y-crdt] is the Rust implementation of [Yjs].
33+
34+
Let's get started!
35+
36+
## Getting Started
37+
38+
The course project uses pnpm workspace, so you need to install pnpm first.
39+
40+
```bash
41+
pnpm i
42+
```
43+
44+
After entering the course directory, run [vite]:
45+
46+
```bash
47+
cd packages/lesson_001
48+
pnpm run dev
49+
```
50+
51+
## Lesson 1
52+
53+
In Lesson 1, we will introduce:
54+
55+
- A hardware abstraction layer based on WebGL1/2 and WebGPU.
56+
- Canvas API design.
57+
- Implementing a simple plugin system.
58+
- Implementing a rendering plugin based on the hardware abstraction layer.
59+
60+
[infinitecanvas]: https://infinitecanvas.tools/
61+
[Figma]: https://madebyevan.com/figma/building-a-professional-design-tool-on-the-web/
62+
[Modyfi]: https://digest.browsertech.com/archive/browsertech-digest-how-modyfi-is-building-with/
63+
[rnote]: https://github.com/flxzt/rnote
64+
[tldraw]: https://github.com/tldraw/tldraw
65+
[excalidraw]: https://github.com/excalidraw/excalidraw
66+
[rough.js]: https://github.com/rough-stuff/rough
67+
[rough-rs]: https://github.com/orhanbalci/rough-rs
68+
[zed]: https://zed.dev/blog/videogame
69+
[wgpu]: https://wgpu.rs/
70+
[vello]: https://github.com/linebender/vello
71+
[xilem]: https://github.com/linebender/xilem
72+
[piet]: https://github.com/linebender/piet
73+
[@antv/g-device-api]: https://github.com/antvis/g-device-api
74+
[mapbox]: https://blog.mapbox.com/rendering-big-geodata-on-the-fly-with-geojson-vt-4e4d2a5dd1f2?gi=e5acafcf219d
75+
[Yjs]: https://yjs.dev/
76+
[y-crdt]: https://github.com/y-crdt/y-crdt

README.zh_CN.md

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# 一个无限画布教程
2+
3+
什么是无限画布?[infinitecanvas] 对“无限”的描述如下:
4+
5+
- 高扩展性。用户可以以非线形的形式自由组织内容结构。
6+
- 缩放。模拟真实世界中的“放大”纵览全局和“缩小”观察细节。
7+
- 直接操作。提供对于基础图形的直观编辑能力,包括移动、成组、修改样式等。
8+
- 实时协作。
9+
10+
你一定见过甚至使用过各种包含无限画布的应用,[infinitecanvas] 上就展示了从设计工具到创意画板在内的众多案例,其中不乏一些知名产品包括 [Figma][Modyfi][rnote][tldraw][excalidraw]等等。
11+
12+
作为一个前端,我对其中涉及到的渲染技术很感兴趣。尽管 [tldraw][excalidraw] 等普遍使用易用性更高的 Canvas2D / SVG 技术,但 JS 和 Rust 生态中也有很多编辑器、设计工具使用更底层的渲染技术对 2D 图形进行 GPU 加速,以获得更好的性能和体验:
13+
14+
- [Figma] 使用 C++ 编写了一个 tile-based 的渲染引擎,编译成 WASM 后调用 WebGL 渲染
15+
- [Modyfi] 使用了 Rust 生态中的 [wgpu],同样编译成 WASM 后调用 WebGL2 渲染
16+
- [Zed] 使用 GPUI 渲染矩形、阴影、文本、图片等 UI。
17+
- [vello][xilem] 实验性地使用了 Compute Shader 进行 2D 渲染。
18+
19+
因此在这个教程中,我希望实现以下特性:
20+
21+
- 使用 [@antv/g-device-api] 作为硬件抽象层,支持 WebGL1/2 和 WebGPU。
22+
- 参考 [mapbox][Figma],尝试使用 Tile-based 渲染。
23+
- 使用 SDF 渲染圆、椭圆、矩形等。
24+
- GPU 加速的文本和贝塞尔曲线渲染。
25+
- 使用 [rough.js] 支持手绘风格。
26+
- 使用 CRDT 支持协同 [Yjs]
27+
28+
未来我希望将画布的渲染部分用 Rust 重写,目前项目的完成度还比较低:
29+
30+
- [wgpu] 是非常可靠的硬件抽象层,甚至可以为 [piet] 实现后端。
31+
- Shader 基本可以复用。
32+
- 手绘风格可以使用 [rough-rs]
33+
- [y-crdt][Yjs] 的 Rust 实现。
34+
35+
![rust stack](/images/rust.png)
36+
37+
让我们开始吧!
38+
39+
## 开始
40+
41+
课程项目使用了 [pnpm workspace],因此需要先安装 [pnpm]
42+
43+
```bash
44+
pnpm i
45+
```
46+
47+
进入课程目录后,运行 [vite]
48+
49+
```bash
50+
cd packages/lesson_001
51+
pnpm run dev
52+
```
53+
54+
## 课程 1
55+
56+
[课程 1](/packages/lesson_001/README.zh_CN.md)中我们将介绍:
57+
58+
- 基于 WebGL1/2 和 WebGPU 的硬件抽象层
59+
- 画布 API 设计
60+
- 实现一个简单的插件系统
61+
- 基于硬件抽象层实现一个渲染插件
62+
63+
[infinitecanvas]: https://infinitecanvas.tools/
64+
[Figma]: https://madebyevan.com/figma/building-a-professional-design-tool-on-the-web/
65+
[Modyfi]: https://digest.browsertech.com/archive/browsertech-digest-how-modyfi-is-building-with/
66+
[rnote]: https://github.com/flxzt/rnote
67+
[tldraw]: https://github.com/tldraw/tldraw
68+
[excalidraw]: https://github.com/excalidraw/excalidraw
69+
[rough.js]: https://github.com/rough-stuff/rough
70+
[rough-rs]: https://github.com/orhanbalci/rough-rs
71+
[zed]: https://zed.dev/blog/videogame
72+
[wgpu]: https://wgpu.rs/
73+
[vello]: https://github.com/linebender/vello
74+
[xilem]: https://github.com/linebender/xilem
75+
[piet]: https://github.com/linebender/piet
76+
[@antv/g-device-api]: https://github.com/antvis/g-device-api
77+
[mapbox]: https://blog.mapbox.com/rendering-big-geodata-on-the-fly-with-geojson-vt-4e4d2a5dd1f2?gi=e5acafcf219d
78+
[Yjs]: https://yjs.dev/
79+
[y-crdt]: https://github.com/y-crdt/y-crdt
80+
[pnpm]: https://pnpm.io/installation
81+
[pnpm workspace]: https://pnpm.io/workspaces

0 commit comments

Comments
 (0)