{"id":20461342,"url":"https://github.com/antvis/infinite-canvas-tutorial","last_synced_at":"2025-04-13T06:16:26.511Z","repository":{"id":239685838,"uuid":"800255577","full_name":"antvis/infinite-canvas-tutorial","owner":"antvis","description":"An infinite canvas tutorial","archived":false,"fork":false,"pushed_at":"2024-05-14T02:31:30.000Z","size":4794,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-13T06:16:07.692Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://antv.vision/infinite-canvas-tutorial/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/antvis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-14T01:52:25.000Z","updated_at":"2025-04-11T04:13:50.000Z","dependencies_parsed_at":"2024-05-14T03:36:24.634Z","dependency_job_id":null,"html_url":"https://github.com/antvis/infinite-canvas-tutorial","commit_stats":null,"previous_names":["antvis/infinite-canvas-tutorial"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antvis%2Finfinite-canvas-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antvis%2Finfinite-canvas-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antvis%2Finfinite-canvas-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/antvis%2Finfinite-canvas-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/antvis","download_url":"https://codeload.github.com/antvis/infinite-canvas-tutorial/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248670438,"owners_count":21142905,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T12:24:50.892Z","updated_at":"2025-04-13T06:16:26.490Z","avatar_url":"https://github.com/antvis.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# An Infinite Canvas Tutorial\n\nWhat is an Infinite Canvas? The term \"infinite\" in [infinitecanvas] is described as follows:\n\n-   High scalability. Users can freely organize content structures in a non-linear fashion.\n-   Zooming. Emulates the \"zoom in\" to get an overview and \"zoom out\" to observe details as in the real world.\n-   Direct manipulation. Provides intuitive editing capabilities for basic shapes, including moving, grouping, and modifying styles.\n\nThe [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.\n\nAs 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:\n\n-   [Figma] uses a tile-based rendering engine written in C++, compiled into WASM and then calls WebGL for rendering.\n-   [Modyfi] uses [wgpu] from the Rust ecosystem, also compiled into WASM and then calls WebGL2 for rendering.\n-   [Zed] uses GPUI to render rectangles, shadows, text, images, and other UI elements.\n-   [Vello] and [xilem] experimentally use Compute Shader for 2D rendering.\n\nTherefore, in this tutorial, I hope to implement the following features:\n\n-   Use [@antv/g-device-api] as a hardware abstraction layer, supporting WebGL1/2 and WebGPU.\n-   Referencing [mapbox] and [Figma], attempt to use tile-based rendering.\n-   Use SDF (Signed Distance Field) rendering for circles, ellipses, rectangles, etc.\n-   GPU-accelerated text and Bezier curve rendering.\n-   Use [rough.js] to support hand-drawn styles.\n-   Use CRDT (Conflict-free Replicated Data Type) to support collaborative [Yjs].\n\nLet's get started!\n\n## Getting Started\n\nThe course project uses pnpm workspace, so you need to install pnpm first.\n\n```bash\npnpm i\n```\n\nAfter entering the course directory, run [vite]:\n\n```bash\ncd packages/lesson_001\npnpm run dev\n```\n\n## Lesson 1 - Initialize canvas\n\n-   A hardware abstraction layer based on WebGL1/2 and WebGPU.\n-   Canvas API design.\n-   Implementing a simple plugin system.\n-   Implementing a rendering plugin based on the hardware abstraction layer.\n\n## Lesson 2 - Draw a circle\n\n-   Adding shapes to the canvas.\n-   Drawing a circle using SDF.\n-   Anti Aliasing.\n-   Dirty flag design pattern.\n\n## Lesson 3 - Scene graph and transform\n\n-   Transformations. Make shapes support pan, zoom, rotate, and skew transformations.\n-   Scene graph.\n\n## Lesson 4 - Camera\n\n-   What is a Camera?\n-   Projection transformation.\n-   Camera transformation.\n-   Camera animation. Using Landmark transition between different camera states.\n\n## Lesson 5 - Grid\n\n-   Drawing straight lines using Line Geometry or screen-space techniques.\n-   Drawing dots grid.\n\n## Lesson 6 - Event System\n\n-   Implement an event system compatible with DOM Event API.\n-   How to pick a circle.\n-   Implement a drag-and-drop plugin based on our event system.\n-   Support for pinch zoom gestures.\n\n## Lesson 7 - Web UI\n\n-   Developing Web UI with Lit and Shoelace\n-   Implementing a canvas component\n-   Implementing a zoom toolbar component\n\n# Lesson 8 - Optimize performance\n\n-   What is a draw call\n-   Reducing draw calls with culling\n-   Reducing draw calls by combining batches\n-   Using spatial indexing to improve pickup efficiency\n\n[infinitecanvas]: https://infinitecanvas.tools/\n[Figma]: https://madebyevan.com/figma/building-a-professional-design-tool-on-the-web/\n[Modyfi]: https://digest.browsertech.com/archive/browsertech-digest-how-modyfi-is-building-with/\n[rnote]: https://github.com/flxzt/rnote\n[tldraw]: https://github.com/tldraw/tldraw\n[excalidraw]: https://github.com/excalidraw/excalidraw\n[rough.js]: https://github.com/rough-stuff/rough\n[zed]: https://zed.dev/blog/videogame\n[wgpu]: https://wgpu.rs/\n[vello]: https://github.com/linebender/vello\n[xilem]: https://github.com/linebender/xilem\n[@antv/g-device-api]: https://github.com/antvis/g-device-api\n[mapbox]: https://blog.mapbox.com/rendering-big-geodata-on-the-fly-with-geojson-vt-4e4d2a5dd1f2?gi=e5acafcf219d\n[Yjs]: https://yjs.dev/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantvis%2Finfinite-canvas-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fantvis%2Finfinite-canvas-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fantvis%2Finfinite-canvas-tutorial/lists"}