An Overview of Open Design in 2022: Part 1
Open Design team
January 17, 2023
In this blog post, we'll explore the evolution of the Octopus design format and detail the changes that have occurred.
I asked my colleagues to contribute ideas for this blog post, and I received so much great content that I decided to split it into multiple blog posts. I'll be gradually publishing these over time. To start, let's provide a brief overview.
What is Open Design 2.0?
Open Design 2.0 is a headless design editor, meaning it is a TypeScript framework that provides a foundation for developers to build upon when working with designs. The framework helps developers tackle complex issues such as design rendering, design format, and importing existing design formats.
Back in September 2022, we discussed the ongoing work on refactoring almost all parts of the framework. This process brings both benefits and increased complexity and instability. In this article, we will explain the changes being made to each part of the framework and their current status.
The current state of Open Design
It is important to note that Open Design is still under development and is not ready for production use at this time. Despite this, we have made significant progress and the initial benchmark tests have been promising. Let's take a look at the changes that have been made.
The design format, also known as Octopus
Octopus is the universal design format used in our products, such as Avocode, Inspect, Design Converters and Ceros Studio. It has evolved over the years and has undergone a major change with the introduction of a new, more flexible, and generalized design data model.
This is the third version of Octopus and it currently supports integration with the following design tools: Figma, Adobe XD, Adobe Illustrator, and Adobe Photoshop. Where is Sketch, you may ask? The Sketch format is quite complicated and we need more time to get it right.
Our main focus for the third version was on improving the robustness, universality, and clarity of the data model. The key changes are as follows:
- Layer content is now positioned entirely in a relative coordinate system, allowing for the reuse of design elements without the need to update layer content.
- Layer transformations are relative to the parent layer and are clearly described using a transformation matrix. This removes any confusion regarding the application of transformations such as rotation and flipping (which are still present as metadata).
- There is a restricted set of layer types, which includes shape, text, group, component reference, and mask group. Images are represented as patterns on shapes.
- The representation of shapes has been redesigned in the following ways:
- Shapes can be composed of an arbitrary combination of individual paths combined using boolean path operations (union, intersect, exclude, subtract).
- The core path geometry is encoded in SVG path format.
- Shapes may optionally include stroke geometry, where the border is expressed as a shape in itself, addressing Figma's shape representation.
- Shape fills and strokes are stored directly within the shape object, rather than being stored among generic layer effects, making the data more closely linked and clearer.
- The representation of layer effects has been updated as follows:
- Layer-wide effects (such as blurs, shadows, and raster fills) are separated from entity-specific effects (such as vector strokes on shapes and fills on specific ranges of text).
- Effect positioning parameters are consistent, eliminating any ambiguity in the description of, for example, pattern or gradient fills, which had multiple ways of being expressed in Octopus 2
- The handling of masks has been updated as follows:
- All masks are represented in a "mask group" layer, with the masking layers explicitly stored in the "mask" object and the masked layers stored in the "layers" array as in group layers. This makes the format more user-friendly as there is no need to parse the layer tree to understand which layers are being masked.
- There is no explicit handling of specific mask types like Photoshop bitmap or vector masks, as they are converted to the new representation.
- The representation of text has undergone only minor updates, specifically, the meaning of text transformation is now explicitly stated. In addition, the naming of Octopus entities has been standardized, with a unified format for keys and enum value labels throughout the entire specification.
- The concept of "meta" data has been introduced, which refers to all platform-specific and/or auxiliary data that is not necessary for a complete design representation. This data is stored in a dedicated "meta" object. For example, the original values of layer transformations (like rotation angle) are not essential as the transformation is already represented by a single matrix, but they may be useful and are therefore stored as metadata. This also allows for the storage of specific data from the original design tools.
You can look at an example of how Octopus 3 compares to Octopus 3 here.
During the processing of design data, we also attempt to normalize it. For example, Figma's vector representation can be unnecessarily complex and contain unnecessary points. When converting it to Octopus 3, we optimize the output by removing these points:
In the example above, the original shape takes up approximately 122 kB, while the normalized version only takes 16 kB (a savings of ~87%). This makes Octopus files more compact and easier to work with.
In Octopus 2, we primarily focused on representing artboards, and saving design-wide meta-information was not a priority. Octopus 3 is now a design-wide format that includes all essential details and meta-information about the entire design. It connects components, images, pages, and artboards.
Flexibility of Octopus parsers
Another significant change is the design of the Octopus parsers, which are now more abstracted from specific inputs and can be extended by developers. This means, for example, that the parsers can consume data from both the Figma Plugin API and the Figma REST API. The exporting of artifacts, which are used to create the final Octopus file, is also abstracted and left to the developer to handle. The resulting data can be handled in any desired way, such as being saved as files or uploaded to the cloud.
Subscribe to get the latest
Open Design news by email
Many of the products that use Octopus are web services, so we also made sure to address this in the design. Non-compatible dependencies were rewritten to be compatible with browsers. For example, Octopus 2 used the psd-tools library to parse Adobe Photoshop files, but it was written in Python and not compatible with browsers. In Octopus 3, we use TypeScript and Rust, which are modern, robust, and browser-compatible technologies.
Although the current design processing using Octopus 3 is almost twice as fast as with Octopus 2, there are still missing features that we hope to add in the near future. Our focus will be on proper support for design components, fixing existing bugs, and making it ready for production use.
That's all for this blogpost. In the next article we will discuss the Open Design engine, which we have also completely refactored and changed the architecture.