Comprehensively update user manual and contributor guide, add Adam to core team

This commit is contained in:
Keavon Chambers
2025-01-08 03:52:11 -08:00
parent 9eb544df74
commit 93a60daa24
76 changed files with 931 additions and 685 deletions
+9 -9
View File
@@ -5,27 +5,27 @@ page_template = "book.html"
[extra]
book = true
js = ["video-embed.js"]
js = ["youtube-embed.js"]
+++
**Welcome to the Graphite user manual.** Get ready to learn how the software can help bring your 2D creative ideas to life.
Welcome to the Graphite user manual. Keep reading to to learn how the software can help bring your 2D creative ideas to life.
You may choose to read this sequentially and learn from the structured introduction and sample projects. Or you may jump to chapters of interest that also serve as quick reference.
## More chapters coming soon
## More chapters on the way
Additional manual chapters are being added over time. Check back often!
Additional manual chapters are being added over time. Check back every so often.
## Need help?
If you're ever stuck or confused, ask your questions in the `#🧭user-help` channel of the [Graphite Discord server](https://discord.graphite.rs) or post a thread in the [discussion board](https://github.com/GraphiteEditor/Graphite/discussions) on GitHub.
## Jump right in
<!-- If you're eager to skip the reading, head straight to the [hands-on quickstart video](./introduction) in the next chapter for a beginner project walkthrough you can follow along with. -->
The fastest way to get started is to watch and follow along with the steps in the hands-on quickstart video:
The fastest way to get started is to watch and follow along steps-by-step in the hands-on quickstart video:
<div class="video-embed aspect-16x9">
<img data-video-embed="7gjUhl_3X10" src="https://static.graphite.rs/content/learn/introduction/tutorial-1-vector-art-quickstart-youtube.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Graphite Tutorial 1 - Hands-On Quickstart" />
</div>
## Need help?
If you're ever stuck or confused, ask your questions in the `#🧭user-help` channel of the [Graphite Discord server](https://discord.graphite.rs) or post a thread in the [discussion board](https://github.com/GraphiteEditor/Graphite/discussions) on GitHub.
@@ -1,13 +0,0 @@
+++
title = "Graph"
template = "book.html"
page_template = "book.html"
[extra]
order = 4
+++
- Opening the graph
- Document graph vs. layer graph, limitations
- Adding nodes
- Connecting nodes
@@ -0,0 +1,34 @@
+++
title = "Graph"
template = "book.html"
page_template = "book.html"
[extra]
order = 4
+++
- Opening the graph
- Document graph vs. layer graph, limitations
- Adding nodes
- Connecting nodes
## Overlaid node graph editing
Opening the overlaid node graph shows the structure of nodes and layers that compose the document artwork. It's a more detailed view of what the [Layers](../layers-panel) and [Properties](../properties-panel) panels show.
**Nodes** are the entities with left-to-right input **connectors**.
**Layers** are the larger entities shown with thumbnails and a bottom-to-top direction of data stacking. Their purpose is to composite sources of graphical data on top of one another in a **layer stack**. Layers take input from other nodes or layers via a connector on their left side. When that connector is fed by another layer stack, the Layers panel considers it a **group** because it combines one stack into another parent stack.
Layers and nodes are wired together using **links** which send data between the outputs of nodes to the inputs of others. You can wire up a node by dragging from the output connector of one node to the input connector of its destination node. But note that forming cyclic graphs, where a loop can be traced along the links of a set of nodes, is not permitted. Graphical data flows into the **Output** node which then becomes rendered to the document viewport.
### Node/layer controls
When a layer or node is selected, these buttons will show up on the left side of the control bar:
<p><img src="https://static.graphite.rs/content/learn/interface/document-panel/node-controls-buttons.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="The node/layer controls" /></p>
| | |
|-|-|
| Make<span>&nbsp;</span>Hidden/<br />Make<span>&nbsp;</span>Visible | <p>Toggles the visibility state of the layer or node. This is equivalent to the eye icon button displayed beside each layer. If a node or layer is hidden, it gets bypassed in the data flow. <kbd>Ctrl</kbd><kbd>H</kbd> (macOS: <kbd>⌘</kbd><kbd>H</kbd>) is a shortcut for this toggle that can be used from the graph or viewport.</p> |
| Preview/<br />End<span>&nbsp;</span>Preview | <p>Temporarily moves the graph output away from the Output node and the graph output is instead provided by the previewed node. While previewing, the node is styled with a dashed, brighter border. Ending the preview returns responsibility back to the Output node. This is a handy feature for viewing part of a graph without needing to disconnect the actual Output node and manually restore it later. Clicking a node or layer in the graph while holding <kbd>Alt</kbd> is a shortcut for toggling its preview.</p> |
@@ -8,7 +8,7 @@ order = 3
This manual page hasn't been written yet! But here is an outline for what's coming soon:
- About layers and folders
- Top bar
- Control bar
- Blend modes and opacity
- Adding folders
- Deleting the selected layers
@@ -3,7 +3,7 @@ title = "Imaginate"
[extra]
order = 2
js = ["image-interaction.js"]
js = ["carousel.js"]
+++
Imaginate is a useful tool at every stage in the artistic process. Early on it provides inspiration for styles, color palettes, subjects, and composition. It lets you quickly test ideas and explore artistic directions. It's also a useful way to generate placeholder images and content for kit bashing.
+19 -14
View File
@@ -21,37 +21,41 @@ On the left, the [**menu bar**](./menu-bar) provides quick access to many editor
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The menu bar" /></p>
In the (forthcoming) macOS desktop release, the menu bar is absent from the editor window; its functions are instead located in macOS menu bar.
<!-- In the (forthcoming) macOS desktop release, the menu bar is absent from the editor window; its functions are instead located in macOS menu bar. -->
### Document title
In the center, the **document title** displays the name of the active document. That name is given a `*` suffix if the file has unsaved changes. For example, *Painting.graphite** would be unsaved but *Painting.graphite* would have no changes since it was last saved.
In the center, the **document title** displays the name of the active document. That name is given a `*` suffix if the file has unsaved changes. For example, *Painting.graphite** would be unsaved but *Painting.graphite* would have no changes following its last save.
<p><img src="https://static.graphite.rs/content/learn/interface/document-title.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The document title" /></p>
### Window buttons
On the right, the **window buttons** provide platform-specific controls for the application window. In the (forthcoming) macOS desktop release, this appears on the left side instead.
On the right, the **window buttons** provide platform-specific controls for the application.
<!-- In the (forthcoming) macOS desktop release, this appears on the left side instead. -->
| | |
|-|-|
| **Web** | A button to enter fullscreen mode is displayed.<br /><br />The label "*Go fullscreen to access all hotkeys*" indicates that some shortcut keys like <kbd>Ctrl</kbd><kbd>N</kbd> (macOS: <kbd>⌘</kbd><kbd>N</kbd>) are reserved by the web browser and can only be used in fullscreen mode. (An alternative to fullscreen mode: include <kbd>Alt</kbd> in the shortcut combinations for browser-reserved hotkeys.)<br /><br /><img src="https://static.graphite.rs/content/learn/interface/window-buttons-web.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Fullscreen button" /> |
| **Windows<br />& Linux** | The standard window controls are displayed: minimize, maximize/restore down, and close.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/window-buttons-windows-linux.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Minimize/maximize/close window buttons" /> |
| **macOS** | The standard window controls are displayed: close, minimize, and fullscreen. These are located on the left of the title bar.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/window-buttons-macos.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Close/minimize/fullscreen window buttons" /> |
| **Web** | <p>A button to enter fullscreen mode is displayed.</p><p>The label "*Go fullscreen to access all hotkeys*" indicates that some shortcut keys like <kbd>Ctrl</kbd><kbd>N</kbd> (macOS: <kbd>⌘</kbd><kbd>N</kbd>) are reserved by the web browser and can only be used in fullscreen mode. (An alternative to going fullscreen: include <kbd>Alt</kbd> in the shortcut combinations for browser-reserved hotkeys.)</p><p><img src="https://static.graphite.rs/content/learn/interface/window-buttons-web.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Fullscreen button" /></p> |
<!-- | **Windows<br />& Linux** | The standard window controls are displayed: minimize, maximize/restore down, and close.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/window-buttons-windows-linux.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Minimize/maximize/close window buttons" /> | -->
<!-- | **macOS** | The standard window controls are displayed: close, minimize, and fullscreen. These are located on the left of the title bar.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/window-buttons-macos.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Close/minimize/fullscreen window buttons" /> | -->
## Workspace
The **workspace** is the editor's main content area. It houses the **panels** packed next to one another. The **gutter** lines between neighboring panels may be dragged to resize them.
The **workspace** is the editor's main content area, filled with **panels** arranged next to one another. The **gutter** lines, located between neighboring panels, may be dragged to resize them.
<p><img src="https://static.graphite.rs/content/learn/interface/workspace__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The workspace" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/workspace__3.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The workspace" /></p>
### Panels
Panels are regions of the UI dedicated to a specific purpose. [**Document**](./document-panel), [**Properties**](./properties-panel), and [**Layers**](./layers-panel) are presently the three panel types. Each will be covered later in the chapter.
Panels are regions of the UI dedicated to a specific purpose. [**Document**](./document-panel), Properties, and Layers are presently the three panel types.
Each panel name is shown in its **panel tab bar**. Panel tabs provide a quick way to swap between multiple panels occupying the same area (currently only documents support this). Down the road, these tabs will be dockable so the default layout may be customized.
Each panel name is shown in its **panel header**. Panel tabs offer a quick way to swap between multiple panels occupying the same area (currently only documents support this).
Beneath the panel tab bar, the **panel body** displays the content for its panel type. Each will be described in the following pages.
Down the road, these tabs will be dockable so the default layout may be customized.
Beneath the panel header, the **panel content** displays the content for its panel type. Each will be described in the following pages.
## Status bar
@@ -75,6 +79,7 @@ The following chart describes each icon representing the mouse inputs you can pe
| | Clicks | Drags | Others |
|-|:-:|:-:|:-:|
| **Left<br />mouse<br />button** | Left click<br /><br /><img src="https://static.graphite.rs/content/learn/interface/mouse-input-left-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Left click icon" /> | Left click drag<br /><br /><img src="https://static.graphite.rs/content/learn/interface/mouse-input-left-click-drag.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Left click drag icon" /> | Left double-click<br /><br /><img src="https://static.graphite.rs/content/learn/interface/mouse-input-left-double-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Left double-click icon" /> |
| **Right<br />mouse<br />button** | Right click<br /><br /><img src="https://static.graphite.rs/content/learn/interface/mouse-input-right-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Right click icon" /> | Right click drag<br /><br /><img src="https://static.graphite.rs/content/learn/interface/mouse-input-right-click-drag.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Right click drag icon" /> | Right double-click<br /><br /><img src="https://static.graphite.rs/content/learn/interface/mouse-input-right-double-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Right double-click icon" /> |
| **Middle<br />mouse<br />button** | Middle click<br /><br /><img src="https://static.graphite.rs/content/learn/interface/mouse-input-middle-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Middle click icon" /> | Middle click drag<br /><br /><img src="https://static.graphite.rs/content/learn/interface/mouse-input-middle-click-drag.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Middle click drag icon" /> | Scroll up/down<br /><br /><img src="https://static.graphite.rs/content/learn/interface/mouse-input-scroll-up.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Scroll up icon" /> <img src="https://static.graphite.rs/content/learn/interface/mouse-input-scroll-down.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Scroll down icon" /> |
| | | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-drag.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Drag icon" /><br style="line-height: 4" />Drag | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-stationary.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Mouse kept stationary icon" /><br style="line-height: 4" />Stationary |
| **Left<br />mouse<br />button** | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-left-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Left click icon" /><br style="line-height: 4" />Left click | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-left-click-drag.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Left click drag icon" /><br style="line-height: 4" />Left click drag | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-left-double-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Left double-click icon" /><br style="line-height: 4" />Left double-click |
| **Right<br />mouse<br />button** | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-right-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Right click icon" /><br style="line-height: 4" />Right click | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-right-click-drag.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Right click drag icon" /><br style="line-height: 4" />Right click drag | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-right-double-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Right double-click icon" /><br style="line-height: 4" />Right double-click |
| **Middle<br />mouse<br />button** | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-middle-click.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Middle click icon" /><br style="line-height: 4" />Middle click | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-middle-click-drag.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Middle click drag icon" /><br style="line-height: 4" />Middle click drag | <img src="https://static.graphite.rs/content/learn/interface/mouse-icon-scroll.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Scroll up/down icons" /><br style="line-height: 4" />Scroll up/down |
@@ -5,131 +5,94 @@ title = "Document panel"
order = 2
+++
The **Document panel** is the main content area where the artwork is displayed and edited using **tools** within the **viewport**. It's also where the **node graph** can be overlaid by pressing <kbd>Ctrl</kbd><kbd>Space</kbd>. The viewport is for interactive, visual editing of the **canvas**. The node graph is where you can inspect the underlying structure of the document and edit it in a more technical way if the need arises.
The **Document panel** is the main content area where the artwork is displayed and edited using **tools** within the **viewport**. It's also where the **node graph** can be overlaid by pressing <kbd>Ctrl</kbd><kbd>Space</kbd>.
The viewport is for interactive, visual editing of the **canvas**. The node graph is where you can inspect the underlying structure of the document and edit it in a more technical manner when the need arises.
There is one instance of the Document panel per open document file. Each has its own tab labeled with its file name. When a document has unsaved changes, an `*` is included at the end of the name.
The Document panel is composed of three main areas:
- The **top bar** runs across the top of the panel and provides controls and view options.
- The **shelf** is the narrow vertical bar that runs down the left of the panel and lists a selection of tools or nodes.
- The **table** fills the rest of the panel and contains the viewport and overlaid node graph.
- The **control bar** runs across the top of the panel and shows tool and viewport controls.
- The **tool shelf** is the vertical bar that runs down the left of the panel showing the editing tools and working colors.
- The **viewport** fills most of the panel and contains a view of the canvas which can be interactively edited using the tools.
The content of each depends if the viewport or node graph is visible, as described in the two sections below.
## Control bar
## Interactive viewport editing
Here is where you control your interaction with the document via active tool and view options.
### Top bar
While the viewport is visible, the left of the bar provides controls for the active tool and the right provides view options.
#### Editing modes
<!--
### Editing modes
Only the default mode is currently implemented. Others will be added in the future and this dropdown is a placeholder for that.
| | |
|-|-|
| <img src="https://static.graphite.rs/content/learn/interface/document-panel/editing-modes__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="The editing modes dropdown menu" /> | The default, **Design Mode**, is for directly editing the artwork.<br /><br />Once implemented, **Select Mode** will be where marquee selections are made to constrain the active tool's edits to a masked area of choice.<br /><br />Once implemented, **Guide Mode** will be for creating guides and constraint systems used for alignment and constraint-based layout. |
| <img src="https://static.graphite.rs/content/learn/interface/document-panel/editing-modes__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="The editing modes dropdown menu" /> | The default, **Design Mode**, is for directly editing the artwork.<br /><br />Once implemented, **Select Mode** will be where marquee selections are made to constrain the active tool's edits to a masked area of choice.<br /><br />Once implemented, **Guide Mode** will be for creating guides and constraint systems used for alignment and constraint-based layout. |
-->
#### Tool options
### Tool controls
Provides controls for the active tool. These change with each tool, and are blank for some.
The left side of the control bar has controls pertaining to the active tool. It's empty for some tools.
<p><img src="https://static.graphite.rs/content/learn/interface/document-panel/tool-options__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Example of the tool options for the Select tool" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/document-panel/tool-options__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Example of the tool controls for the Select tool" /></p>
Pictured above is the tool options for the Select tool. It provides options related to its selection behavior and offers useful action buttons for modifying the selected layers with alignment, flipping, and (not-yet-implemented) boolean operations.
The example above shows the Select tool controls. Because the Select tool deals with selecting and transforming layers, its controls include:
- The selection mode to determine if the deepest or shallowest layer in a nested hierarchy is selected when clicked.
- The point about which the **transform cage** is centered.
- Actions to align and distribute the selected layers amongst themselves.
- Actions to flip the selected layers horizontally or vertically.
- Actions to cut or combine selected layers with themselves using boolean operations.
<!-- Each tool's options are described in the [Tools](../../tools) chapter. -->
Each tool's options will be described in the upcoming tools chapter.
Depending on which tool is active, these will change to reflect the pertinent options.
#### Viewport options
### Viewport controls
Shows options for how the viewport is displayed and interacted with.
The right side of the control bar has controls related to the active document and viewport.
<p><img src="https://static.graphite.rs/content/learn/interface/document-panel/viewport-options__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The viewport options" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/document-panel/viewport-options__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The viewport controls" /></p>
| | |
|-|-|
| Overlays | When checked (default), overlays are shown. When unchecked, they are hidden. Overlays are the contextual visualizations (like bounding boxes and vector points) that appear atop the viewport when using tools. |
| Snapping | When checked (default), drawing and dragging shapes and vector points means they will snap to other areas of geometric interest from other layers, like corners or anchor points. When unchecked, the selection moves freely.<br /><br />Fine-grained options are available by clicking the overflow button to access its options popover menu:<br /><br /><img src="https://static.graphite.rs/content/learn/interface/document-panel/snapping-popover__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="Snapping options popover menu" /><ul><li>**Bounding Boxes** sets whether the *edges* and *centers* of the rectangle that encloses the bounds of each other layer is used for snapping.</li><li>**Geometry** sets whether the anchors and handles of vector paths are used for snapping.</li></ul> |
| Grid | When checked (off by default), grid lines are shown to which drawn and edited shapes are snapped to. The initial grid scale is 1 document unit, helping you draw pixel-perfect artwork.<ul><li>**Origin** is the position where the repeating grid pattern begins from.</li><li>**Type** sets whether the grid pattern is made of squares or triangles.<br /><br />**Rectangular** is a square pattern:<br /><br /><img src="https://static.graphite.rs/content/learn/interface/document-panel/grid-rectangular-popover.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="Snapping options popover menu" /><br /><ul><li>**Spacing** is the width and height of the square grid cells.</li></ul><br /><br />**Isometric** is a triangle pattern:<br /><br /><img src="https://static.graphite.rs/content/learn/interface/document-panel/grid-isometric-popover.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="Snapping options popover menu" /><br /><ul><li>**Y Spacing** is the height between vertical repetitions of the grid.</li><li>**Angles** is the slant of the upward and downward sloped grid lines.</li></ul></li></ul> |
| View Mode | **Normal** (default): The artwork is rendered normally.<br /><br />**Outline**: The artwork is rendered as a wireframe.<br /><br />**Pixels**: **Not implemented yet.** The artwork is rendered as it would appear when exported as a bitmap image at 100% scale regardless of the viewport zoom level. |
| Zoom In | Zooms the viewport in to the next whole increment. |
| Zoom Out | Zooms the viewport out to the next whole increment. |
| Reset Tilt and Zoom to 100% | Resets the viewport tilt to 0°. Resets the viewport zoom to 100% which matches the canvas and viewport pixel scale 1:1. |
| Viewport Zoom | Indicates the current zoom level of the viewport and allows precise values to be chosen. |
| Viewport Tilt | Hidden except when the viewport is tilted (use the *View* > *Tilt* menu action). Indicates the current tilt angle of the viewport and allows precise values to be chosen.
| Node Graph | Toggles the visibility of the overlaid node graph. |
| Overlays | <p>When checked (default), overlays are shown. When unchecked, they are hidden. Overlays are the temporary contextual visualizations (like bounding boxes and vector manipulators) that are usually blue and appear atop the viewport when using tools.</p> |
| Snapping | <p>When checked (default), drawing and dragging shapes and vector points means they will snap to other areas of geometric interest like corners or anchor points. When unchecked, the selection moves freely.<br /><br />Fine-grained options are available by clicking the overflow button to access its options popover menu:</p><p><img src="https://static.graphite.rs/content/learn/interface/document-panel/snapping-popover__3.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="Snapping options popover menu" /></p><p>Snapping options relating to **Bounding Boxes**:</p><p><ul><li>**Box Center** enables snapping to the center point of any layer's bounding box.</li><li>**Box Corner** enables snapping to the four corners of any layer's bounding box.</li><li>**Along Edge** enables snapping anywhere along the four edges of any layer's bounding box.</li><li>**Midpoint of Edge** enables snapping to any of the four points at the middle of the edges of any layer's bounding box.</li><li>**Align to Box** enables snapping to anywhere outside any layer's bounding box along the four lines extending outward from its edges.</li><li>**Evenly Distribute Boxes** enables snapping to a consistent distance offset established by the bounding boxes of nearby layers (due to a bug, **Box Center** and **Box Corner** must be enabled).</li></ul></p><p>Snapping options relating to **Geometry**:</p><p><ul><li>**Anchor** enables snapping to the anchor point of any vector path.</li><li>**Line Midpoint** enables snapping to the point at the middle of any straight line segment of a vector path.</li><li>**Path** enables snapping along the length of any vector path.</li><li>**Normal to Path** enables snapping a line to a point perpendicular to a vector path (due to a bug, **Intersection** must be enabled).</li><li>**Tangent to Path** enables snapping a line to a point tangent to a vector path (due to a bug, **Intersection** must be enabled).</li><li>**Intersection** enables snapping to any points where vector paths intersect.</li><li>**Align to Selected Path** enables snapping to the handle control points of a selected vector layer.</li></ul></p> |
| Grid | <p>When checked (off by default), grid lines are shown and snapping to them becomes active. The initial grid scale is 1 document unit, helping you draw pixel-perfect artwork.</p><ul><li><p>**Type** sets whether the grid pattern is made of squares or triangles.</p><p>**Rectangular** is a pattern of horizontal and vertical lines:</p><p><img src="https://static.graphite.rs/content/learn/interface/document-panel/grid-rectangular-popover__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="Snapping options popover menu" /></p><p>It has one option unique to this mode:</p><ul><li>**Spacing** is the width and height of the rectangle grid cells.</li></ul><p>**Isometric** is a pattern of triangles:</p><p><img src="https://static.graphite.rs/content/learn/interface/document-panel/grid-isometric-popover__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="Snapping options popover menu" /></p><p>It has two options unique to this mode:</p><ul><li>**Y Spacing** is the height between vertical repetitions of the grid.</li><li>**Angles** is the slant of the upward and downward sloped grid lines.</li></ul></li><li>**Display** gives control over the appearance of the grid. The **Display as dotted grid** checkbox (off by default) replaces the solid lines with dots at their intersection points.</li><li>**Origin** is the position in the canvas where the repeating grid pattern begins from. If you need an offset for the grid where an intersection occurs at a specific location, set those coordinates.</li></ul> |
| View Mode | <p>**Normal** (default): The artwork is rendered normally.</p><p>**Outline**: The artwork is rendered as a wireframe.</p><p>**Pixels**: **Not implemented yet.** The artwork is rendered as it would appear when exported as a bitmap image at 100% scale regardless of the viewport zoom level.</p> |
| Zoom In | <p>Zooms the viewport in to the next whole increment.</p> |
| Zoom Out | <p>Zooms the viewport out to the next whole increment.</p> |
| Reset Tilt and Zoom to 100% | <p>Resets the viewport tilt to 0°. Resets the viewport zoom to 100% which matches the canvas and viewport pixel scale 1:1.</p> |
| Viewport Zoom | <p>Indicates the current zoom level of the viewport and allows precise values to be chosen.</p> |
| Viewport Tilt | <p>Hidden except when the viewport is tilted (use the *View* > *Tilt* menu action). Indicates the current tilt angle of the viewport and allows precise values to be chosen.</p> |
| Node Graph | <p>Toggles the visibility of the overlaid node graph.</p> |
### Shelf
## Tool shelf
This narrow bar runs vertically down the left side of the Document panel beside the table where the viewport is displayed.
This narrow bar runs vertically down the left side of the Document panel beside the viewport.
#### Tool shelf
### Tools
Located at the top of the shelf area, the **tool shelf** provides a selection of **tools** for interactively editing the artwork.
Located at the top of the tool shelf area, the **tool shelf** provides a selection of **tools** for interactively editing the artwork.
| | |
|-|-|
| <img src="https://static.graphite.rs/content/learn/interface/document-panel/tool-shelf__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="The tool shelf" /> | The tool shelf is split into three sections: the **general tools** (gray icons), **vector tools** (blue icons), and **raster tools** (orange icons).<br /><br /><ul><li>**General tools** are used for assorted editing tasks within the viewport.</li><li>**Vector tools** are used for drawing and editing vector shapes, curves, and text.</li><li>**Raster tools** are used for drawing and editing raster image content. The grayed out icons are placeholders for upcoming tools.</li></ul> |
| <img src="https://static.graphite.rs/content/learn/interface/document-panel/tool-shelf__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="The tool shelf" /> | <p>The tool shelf is split into three sections: the **general tools** (gray icons), **vector tools** (blue icons), and **raster tools** (orange icons).</p><p><ul><li>**General tools** are used for assorted editing tasks within the viewport.</li><li>**Vector tools** are used for drawing and editing vector shapes, paths, and text.</li><li>**Raster tools** are used for drawing and editing raster image content. The grayed out icons are placeholders for upcoming tools.</li></ul></p> |
#### Working colors
### Working colors
The **working colors** are the two colors used by the active tool.
| | |
|-|-|
| <img src="https://static.graphite.rs/content/learn/interface/document-panel/working-colors.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The working colors" /> | The upper circle is the **primary color**. The lower circle is the **secondary color**.<br /><br />There are two buttons located underneath: **Swap** which reverses the current color choices, and **Reset** which restores the primary color to black and the secondary color to white. |
| <img src="https://static.graphite.rs/content/learn/interface/document-panel/working-colors.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The working colors" /> | <p>The upper circle is the **primary color**. The lower circle is the **secondary color**.</p><p>There are two buttons located underneath: **Swap** which reverses the current color choices, and **Reset** which restores the primary color to black and the secondary color to white.</p> |
Various tools provide choices for using the primary and secondary colors as controls in the tool options. For example, many vector tools have **Fill** and **Stroke** options that use the current secondary and primary colors, respectively, as defaults:
The tool controls (above the viewport) for some of the tools offer choices for using the primary and secondary colors. For example, the vector drawing tools have **Fill** and **Stroke** options that use the current secondary and primary colors, respectively, as defaults:
<p><img src="https://static.graphite.rs/content/learn/interface/document-panel/tool-options-fill-stroke-colors__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The Fill and Stroke controls for a vector tool's options" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/document-panel/tool-options-fill-stroke-colors__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="The Fill and Stroke controls for a vector tool's controls" /></p>
These options each allow choices of being driven by the primary working color, secondary working color, or a custom color set just for that tool.
### Table
## Viewport
The **table** contains the **viewport** bounded by rulers and scrollbars along its edges.
The **viewport** is the view into the canvas. It lets you interact visually with the artwork content. It also displays temporary contextual **overlays** atop the content to assist with your editing.
#### Rulers and scrollbars
The **rulers**, located along the top and left edges within the table, display the size and location of the viewport's visible region in canvas coordinates. The rulers can be hidden with the *View* > *Rulers* toggleable menu option.
The **scrollbars**, located along the bottom and right edges within the table, allow scrolling the artwork to show different parts of the canvas in the viewport.
#### Viewport
The **viewport** is the view into the canvas. It is where the artwork is displayed and gets interactively edited using the tools.
## Overlaid node graph editing
Opening the overlaid node graph shows the structure of nodes and layers that compose the document artwork. It's a more detailed view of what the [Layers](../layers-panel) and [Properties](../properties-panel) panels show.
**Nodes** are the entities with left-to-right input **connectors**.
**Layers** are the larger entities shown with thumbnails and a bottom-to-top direction of data stacking. Their purpose is to composite sources of graphical data on top of one another in a **layer stack**. Layers take input from other nodes or layers via a connector on their left side. When that connector is fed by another layer stack, the Layers panel considers it a **group** because it combines one stack into another parent stack.
Layers and nodes are wired together using **links** which send data between the outputs of nodes to the inputs of others. You can wire up a node by dragging from the output connector of one node to the input connector of its destination node. But note that forming cyclic graphs, where a loop can be traced along the links of a set of nodes, is not permitted. Graphical data flows into the **Output** node which then becomes rendered to the document viewport.
### Top bar
Provides several controls for the graph and selected node or layer. The options change based on what's selected.
#### Node/layer controls
When a layer or node is selected, these buttons will show up on the left side of the top bar:
<p><img src="https://static.graphite.rs/content/learn/interface/document-panel/node-controls-buttons.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="The node/layer controls" /></p>
| | |
|-|-|
| Make<span>&nbsp;</span>Hidden/<br />Make<span>&nbsp;</span>Visible | Toggles the visibility state of the layer or node. This is equivalent to the eye icon button displayed beside each layer. If a node or layer is hidden, it gets bypassed in the data flow. <kbd>Ctrl</kbd><kbd>H</kbd> (macOS: <kbd>⌘</kbd><kbd>H</kbd>) is a shortcut for this toggle that can be used from the graph or viewport. |
| Preview/<br />End<span>&nbsp;</span>Preview | Temporarily moves the graph output away from the Output node and the graph output is instead provided by the previewed node. While previewing, the node is styled with a dashed, brighter border. Ending the preview returns responsibility back to the Output node. This is a handy feature for viewing part of a graph without needing to disconnect the actual Output node and manually restore it later. Clicking a node or layer in the graph while holding <kbd>Alt</kbd> is a shortcut for toggling its preview. |
### Shelf
This narrow bar, which is currently empty, runs vertically down the left side of the Document panel beside the graph area. In the future, icons for categories of nodes will be listed here, allowing quick access and browsing.
#### Working colors
Same functionality as [explained for the viewport](#working-colors) (when the graph overlay is closed).
The viewport is also surrounded by **scrollbars** and **rulers** around its edges. Scrollbars, located along the bottom/right edges, allow scrolling the artwork to show different parts in the viewport. Rulers, located along the top/left edges, offer dimensional information for the area of the canvas that's within view. They can be hidden with the *View* > *Rulers* toggleable menu option.
+50 -46
View File
@@ -21,93 +21,97 @@ The **app button** shows the [Graphite logo](/logo). Clicking it opens the Graph
## File
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-file.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The File menu" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-file__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The File menu" /></p>
The **File menu** lists actions related to file handling:
| | |
|-|-|
| New… | Opens the **New Document** dialog for creating a blank canvas in a new editor tab.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/menu-bar/dialog-new-document.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The 'New Document' dialog" /> |
| Open… | Opens the operating system file picker dialog for selecting a `.graphite` file from disk to be opened in a new editor tab. |
| Open Demo Artwork… | Opens the **Demo Artwork** dialog for loading a choice of premade sample artwork files provided for you to explore. Click the button below each image to open it.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/menu-bar/dialog-demo-artwork.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The 'Demo Artwork' dialog" /> |
| Close | Closes the active document. If it has unsaved changes (denoted by the `*` after the file name), you will be asked to save or discard the changes. |
| Close All | Closes all open documents. To avoid accidentally losing unsaved work, you will be asked to confirm that you want to proceed which will discard the unsaved changes in all open documents. |
| Save | Saves the active document by writing the `.graphite` file to disk. An operating system file download dialog may appear asking where to place it. That dialog will provide an opportunity to save over a previous version of the file, if you wish, by picking the identical name instead of saving another instance with a number after it. |
| Import… | Opens the operating system file picker dialog for selecting an image file from disk to be placed as a new bitmap image layer into the active document. |
| Export… | Opens the **Export** dialog for saving the artwork as a *File Type* of *PNG*, *JPG*, or *SVG*. *Scale Factor* multiplies the content's document scale, so a value of 2 would export 300x400 content as 600x800 pixels. *Bounds* picks what area to render: *All Artwork* uses the bounding box of all layers, *Selection* uses the bounding box of the currently selected layers, and an *Artboard: \[Name\]* uses the bounds of that artboard. *Transparency* exports the PNG or SVG file with transparency instead of the artboard background color.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/menu-bar/dialog-export.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The 'Export' dialog" /> |
| Preferences… | Opens the **Editor Preferences** dialog for configuring Graphite's settings.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/menu-bar/dialog-editor-preferences.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The 'Editor Preferences' dialog" /> |
| New… | <p>Opens the **New Document** dialog for creating a blank canvas in a new editor tab.</p><p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/dialog-new-document.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The 'New Document' dialog" /></p> |
| Open… | <p>Opens the operating system file picker dialog for selecting a `.graphite` file from disk to be opened in a new editor tab.</p> |
| Open Demo Artwork… | <p>Opens the **Demo Artwork** dialog for loading a choice of premade sample artwork files provided for you to explore. Click the button below each image to open it.</p><p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/dialog-demo-artwork__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The 'Demo Artwork' dialog" /></p> |
| Close | <p>Closes the active document. If it has unsaved changes (denoted by the `*` after the file name), you will be asked to save or discard the changes.</p> |
| Close All | <p>Closes all open documents. To avoid accidentally losing unsaved work, you will be asked to confirm that you want to proceed which will discard the unsaved changes in all open documents.</p> |
| Save | <p>Saves the active document by writing the `.graphite` file to disk. An operating system file download dialog may appear asking where to place it. That dialog will provide an opportunity to save over a previous version of the file, if you wish, by picking the identical name instead of saving another instance with a number after it.</p> |
| Import… | <p>Opens the operating system file picker dialog for selecting an image file from disk to be placed as a new bitmap image layer or SVG content into the active document.</p> |
| Export… | <p>Opens the **Export** dialog for saving the artwork as a *File Type* of *PNG*, *JPG*, or *SVG*. *Scale Factor* multiplies the content's document scale, so a value of 2 would export 300x400 content as 600x800 pixels. *Bounds* picks what area to render: *All Artwork* uses the bounding box of all layers, *Selection* uses the bounding box of the currently selected layers, and an *Artboard: \[Name\]* uses the bounds of that artboard. *Transparency* exports PNG or SVG files with transparency instead of the artboard background color.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/menu-bar/dialog-export.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The 'Export' dialog" /></p> |
| Preferences… | <p>Opens the **Editor Preferences** dialog for configuring Graphite's settings.<br /><br /><img src="https://static.graphite.rs/content/learn/interface/menu-bar/dialog-editor-preferences__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The 'Editor Preferences' dialog" /></p> |
## Edit
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-edit.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The Edit menu" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-edit__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The Edit menu" /></p>
The **Edit menu** lists actions related to the editing workflow:
| | |
|-|-|
| Undo | Steps back in the history of changes in the active document. |
| Redo | Steps forward in the history of changes in the active document. |
| Cut | Copies the selected layer(s) to the clipboard, then deletes them. |
| Copy | Copies the selected layer(s) to the clipboard. |
| Paste | Pastes the copied layer(s) from the clipboard into the document. It will end up beside a selected layer or inside a selected folder, or otherwise at the base of the folder structure.<br /><br />In the web version of Graphite, your browser will ask for permission to read from your clipboard which you must grant; using the hotkey <kbd>Ctrl</kbd><kbd>V</kbd> (macOS: <kbd>⌘</kbd><kbd>V</kbd>) works without browser permission. |
| Undo | <p>Steps back in the history of changes in the active document.</p> |
| Redo | <p>Steps forward in the history of changes in the active document.</p> |
| Cut | <p>Copies the selected layer(s) to the clipboard, then deletes them.</p> |
| Copy | <p>Copies the selected layer(s) to the clipboard.</p> |
| Paste | <p>Pastes the copied layer(s) from the clipboard into the document. It will end up directly above the selected layer, or otherwise at the base of the folder structure.</p><p>In the web version of Graphite, your browser will ask for permission to read from your clipboard which you must grant; alternatively, using the hotkey <kbd>Ctrl</kbd><kbd>V</kbd> (macOS: <kbd>⌘</kbd><kbd>V</kbd>) works without the browser needing this permission.</p> |
## Layer
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-layer.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The Layer menu" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-layer__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The Layer menu" /></p>
The **Layer menu** lists actions related to the layers within a document:
| | |
|-|-|
| Select All | Selects all layers and folders in the document. |
| Deselect All | Deselects everything in the document. |
| Delete Selected | Removes all selected layers and folders. |
| Grab Selected | Begin grabbing the selected layer(s) to translate (move) them around with your cursor's movement. Lock to an axis with <kbd>X</kbd> or <kbd>Y</kbd> then use the number keys to type a pixel distance value. Confirm with a left click or <kbd>Enter</kbd>. Cancel with a right click or <kbd>Esc</kbd>. |
| Rotate Selected | Begin rotating the selected layer(s) around their pivot point with your cursor's movement. Use the number keys to type an angle value in degrees. Confirm with a left click or <kbd>Enter</kbd>. Cancel with a right click or <kbd>Esc</kbd>. |
| Scale Selected | Begin scaling the selected layer(s) around their pivot point with your cursor's movement. Lock to an axis with <kbd>X</kbd> or <kbd>Y</kbd>. Use the number keys to type a scale multiplier value. Confirm with a left click or <kbd>Enter</kbd>. Cancel with a right click or <kbd>Esc</kbd>. |
| Order ><br />Raise to Front | Reorders the selected layer(s) above all other layers within their same folder(s), so they appear in the layer stack and render above those other layers. |
| Order ><br />Raise | Reorders the selected layers(s) up by one in the layer stack, so any layer that was immediately above the selected layer(s) ends up immediately below. |
| Order ><br />Lower | Reorders the selected layers(s) down by one in the layer stack, so any layer that was immediately below the selected layer(s) ends up immediately above. |
| Order ><br />Lower to Back | Reorders the selected layer(s) below all other layers within their same folder(s), so they appear in the layer stack and render below those other layers. |
| New | <p>Creates a new layer in the active document. It will end up directly above the selected layer, or otherwise at the base of the folder structure.</p> |
| Select All | <p>Selects all layers and folders in the document.</p> |
| Deselect All | <p>Deselects everything in the document.</p> |
| Previous Selection | <p>Goes back to the previously selected set of layers/nodes in the selection history.</p><p>If the side of your mouse has navigation buttons, you can use the back button as a shortcut (not supported in Firefox).</p> |
| Next Selection | <p>Goes forward to the next selected set of layers/nodes in the selection history.</p><p>If the side of your mouse has navigation buttons, you can use the forward button as a shortcut (not supported in Firefox).</p> |
| Group Selected | <p>Creates a new folder in place of the selected layer(s), then moves them into that folder.</p> |
| Delete Selected | <p>Removes all selected layers and folders.</p> |
| Grab Selected | <p>Begin grabbing the selected layer(s) to translate (move) them around with your cursor's movement. Lock to an axis with <kbd>X</kbd> or <kbd>Y</kbd> then use the number keys to type a pixel distance value. Confirm with a left click or <kbd>Enter</kbd>. Cancel with a right click or <kbd>Esc</kbd>.</p> |
| Rotate Selected | <p>Begin rotating the selected layer(s) around their pivot point with your cursor's movement. Use the number keys to type an angle value in degrees. Confirm with a left click or <kbd>Enter</kbd>. Cancel with a right click or <kbd>Esc</kbd>.</p> |
| Scale Selected | <p>Begin scaling the selected layer(s) around their pivot point with your cursor's movement. Lock to an axis with <kbd>X</kbd> or <kbd>Y</kbd>. Use the number keys to type a scale multiplier value. Confirm with a left click or <kbd>Enter</kbd>. Cancel with a right click or <kbd>Esc</kbd>.</p> |
| Order ><br />Raise to Front | <p>Reorders the selected layer(s) above all others within their same folder(s), so they appear in the layer stack and render above those other layers.</p> |
| Order ><br />Raise | <p>Reorders the selected layers(s) up by one in the layer stack, so any layer that was immediately above the selected layer(s) ends up immediately below.</p> |
| Order ><br />Lower | <p>Reorders the selected layers(s) down by one in the layer stack, so any layer that was immediately below the selected layer(s) ends up immediately above.</p> |
| Order ><br />Lower to Back | <p>Reorders the selected layer(s) below all others within their same folder(s), so they appear in the layer stack and render below those other layers.</p> |
## Document
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-document.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The Document menu" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-document__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The Document menu" /></p>
The **Document menu** lists actions related to the document and artwork:
| | |
|-|-|
| Clear Artboards | Removes all artboards from the document, thus enabling an infinite canvas. |
| Clear Artboards | <p>Removes all artboards from the document, resulting in an infinite canvas.</p> |
## View
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-view.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The View menu" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-view__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The View menu" /></p>
The **View menu** lists actions related to the view of the canvas and viewport:
The **View menu** lists actions related to the view of the canvas within the viewport:
| | |
|-|-|
| Tilt | Begins tilting the viewport angle based on your mouse movements. Hold <kbd>Ctrl</kbd> to snap to 15° increments. Confirm with a left click or <kbd>Enter</kbd>. Cancel with a right click or <kbd>Esc</kbd>. |
| Reset Tilt | Sets the viewport tilt angle back to 0°. |
| Zoom In | Narrows the view to the next whole zoom increment. |
| Zoom Out | Widens the view to the next whole zoom increment. |
| Zoom to Fit Selection | Zooms and frames the viewport to the bounding box of the selected layer(s). |
| Zoom to Fit All | Zooms and frames the viewport to fit all artboards, or all artwork if using infinite canvas. |
| Zoom to 100% | Zooms the viewport in or out to 100% scale, matching 1:1 the scale of the document and viewport. |
| Zoom to 200% | Zooms the viewport in or out to 200% scale, displaying the artwork at twice the actual size. |
| Rulers | Toggles visibility of the rulers shown along the top and left edges of the viewport. |
| Tilt | <p>Begins tilting the viewport angle based on your mouse movements.</p><p>While tilting, hold <kbd>Ctrl</kbd> to snap to 15° increments. Confirm with a left click or <kbd>Enter</kbd>. Cancel with a right click or <kbd>Esc</kbd>.</p> |
| Reset Tilt | <p>Sets the viewport tilt angle back to 0°.</p> |
| Zoom In | <p>Narrows the view to the next whole zoom increment, such as:</p><p>25%, 33.33%, 40%, 50%, 66.67%, 80%, 100%, 125%, 160%, 200%, 250%, 320%, 400%, 500%</p> |
| Zoom Out | <p>Widens the view to the next whole zoom increment, such as above.</p> |
| Zoom to Fit Selection | <p>Zooms and frames the viewport to the bounding box of the selected layer(s).</p> |
| Zoom to Fit All | <p>Zooms and frames the viewport to fit all artboards, or all artwork if using infinite canvas.</p> |
| Zoom to 100% | <p>Zooms the viewport in or out to 100% scale, making the document and viewport scales match 1:1.</p> |
| Zoom to 200% | <p>Zooms the viewport in or out to 200% scale, displaying the artwork at twice the actual size.</p> |
| Rulers | <p>Toggles visibility of the rulers along the top/left edges of the viewport.</p> |
## Help
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-help.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The Help menu" /></p>
<p><img src="https://static.graphite.rs/content/learn/interface/menu-bar/menu-help__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="The Help menu" /></p>
The **Help menu** lists actions related to information about Graphite:
| | |
|-|-|
| About Graphite… | Opens the **About Graphite** dialog for displaying release and license information. |
| User Manual | Opens this [user manual](./learn). |
| Report a Bug | Opens a page to file a [new GitHub issue](https://github.com/GraphiteEditor/Graphite/issues/new). |
| Visit on GitHub | Opens the [Graphite GitHub repository](https://github.com/GraphiteEditor/Graphite). |
| *Debug section* | Developer-only actions. |
| About Graphite… | <p>Opens the **About Graphite** dialog for displaying release and license information. You can check it for the release date of the current editor version.</p> |
| User Manual | <p>Opens this [user manual](./learn).</p> |
| Report a Bug | <p>Opens a page to file a [new GitHub issue](https://github.com/GraphiteEditor/Graphite/issues/new).</p> |
| Visit on GitHub | <p>Opens the [Graphite GitHub repository](https://github.com/GraphiteEditor/Graphite).</p> |
| *Debug section* | <p>Developer-only actions. Users should ignore these.</p> |
+2 -2
View File
@@ -5,14 +5,14 @@ page_template = "book.html"
[extra]
order = 1
js = ["video-embed.js"]
js = ["youtube-embed.js"]
+++
<!-- Before taking the time to read the coming chapters, let's build some context by jumping straight into a small project that you can follow along with. That way you will have a mental framework for the topics explained in the rest of this manual. -->
Begin learning Graphite by watching the introductory tutorial videos below.
One is available now, and more will be released on a regular basis throughout early 2024.
One is available now, and more will be released on a regular basis throughout early 2025.
## Tutorial series
@@ -5,39 +5,31 @@ title = "Features and limitations"
order = 1
+++
Please bear in mind that Graphite is alpha software, meaning it is actively changing and improving. Remember to save your work frequently because crashes are not unheard of.
Bear in mind that Graphite is alpha software, meaning it is actively changing and improving.
## Current capabilities
A lot is planned on the future [roadmap](/features#roadmap), but here's an overview of the concepts behind the selection of workflows you can currently use in Graphite.
### Vector illustration and graphic design
Vector editing is the core competency of the Graphite editor at this stage in its development. That means you can create graphic designs and shape-based vector artwork with the tools on offer, like this cactus:
<p><img src="https://static.graphite.rs/content/index/just-a-potted-cactus-thumbnail.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Example vector artwork of a potted cactus" /></p>
Primitive geometry like rectangles and ellipses can be drawn and, as desired, modified into more complex shapes using the Path tool. Fully organic shapes may also be created from scratch with the Pen tool. They can then be given colors and gradients to add visual style.
### Raster compositing
Raster image editing is a growing capability that will develop over time into the central focus of Graphite. Raster imagery is composed of pixels which are grids of color that can represent anything visual, like paintings and photographs. The current feature set lets you import images, manipulate them using the node-based compositor, and apply nondestructive effects like color adjustment filters.
A prototype Brush tool exists letting you draw simple doodles and sketches. However it is very limited in its capabilities and there are multiple bugs and performance issues with the feature. It can be used in a limited capacity, but don't expect to paint anything too impressive using raster brushes quite yet.
The raster-based Imaginate feature enables you to synthesize artwork using generative AI based on text descriptions. With it, you can also nondestructively modify your vector art and imported images. You can inpaint (or outpaint) the content in a specific masked part of an image or use it to touch up quick-and-dirty compositions. This feature is temporarily out of comission but will be resurrected, and further improved upon, in the near future.
| | |
|-|-|
| <p>Vector editing is the core competency of the Graphite editor at this stage in its development. That means you can create shape-based vector artwork and designs with the available tools.</p><p>Primitive geometry like rectangles and ellipses can be drawn and, as desired, modified into more complex shapes using the Path tool. Fully organic shapes may also be created from scratch with the Pen tool. They can then be given colors and gradients to add visual style. This cactus is an example of the style of artwork you can create with vector graphics.</p> | <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/cactus-vector-art.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Example vector artwork of a potted cactus" style="max-width: unset" /> |
### Procedural design
A procedural content generation workflow lets you describe *how* a creative decision becomes a visual outcome rather than doing it all yourself. For example, copying a shape 25 times around the inside of a circle would be a lot of work if done by hand but it's easy for the computer to do it. And if you decide 10 instances may look better than 25, or you want to change the copied shape, or you opt for a different circle radius, it's easy to just update a numerical parameter. That saves you from laboriously placing every shape all over again. You're able to build a *procedure* that the computer carries out on your behalf.
A procedural content generation workflow lets you describe *how* a creative decision becomes a visual outcome rather than doing it all yourself. For example, copying a shape 25 times around the inside of a circle would be tedious work if done by hand but it's easy for the computer to do it. And if you decide 10 instances may look better than 25, or you want to change the copied shape, or you opt for a different radial separation, it's easy to just update a numerical parameter. That saves you from laboriously placing every shape all over again. You're able to build a *procedure* that the computer carries out on your behalf.
The aforementioned example takes the form of the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" style="vertical-align: middle" alt="Circular Repeat" /> node which is represented as this box-shaped entity with colored *connectors* on either end. *Nodes* encode certain operations (or functions) in the procedure that generates your artwork. Once you've drawn some content, you can see the nodes which generate it by opening the *node graph* with the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/node-graph-button.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" style="vertical-align: middle" alt="'Node Graph' button" /> button located to the top right of the viewport. This example may have a node setup which looks like this:
The aforementioned example takes the form of the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node__3.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" style="vertical-align: middle" alt="Circular Repeat" /> node which is represented as this box-shaped entity with colored *connectors* on either end. *Nodes* encode certain operations (or functions) in the procedure that generates your artwork. Once you've drawn some content, you can see the nodes which generate it by opening the *node graph* with the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/node-graph-button.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" style="vertical-align: middle" alt="'Node Graph' button" /> button located to the top right of the viewport. This example may have a node setup which looks like this:
<p><img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/shape-fill-circular-repeat-layer.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Shape" /></p>
<p><img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/path-fill-circular-repeat-layer.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" alt="Path node, Fill node, Circular Repeat node in a sequence feeding into the Untitled Layer" /></p>
Starting from the left, the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/shape-node.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" style="vertical-align: middle" alt="Shape" /> node generates some geometry (in this case, drawn using the *Pen* tool). Next, the shape data feeds through the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/fill-node.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" style="vertical-align: middle" alt="Fill" /> node to apply a blue color. At this point, the shape data looks like so:
Starting from the left, the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/path-node.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" style="vertical-align: middle" alt="Path" /> node generates some geometry (in this case, drawn using the *Pen* tool). Next, the vector path data feeds through the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/fill-node__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" style="vertical-align: middle" alt="Fill" /> node to apply a blue color. At this point, the path data looks like so:
<p><img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/blue-arch-shape.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="" /></p>
<p><img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/blue-arch-shape.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" /></p>
Next, that is fed into the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" style="vertical-align: middle" alt="Circular Repeat" /> node which has several parameters you can modify and get different output data based on your choices, like in these examples:
Next, that is fed into the <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node__3.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" style="vertical-align: middle" alt="Circular Repeat" /> node which has several parameters you can modify and get different output data based on your choices, like in these examples:
<style class="table-1-style">
.table-1-style + table {
@@ -52,12 +44,20 @@ Next, that is fed into the <img src="https://static.graphite.rs/content/learn/in
| | |
|-|-|
| <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-parameters-1.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="" /> | <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-output-1.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="" /> |
| <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-parameters-2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="" /> | <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-output-2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="" /> |
| <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-parameters-3.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="" /> | <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-output-3.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="" /> |
| <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-parameters-4.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="" /> | <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-output-4.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width /= 2" alt="" /> |
| <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-parameters-1__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" /> | <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-output-1.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" /> |
| <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-parameters-2__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" /> | <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-output-2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" /> |
| <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-parameters-3__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" /> | <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-output-3.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" /> |
| <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-parameters-4__2.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" /> | <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/circular-repeat-node-output-4.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" /> |
The node's properties offer controls over settings like *Angle Offset* (what angle to start at), *Radius* (distance from the center), and *Count* (how many copies to distribute). These parameters can also be exposed into the graph so they are driven by the calculated numerical outputs of other nodes instead of values you pick by hand.
The node's properties offer controls over settings like *Angle Offset* (what angle to start at), *Radius* (distance from the center), and *Instances* (how many copies to distribute). These parameters can also be exposed into the graph so they are driven by the calculated numerical outputs of other nodes instead of values you pick by hand.
### Raster compositing
Raster image editing is a growing capability that will develop over time into the central focus of Graphite. Raster imagery is composed of pixels which are grids of color that can represent anything visual, like paintings and photographs. The current feature set lets you import images, manipulate them using the node-based compositor, and apply nondestructive global effects like color adjustment filters.
A prototype <img src="https://static.graphite.rs/content/learn/introduction/features-and-limitations/brush-tool-icon.avif" onerror="this.onerror = null; this.src = this.src.replace('.avif', '.png')" onload="this.width = this.naturalWidth / 2" alt="" style="vertical-align: bottom" /> Brush tool exists letting you draw simple doodles and sketches. However it is very limited in its capabilities and there are multiple bugs and performance issues with the feature. It can be used in a basic capacity, but don't expect to paint anything too impressive using raster brushes quite yet. The tool will be fully rewritten in the future.
<!-- The raster-based Imaginate feature enables you to synthesize artwork using generative AI based on text descriptions. With it, you can also nondestructively modify your vector art and imported images. You can inpaint (or outpaint) the content in a specific masked part of an image or use it to touch up quick-and-dirty compositions. This feature is temporarily out of comission but will be resurrected, and further improved upon, in the near future. -->
## Status and limitations
@@ -67,16 +67,22 @@ Please make yourself aware of these factors to better understand and work around
Saved documents will eventually fail to render in future versions of the Graphite editor because of code changes. Since node implementations and other systems are in flux, file format stability isn't possible yet during this alpha stage of development. If a file opens but there's a rendering error, you may need to open the node graph and replace outdated nodes by creating new ones near the site of an error. Later in the development roadmap, a redesigned file format with a `.gdd` (Graphite Design Document) extension will replace `.graphite` files and it will be built with seamless backwards-compatability in mind.
### Limited raster capabilities
### Limited raster tooling
While you can import bitmap images, apply image effects in the node graph, and draw brush strokes, there is not much tooling yet to make the overall raster workflow that useful. Marquee selection is an upcoming feature in the first half of 2025 which will significantly improve the utility of raster editing in Graphite. Hardware accelerated rendering, to offload work from the CPU to GPU, is also planned for early 2025 which will drastically improve the performance of working with millions of pixels.
While you can import bitmap images, apply image effects in the node graph, and draw brush strokes, there is not much tooling yet to make the overall raster workflow that useful. Marquee selection is an upcoming feature slated for later in 2025 which will significantly improve the utility of raster editing in Graphite.
Hardware accelerated rendering, to offload pixel processing from the CPU to GPU, is also planned for 2025. It will drastically improve the performance of working with millions of pixels.
### Performance bottlenecks
Graphite has several temporary performance bottlenecks that currently yield poor performance when working with raster content, complex vector artwork, and large procedural node graphs. Each of these limitations will be resolved by finishing the implementations of the incomplete systems that impose slowdowns in their current forms. For example, caching in the node graph isn't operational and GPU-accelerated rendering isn't enabled yet. This will be a central focus throughout 2024 and 2025.
Graphite has several temporary performance bottlenecks that currently yield poor responsiveness when working with raster content, complex vector artwork, and large procedural node graphs. This is especially impactful for raster content. It also currently applies to large volumes of vector data, such as paragraphs worth of text (which is represented as vector paths).
Each of these limitations will be resolved by finishing the implementations of incomplete systems that impose slowdowns in their current forms. For example, certain opportunities for node graph caching are not operational and GPU-accelerated rendering isn't enabled yet.
Performance will be a high-priority focus throughout 2025.
### Best-effort Safari support
Old versions of Safari lack the minimum web standards features Graphite requires to run. The latest version of the browser still won't run Graphite as well as Chrome and you may encounter extra bugs because we have limited resources to regularly test for Safari issues.
Old versions of Safari lack support for the web standards Graphite is built upon. The latest version of the browser still won't run Graphite as well as Chrome and you may encounter extra bugs because we have limited resources to regularly test for Safari issues. Feel free to file issues only if you're using the latest Safari version and find a bug that isn't present in Chrome.
The latest Chrome or Chromium-based browser is recommended for the best-supported experience, although Firefox works with only some minor feature degradations.
The latest Chrome, Edge, or Opera browser is recommended for the best-supported experience. Firefox works reasonably well, with only some minor loss of quality-of-life features. Brave is likely to encounter issues due to its aggressive degradation of web standards.