PaintCode Power User: Frames
This post is a part of series PaintCode Power User.
Frames are one of the most advanced features of PaintCode. When we first introduced them, they were a unique feature not found in any other drawing app. They are an entirely new approach to an old problem — making drawings resizable.
Modern apps and websites often require user interface elements with variable size. Buttons may need to be wider when localized in German. Toolbars must typically fill the entire horizontal space, which varies wildly between devices. Even simple sliders may need to be resizable.
These are exactly the cases Frames are supposed to solve. After you add a Frame into canvas, all the Shapes inside the Frame will gain the ability to move and resize when the Frame changes size.
In other words, Frame is an invisible rectangle placed into canvas. Shapes that are inside of the Frame have enabled editing of Springs.
Working with Frames
- To create a Frame, use toolbar button or press F and place the Frame into canvas.
- When placing a new Frame, create it around the Shapes you want to change when resizing. Most typically around all Shapes in canvas.
- After the Frame is placed, changing its size may result in unwanted movements and resizing of contained Shapes. To suppress this, hold ⌘ while changing position or size of the Frame. Either when dragging in canvas or editing text fields in Inspector.
- You can have multiple Frames in canvas, they are all listed on top of the Shapes List.
- Frames can be moved into Groups, where they affect only Shapes inside the group.
- Typically, one Frame in canvas is main. The main Frame defines canvas dimensions when the canvas is used as a Symbol.
- By default, Frame affects all Shapes that are fully inside and Shapes that intersect the Frame. To make Frame affect only those fully inside, use a dedicated checkbox in Inspector.
- Frames can be nested. This enables more advanced resizing rules for contained Shapes.
- Position and size of Frame can be connected to Variables. However, Frames cannot be accessed from Expressions.
Springs & Struts
You might notice this Inspector element before, near the text fields for position and size of every Shape. If you only saw it disabled before, try wrapping your Shape in a Frame and it will become active.
There are 6 parts that are clickable and they toggle between Spring and Strut appearance: top margin, left margin, right margin, bottom margin, width and height. The inner square represents the selected Shape, the outer square represents enclosing Frame. These Springs and Struts describe resizing behavior if selected Shape in case its enclosing Frame is resized.
In case you choose any of the margins as fixed (using Strut), the distance between respective edges of Frame and Shape will be preserved. If you use flexible margin (using Spring), this distance may grow or shrink during resizing.
Similar behavior is true for width and height. If you set any dimension flexible, the selected Shape will resize proportionally to the Frame resizing. In case you choose fixed dimension, the Shape will stay the same size. You may notice how it’s not possible to use 3 Struts in any axis at the same time. Such scenario would not allow for the Frame to be resized at all, which makes little sense.
Springs and Struts for width and height are not available for Shapes that are rotated, scaled, or their anchor is moved from default position. Such Shapes are only able to customize margins, which means they can only move during resizing. Resizing is also not available for Beziers, Stars and Polygons.
There are several special considerations when using Frames with Beziers. As you might notice, they don’t have Spring settings for width and height. That’s because every vertex of Bezier has its own Springs settings and can be configured independently. Bezier vertices have the simplified Springs settings with only margins, since they have no dimensions.
Interesting aspect if this per-vertex resizing is that different parts of Bezier can be affected by different Frames. Imagine a double-headed arrow, where you encapsulate each head in its Frame and then move them independently.
To learn more about Frames in PaintCode, see our Dynamic Shapes documentation and Dynamic Beziers documentation or watch tutorial videos.