Graphite is a digital content creation software package for 2D graphics

Overview

Graphite Logo

Powerful 2D vector and raster editing. Procedural and nondestructive.

Graphite is a digital content creation software package for 2D graphics, merging traditional tool-based interactive editing workflows with a powerful node-based approach to procedural, non-destructive editing and compositing. The application strives to be the most user-friendly and versatile tool for vector and raster illustration, graphic design, photo editing, procedural texturing, data-driven visualization, and technical art.

While the project is still in early development, implementation progress has been moving forward at a swift pace. The Graphite Alpha release is launching soon and focuses on vector art for SVG creation. The next major milestone will introduce a nondestructive backend for vector graphics with a powerful node graph system. Later releases will provide better vector rendering capabilities and then resolution-agnostic raster editing and compositing.

Play around with Graphite right now in your browser at editor.graphite.design. Windows, Mac, and Linux will additionally be supported with a native (not web-based) desktop client later in the development roadmap.

Contributing

We need Rust and web developers! See instructions here for getting started.

We are also in search of a new logo and brand style system. If you are an experienced designer, please get in touch for more details.

Discord

If the Graphite project strikes your fancy, join our Discord community to chat with the community and development team. You're invited to stop by just to lurk, ask questions, offer suggestions, or get involved in the project. We are seeking collaborators to help design and develop the software and this is where we communicate. Paste https://di----scord.gg/uMjBz----5N68W into your browser and delete the dashes. (To prevent spam bots, please don't share the link on any website without the dashes.)

Vision

Graphite is an open source, cross-platform digital content creation desktop and web application for 2D graphics editing, photo processing, vector art, digital painting, illustration, data visualization, compositing, and more. Inspired by the open source success of Blender in the 3D domain, it aims to bring 2D content creation to new heights with efficient workflows influenced by Photoshop/Gimp and Illustrator/Inkscape and backed by a powerful node-based, nondestructive approach proven by Houdini and Substance.

The user experience of Graphite is of central importance, offering a meticulously-designed UI catering towards an intuitive and efficient artistic process. Users may draw and edit in the traditional interactive (WYSIWYG) viewport with the Layer Tree panel or jump in or out of the node graph at any time to tweak previous work and construct powerful procedural image generators that seamlessly sync with the interactive viewport. A core principle of the application is its 100% nondestructive workflow that is resolution-agnostic, meaning that raster-style image editing can be infinitely zoomed and scaled to arbitrary resolutions at a later time because editing is done by recording brush strokes, vector shapes, and other manipulations parametrically.

One might use the painting tools on a small laptop display, zoom into specific areas to add detail to finish the artwork, then perhaps try changing the simulated brush style from a blunt pencil to a soft acrylic paintbrush after-the-fact, and finally export the complete drawing at ultra high resolution for printing on a large poster.

On the surface, Graphite is an artistic medium for drawing anything imaginable— under the hood, the node graph in Graphite powers procedural graphics and parametric rendering to produce unique artwork and automated data-driven visualizations. Graphite brings together artistic workflows and empowers your creativity in a free, open source package that feels familiar but lets you delve further.

This UI mockup illustrates a future concept for the raster-based workflow in a photo editing example.

Demo UI mockup

Roadmap

The Graphite team is focusing initial feature development on a simple vector graphics editor for the Alpha release.

Following this MVP release, the layer system will be extended into a fleshed-out node graph system, called Graphene, to offer innovative nondestructive vector editing capabilities in the next milestone release.

The following major releases will add a purpose-built render engine to support node-based raster editing, thereby providing a seamless combined raster and vector workflow.

The interim web-based frontend will be replaced by an identical native desktop client for Windows, Mac, and Linux plus the web. This new frontend will mark the release of Graphite 1.0 when complete.

Development is broken into monthly sprints culminating in a presentation at the Rust Gamedev Meetup and a post in the Rust Gamedev Newsletter. Check out the Task Board to see the current features being built and prioritized.

Technology stack

Rust is the language of choice for many compelling reasons. It is low-level and highly efficient which is important because the nondestructive, resolution-agnostic editing approach will already be challenging to render quickly for interactive, real-time editing. Furthermore, Rust makes multithreading easy to implement and its safety guarantees will eliminate the inclusion of many bugs and crashes in the software. It is also simple to compile Rust code natively to Windows, Mac, Linux, and web browsers via WebAssembly, with the possibility of deploying Graphite to mobile devices down the road as well.

Vue.js is the web frontend framework initially used for building Graphite's user interface. This means, for the moment, Graphite will only run in a browser using Rust code compiled to WebAssembly (via wasm-bindgen). This web-based GUI is intended to be rewritten in a native Rust GUI framework once that ecosystem matures or the project has engineering resources to write a tailor-made GUI framework for Graphite's needs. Development initially began by writing a custom GUI system throughout 2020, but slow progress led to the decision of shelving it in lieu of a temporary web-based GUI.

WebGPU (via the WGPU Rust library) will be used as the graphics API for GPU-accelerated rendering because it is modern, portable, and safe. It makes deployment on the web and native platforms easy while ensuring consistent cross-platform behavior. Shaders will be written in Rust GPU to keep the codebase in a consistent language. Early Graphite releases are relying on web browsers' built-in SVG rendering capabilities before work begins building Graphite's sophisticated render engine.

Comments
  • Copy and paste layers MVP

    Copy and paste layers MVP

    corresponding issue: #218

    @TrueDoctor I'm not sure if this is what you imagined here so I created this PR in a bit of an unfinished state to ask for some feedback. Since the copy buffer is in the editor I think I need to send Layers wrapped as operations and since operations are serializable I needed to make Layers serializable too. And in turn I needed to enable to serde feature of kurbo. I’m not sure if this is desired.

    Also I think there is a problem with the keybindings: I had to add the control-V shortcut to the beginning of the mapping! because otherwise the SelectTool(ToolType::Select) message bound to V did take precendence.

    Furthermore the way I select the active layers in CopySelectedLayers (which I think is the same way we do it in DuplicateSelectedLayers and DeleteSelectedLayers) is flawed as it appears to also take into account some sort of temporary layers. This is why I added the warn log in process_action for CopySelectedLayers. To reproduce: create a rect and then press control-C which correctly copies the rect and logs a debug message to the console. Now just click the canvas with the rect tool which will not create a new layer and then press control-C. You’ll now see the warning message in the console indicating that layer_data contained a selected layer which does not actually exist in the real document layers.


    This change is Reviewable

    opened by tillarnold 34
  • (G)rab, (R)otate, and (S)cale layers with hotkeys

    (G)rab, (R)otate, and (S)cale layers with hotkeys

    Closes #317

    • [x] Add new handler
    • [x] Add (neat) bindings to input mapper
    • [x] Handle translation mouse movement
    • [x] Handle rotation mouse movement
    • [x] Handle scale mouse movement
    • [x] Handle constrain to axis
    • [x] Handle number typing
    • [x] Handle shift to slow mouse movements
    • [x] Handle ctrl to snap rotation and scale
    • [x] Fix 0 scale breaking things
    • [x] Fix deselecting layers sometimes causing panic (trouble reproducing)

    This change is Reviewable

    opened by 0HyperCube 21
  • Hide popups triggered by hovering after moving the cursor away

    Hide popups triggered by hovering after moving the cursor away

    They might block the thing you actually wanted to interact with.

    https://user-images.githubusercontent.com/17426603/164512624-f5af3b76-9995-4767-a799-0dbd7897e221.mp4

    opened by bjorn3 15
  • Layer snapping

    Layer snapping

    Closes #200

    • [ ] Display lines (probably wait for overlay system?)
    • [x] Don't search for every layer each mouse move
    • [x] Snap new shapes while they're being created
    • [x] Hook up the snap (🧲) icon to entirely enable/disable snapping behavior (on by default)

    This change is Reviewable

    hacktoberfest-accepted 
    opened by 0HyperCube 14
  • Rework wasm initialization and reduce global state

    Rework wasm initialization and reduce global state

    As discussed, I will eventually need two editor instances side-by-side, so we cannot have global state.

    This PR is the beginning of that work. Some global state has been reduced or eliminated, but there's still plenty of work to be done.

    I will add further commits as I keep working on it, chipping away at the global state one piece at a time. You can merge anytime you like.

    My current plan is as follows:

    • Step 1: remove global state from the vue app. utilities/{dialog/documents,fullscreen}.ts still contain a lot of them, and I'll need to wrap my head around the response handler logic. On that topic, I'd like to move the stateful code from utilities/ to state/ or somewhere, if that's ok with you?
    • Step 2: remove global state from the wasm.

    This change is Reviewable

    opened by cauthmann 14
  • Show working color modifications in the frontend

    Show working color modifications in the frontend

    Currently ToolMessage::SwapColors and ToolMessage::ResetColors don't inform the frontend of their changes.

    Todo:

    • Add a FrontendMessage::UpdateWorkingColors(primary, secondary)
    • emit that message in the tool_message_handler.rs
    • add the message type to client/web/src/response-handlers.ts
    • register a listener for the message in Document.vue
    • modify the working colors accordingly

    Test cases:

    • use the keyboard shortcut X to check the colors have been swapped
    • click the swap and reset buttons below your color picker swatches

    Comeplexity: 1 Involves: Editor (Rust), Frontend (Javascript)

    Good First Issue Web Rust 
    opened by TrueDoctor 14
  • Disallow zero-area artboards

    Disallow zero-area artboards

    This PR ensures that adding and resizing artboards will not result in zero width or zero height.

    Regarding adding borders to all artboards when the artboard tool is selected, I believe a separate PR is more suitable. When this PR is merged, a new issue should be created.

    This is my first time writing Rust, any feedback is welcome!

    Closes #704.

    opened by Kit-p 10
  • Properties panel doesn't go blank after clicking in Layer Tree panel to deselect, requires a second click to blank it

    Properties panel doesn't go blank after clicking in Layer Tree panel to deselect, requires a second click to blank it

    The first click in the empty area of the Layer Tree deselects the layers but the Properties panel doesn't go blank. It takes a second click in the same place to make it go blank.

    https://user-images.githubusercontent.com/17426603/164511902-de672dbd-bcdf-4a4f-b0cb-3353569c54b6.mp4

    Bug Rust P-Low 
    opened by bjorn3 10
  • Font selection for text layers

    Font selection for text layers

    Closes #504 Closes #529 Closes #508

    • [x] Fetch fonts and put them into dropdown in the properties panel
    • [x] TextArea to add to text properties
    • [x] Download selected font and render.
    opened by 0HyperCube 10
  • Populate layer entry cache

    Populate layer entry cache

    Closes #430

    The layer entry cache in the frontend was not populated when the document was opened because UpdateLayer was never called. This MR just creates the layerdata for all of the layers and then calls UpdateLayer on them.

    opened by 0HyperCube 10
  • Change responses to use classes instead of interfaces

    Change responses to use classes instead of interfaces

    For some reason, Github closed this issue while rebasing to get rid of the commit from my other PR. This is not related to an active issue, but I saw an opportunity to try and improve the codebase. This PR is not done and needs to be cleaned up a little. Is this change something that is worth pursuing further? The advantage of this pattern is that it makes the subscribing to responses more explicit as well as cuts down on repeated code.

    Closes #399 Workaround for #396


    This change is Reviewable

    opened by mfish33 10
  • Vital UX improvements for the Artboard tool

    Vital UX improvements for the Artboard tool

    • [x] Allow naming artboards. The name should likely be shown above the artboard. (#538)
    • [ ] Always draw border overlays around all artboards
    • [ ] Default to one artboard always being selected (for discoverability, to avoid confusion about how you resize an artboard without any obvious handles shown). The user shouldn't be able to deselect all artboards to have 0 selected. For now, the artboard with index 0 can be the default, and the tool saves which artboard was most recently selected (even if the tool has been switched away from, and then back to), but default to index 0 if that tool information isn't valid or available anymore.
    Feature Good First Issue Available Rust P-High Paper Cut 
    opened by Keavon 0
  • Make dragging Pivot require Alt, and show a tooltip on hover

    Make dragging Pivot require Alt, and show a tooltip on hover

    Right now, you can drag the little blut pivot dot around. But a lot of users complain that they expect this is actually the drag target for the entire layer, and they get confused why the dot is moving without the layer. So we should make the pivot draggable only when holding Alt. Therefore anywhere on the interior of the layer, including the pivot when not holding the modifier, just drags the layer around.

    But discoverability is crucial, so we need to display a hint for the user that this is the pivot and it must be dragged while holding Alt. I mocked this up, shown at 100% and 400%:

    image

    image

    Specs:

    • Font size 12px weight 600/semibold
    • Container 16px tall, white background (14px tall), 1px inset outline, 4px rounded corners, 4px above/below/left/right of the text to the top and bottom of the container (3px to the blue outline)
    • Tooltip box positioned relative to the pivot dot by aligning the container's top edge with the dot's bottom edge, and the container's left edge 8px from the dot's right edge
    • It should appear on hover, but disappear when the user is dragging (the layer or the pivot, i.e. with or without Alt)

    One option is to display this with the overlays system. Text would be new though. The other option is that we just put in the time to implement custom tooltips for our entire UI and add support for a zero-delay option and for positioning tooltips over the viewport based on the positions of artwork. I suggest taking the easiest route for now, since this is just necessary to fix a UX problem, ideally before the public announcement.

    Feature Good First Issue Available Rust P-High Paper Cut 
    opened by Keavon 0
  • Use builder pattern for widgets

    Use builder pattern for widgets

    Builder pattern for widgets e.g.

    DropdownEntryData::new()
    	.label(mode.to_string())
    	.on_update(update_value(move |_| TaggedValue::ImaginateMaskStartingFill(mode), node_id, mask_fill_index)),
    
    opened by 0HyperCube 2
  • Re-add text to shape conversion

    Re-add text to shape conversion

    This was disabled when we switched away from the Kurbo vector data format. We might want to make this an explicit user action with a button in the Text area of the Properties panel, since we actually have a Properties panel now. Previously it was an implicit (and potentially accidentally triggered) action by dragging points with the Path tool. Perhaps it can be a button at the bottom called "Convert to Shape Layer". (Eventually this will be a non-destructive node-based workflow, but destructive will do for now.)

    Feature Available Rust P-High 
    opened by Keavon 0
  • Alt+Arrows should scale the bottom/right edges of layers

    Alt+Arrows should scale the bottom/right edges of layers

    Similar to arrow keys (and the Shift modifier) to nudge the position of selected layer(s), this feature should "nudge" (by resizing) the right and bottom sides of the selected layer(s). Left and right arrows resize the layer(s) by 1px on the right edge. Up and down arrows resize the layer(s) by 1px on the bottom edge. The Shift makes it 10px. This should happen in layer space, not viewport space, so regardless of viewport zoom the user should expect to see the dimensions in the Properties panel change by 1px or 10px in W or H. If the layer is rotated, it should scale along the axis of the layer, so the X and Y would change as expected but the W and H would not necessarily change by 1px/10px. Assuming it doesn't conflict with any other keys, Ctrl would be nice as a modifier that changes it to the Left/Top instead of Bottom/Right.

    Feature Good First Issue Available Rust P-High 
    opened by Keavon 2
Releases(latest-stable)
  • latest-stable(Feb 4, 2022)

    This is a moving release that is frequently updated to newer commits in the master branch once they are deemed stable enough for deployment on https://editor.graphite.rs for general use. It is manually updated and should generally stay mostly up-to-date with the latest features, but often lags slightly behind commits on master which are automatically deployed at https://dev.graphite.rs.

    Source code(tar.gz)
    Source code(zip)
Owner
Graphite
Open source 2D node-based raster/vector graphics editor
Graphite
A vector graphics renderer using OpenGL with a Rust & C API.

bufro A vector graphics renderer using OpenGL with a Rust & C API. A Rust example can be found in examples/quickstart.rs (using glutin). A C example c

Aspect 9 Dec 15, 2022
Kiss3d - Keep it simple, stupid 3d graphics engine for Rust.

Kiss3d - Keep it simple, stupid 3d graphics engine for Rust.

Sébastien Crozet 1.2k Dec 26, 2022
A little cross-platform graphics engine written in rust.

Bismuth This is a version of my C++ graphics engine named Bismuth re-written with Rust. My goal is to learn more about the Rust language and make my g

Admiral サイタマ 1 Nov 1, 2021
Rust bindings to bgfx, a cross-platform, graphics API agnostic

Rust bindings to bgfx, a cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.

Daniel Collin 65 Dec 24, 2022
wgpugd: A WebGPU Graphics Device for R

wgpugd: A WebGPU Graphics Device for R Overview What is WebGPU? WebGPU is an API that exposes the capabilities of GPU hardware. What is wgpu? As the n

Hiroaki Yutani 42 Dec 11, 2022
Generic framebuffer implementation in Rust for use with embedded-graphics library

Fraramebuffer implementation for Rust's Embedded-graphics Framebuffer approach helps to deal with display flickering when you update multiple parts of

Bernard Kobos 9 Nov 29, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
Motion graphics creation tool in Bevy. (Highly inspired by Motion Canvas and Manim)

Bevy MotionGfx Bevy Motiongfx is a motion graphics creation tool in Bevy. It is highly inspired by Motion Canvas & Manim. Goal The goal of this tool i

Nixon 3 Nov 6, 2023
Standard Graphics is a command-line tool for printing 2D graphics from any language to any screen.

2D graphics in any programming language with just print statements!

Caleb Winston 123 Nov 20, 2022
A graphics engine that I made in rust for my high school graphics course.

A graphics engine that I made in rust for my high school graphics course.

Mohammad Khan 1 May 29, 2022
Rust vs C: Software Graphics Challenge

Rust vs C: Reto de Gráficos por Software Aprende Rust y C programando gráficos por software con efectos de demoscene clásica de los años 80. Episodios

null 9 Aug 26, 2023
Prisma2D - Fast, API agnostic, software only 2D graphics crate in pure Rust.

Prisma2D: Ultra-fast CPU 2D graphics Prisma2D is a blazingly fast, efficient yet minimal crate for basic 2D graphics on the CPU. for Rust. With Prisma

Aggelos Tselios 4 Nov 30, 2023
A Rust port of alien, a tool that converts software packages between Linux package managers.

alien A Rust port of alien, a tool that converts software packages to work from one package manager to the next. Currently, the tool supports converti

Leah 3 Jan 19, 2023
An open-source and fully-featured Digital Audio Workstation, made by musicians, for musicians

Meadowlark An open-source and fully-featured Digital Audio Workstation, made by musicians, for musicians. *Current design mockup, not a functioning pr

Meadowlark 1k Jan 7, 2023
The open source musician's digital music stand

DiNoScore* A digital music stand written with GTK in Rust using WoAB. Includes an editor to import your sheet. Touch-friendly thanks to Libhandy. Ever

null 13 Dec 5, 2022
Multi Party Key Management System (KMS) for Secp256k1 Elliptic curve based digital signatures.

Key Management System (KMS) for curve Secp256k1 Multi Party Key Management System (KMS) for Secp256k1 Elliptic curve based digital signatures. Introdu

[ZenGo X] 61 Dec 28, 2022
Rust implementation of {t,n}-threshold ECDSA (elliptic curve digital signature algorithm).

Multi-party ECDSA This project is a Rust implementation of {t,n}-threshold ECDSA (elliptic curve digital signature algorithm). Threshold ECDSA include

[ZenGo X] 706 Jan 5, 2023
A digital audio workstation for all platforms that is libre, gratis, and awesome

?? Dawsome [WIP] A DAW build on React + Rust + WASM Available Scripts In the project directory, you can run: pnpm dev Tauri will open a new window wit

Noah Bennett 9 Dec 14, 2022
TI LDC1312/LDC1314/LDC1612/LDC1614 inductance-to-digital converter driver for Rust embedded-hal

ldc1x1x Rust embedded-hal 1.x driver for Texas Instruments (TI) I²C inductance-to-digital converters (LDC): LDC1312/LDC1314, LDC1612/LDC1614. Includes

null 2 Oct 2, 2022
A modular command line digital signal processor built in rust

Ever wanted to pipe raw audio samples around in the terminal to impress your friends at a party? Well then, you've come to the right place.

Sam Andreae 13 Dec 15, 2022