Quartz Composer. Origami. Mouse. Headaches.

UPDATE: Please note that as part of its Origami 1.2 update, Facebook introduced an entirely new Phone patch which now supports Landscape mode. The part of this article that pertains to the Phone patch is no longer valid. [The approach presented in the article will still work in Portrait mode (as in most cases, the ratio between device and Viewer heights is still roughly 1.6), but the device size is now also affected by the width of the Viewer window.]

UPDATE 2: Updated (as to Origami 1.4) coordinates translator is available here


Ever since Facebook released Origami, Quartz Composer has become significantly more user friendly for UI/UX designers. Even a silly goose like me.

Yet using native QC interaction patches along with Origami’s Phone patch is still a bit confusing. The first problem you’re sure to encounter is tracking the mouse position relative to the device screen.

Why would you want to do that? Origami patches let you prototype some really cool interactions very quickly, but once you want to model custom behavior, things get complicated. Tracking the correct mouse position may help you model your own interaction patches.

The Problem

The default QC coordinate system setting uses the centre of the Viewer window as the origin (point 0,0), and assigns the coordinates –1.0 and +1.0 to the left and right edges of the Viewer window, respectively, but coordinates on the Y axis depend on the aspect ratio of the Viewer window: CQ coordinates The current Origami Phone patch renders the devices in portrait mode, so to ensure it will always be fully visible and as big as possible, it scales proportionally to the Viewer window’s height and not the width. So, obviously, resizing the Viewer window horizontally will not affect the screen size of the rendered device.

The center of the phone screen matches the center of the Viewer window, but both horizontal and vertical coordinates follow the Viewer window size instead of the screen size of the rendered device (as it’s just a clever bitmap and not a real phone. Really.) snapping_scroll_illu2

Solution

Obviously we want to change that. We want the Mouse patch to output 1,1 on the top-right corner of the phone screen.

One good way to start is to put the Mouse patch inside the Render In Image patch (as you would probably do anyway). The ‘Pixels Wide’ and ‘Pixels High’ parameters (usually fed by Phone Dimensions patch) of the Render In Image patch will force the Mouse patch to output the coordinates normalized to the given aspect ratio.snapping_scroll_Illu4It means that now, the right edge of the Viewer window will still output X Position 1, but the top and bottom edges will output 1 and -1 multiplied by the aspect ratio of the Render in Image patch, not the Viewer window.

e.g. for iPhone dimensions, the top and bottom edges of the Viewer window will now return: +1.775 and -1.775 because 1136 / 640 = 1.775

If we convert the Mouse patch outputs using Units to Pixels patch it will now in fact output -320 , +320 (left and right edges) and +568, -568 (top and bottom edges).

Still, we want to get +568 at the top of the phone screen and -568 at the bottom (following the QC coordinate system with positive values above the center and negative values below the center).

Since the device scales following the Viewer window height by a constant ratio, getting the correct output is just a matter of multiplying the mouse’s Y position by that ratio.

How can we obtain the ratio? You could just measure it, or, if you’re a nosy buddy, you could find it lurking around the Origami Phone patch. I did the latter. It’s 1.6. The Viewer window is 1.6 times higher than the phone screen.

So, just multiply the Y position by 1.6 and there you go. You get 1.775 (or 568 when converted to pixels) at the top of the phone screen and -1.775/-568 px at the bottom.

Cool!! What about the X axis? Well, it’s bit trickier. We need to disconnect the relation between the Viewer window width and the mouse’s X position returned by the Mouse patch. To do that, we need to find out the aspect ratio of the Viewer window. We’ll use Rendering Destination Dimensions patch to do just that.snapping_scroll_illu3Important! We can’t use the Rendering Destination Dimensions patch inside Render in Image, as it will return the size of that patch instead of the Viewer window. We have to use it externally and connect it to the self-published input.

Now, since we know the Viewer aspect ratio, the phone aspect ratio, and the constant ratio between both heights, we can get the correct X position. Just multiply the mouse’s X position by the window aspect ratio and divide it by the phone aspect ratio divided by 1.6.

That’s it! Now we can track the mouse pointer position relative to the phone screen, independently of the Viewer window dimensions.

Now what?

Now we build our own interaction patches! Check out my snapping scroll:

Download the above example SnappingScroll_example.qtz

Also, check out super handy console patch, developed by our very own Daniel.

The Science Behind Snapping Scroll - Part I: Dragging
Console patch for Quartz Composer