Keeping It Real: Direct Manipulation
One of the headline features of Project Comet is Repeat Grid, a new tool that makes it easy to lay out repeated items in a design, like a contact list or a photo gallery.
With the Repeat Grid, you can draw an example item, then drag out the grid handles to add rows and columns fluidly. Each item can have its own content, but the layout of each item is kept consistent across the grid.
To adjust the overall grid layout, you can just mouse over the empty padding area between two rows or columns to highlight it, then click and drag to change the padding across the whole grid, as you can see at the end of the example. This mouseover affordance makes layout adjustments feel very direct and fluid.
However, when Adobe built the initial prototype of this padding design and tried it out, they ran into an interesting problem.
The obvious way to handle the mouse drag is to change the padding by the number of pixels the mouse moves. This works fine if you drag the padding underneath the first row. But it starts to feel weird if you drag the padding elsewhere — say, between the fourth and fifth rows in a larger grid.
You can see that the padding doesn’t track the mouse — it seems to get bigger much faster than the mouse is moving, even though we’re adding just one pixel of padding for every pixel the mouse moves. This happens because the padding is the same between each row by default, so adding one pixel to the padding adds one pixel below every row. That means the next row below the mouse will actually move four times as fast as the mouse does. That destroys the illusion of direct manipulation; Comet team really want the padding to stay “attached” to the mouse as the user drags it.
The solution turns out to be simple: just divide the mouse drag distance by the index of the row above the mouse. For example, when dragging the padding below the fourth row, we divide the drag distance by four, so dragging the mouse four pixels increases the padding between each row by one. This keeps the padding under the mouse in sync with the mouse position no matter which row’s padding you drag.
Keeping It Consistent: Snapping and Resizing
The bread and butter of a design app is in its core layout tools: drawing, resizing, and aligning items. But even in these most basic of interactions — affordances that have been in design tools since the beginning of time (more or less) — Adobe found subtle details that were surprisingly tricky to get right.
In Comet, as in many other design and layout tools, Adobe automatically snap the edges of items to align with each other as you move or resize them. And as in other tools, users can hold down the Shift key while dragging a resize handle to maintain the aspect ratio (relative width and height) of the item. But after building the first versions of these two features, the team found that they didn’t work well with each other.
The obvious implementation of edge snapping during a resize looks at the mouse position as you drag to see whether it lines up with the edge of a nearby shape. That works fine for ordinary resizes, as in the top example here.
When you do a Shift-resize, though, the mouse doesn’t always stay directly on the corner of the shape, because the corner has to be in a different location in order to preserve the shape’s proportions. You can see this in the bottom example, where the mouse drifts off the bottom of the square. Because of this, we can’t use the mouse position to figure out when to snap.
It would have been easy to write off this case, and in fact many of the other design tools we checked don’t seem to handle it — during a Shift-resize, they either continue to snap based on the mouse position, or they turn off edge snapping entirely. However, we felt it was important to deal with this case properly, because UX designers often work with images, and when resizing an image you almost always want to preserve its aspect ratio.
So Adobe analyzed all the different combinations of resize constraints and snapping types to make the algorithm work predictably during constrained resizes. As shown below, it works well even in more advanced cases, like using Alt-Shift to resize an item from the center while maintaining its proportions, or Shift-dragging an edge handle.
Keeping It Smooth: Zooming and Artboards
Like many other modern apps, when the user zooms in or out of the canvas, we use the GPU to make the zoom feel smooth. This involves a little bit of a cheat: the GPU is really good at redrawing bitmaps at different scales quickly, but in general it doesn’t help with redrawing vectors or text quickly at different scales. So during the zoom, we have the GPU just rescale the artwork on the canvas at its current resolution (which might briefly cause it to draw pixellated), then redraw it at the final resolution after the zoom is finished.
This caused a problem for artboard titles. If we were to zoom them along with the artwork, they would get temporarily bigger or smaller during the zoom, which would look really weird. When you’re zooming far in, you don’t want the titles to become huge and pixellated! It seemed like a small detail, but we felt it would compromise the zooming experience. So we decided to try to fix it.
As you can see in the example, we’re able to keep the artboard title sizes consistent during smooth zooms by decoupling the rendering of the artboard titles from the artwork. We implemented some tricks in the renderer architecture to keep the GPU’s rendering of the artwork in lockstep with the drawing of the artboard titles on each frame so they don’t drift relative to each other. This also made it possible for us to truncate the artboard titles when you’re zoomed out far enough that they would overlap otherwise. Though it’s not easy to see in an animated GIF, we’re still able to maintain a smooth frame rate during the zoom.href="http://blogs.adobe.com/creativecloud/building-project-comet-details-matter/" data-color-override="false" data-hover-color-override="false" data-hover-text-color-override="#fff">Button Text