Where Da Mouse At?

First and foremost, let me give credit where credit is due. When I ran into the problem of the mouse X and Y not being where I thought they should be in the Origami Phone patch, I came across this Macoscope blog post by Dawid Woldu which explains the cause of the issue (much better than I could) and a solution for the problem in iPhone portrait mode. This article and my mouse position patch are based on his work, and I highly recommend reading it!

Since he wrote that article, Origami was updated to version 1.2, which added not only other devices, but landscape orientation. Since the UI I am mocking up is landscape only, I needed a solution for that, and while I was at it, I figured I might as well take a stab at handling the new devices. The result is a Composition that will give you the correct mouse X and Y for all the Origami Phone devices in landscape and portrait. Mostly1. It also renders the coordinates on the device screen, and has a happy little square Hit Area that should follow in the center of the cursor as you move it around:

Quartz Composer Screenshot

Landscape and Windows Phone Oh My!

Here’s the file so you can follow along with the rest of the article, or if you just want to grab out the bits you need and get on with your day: MouseAnger.qtz.zip (889k) It’s got a bunch of Notes in there that explain a lot of what is going on as well.

How it works

In a nutshell, we pass in the window aspect ratio and device screen width and height (we don’t have access to Pixels Wide and Pixels High so we have bring them in again) to the Render In Image patch:

Quartz Composer Screenshot

Step 1: Learn stuff we need to know

These are published inputs of my Where Da Mouse At? macro patch that does the conversion, which lives inside the Render In Image:

Quartz Composer Screenshot

Step 2: the Macro where it all happens

Inside the Where Da Mouse At? Macro, we use the device height and device width to determine a couple things; the aspect ratio of the device, and its orientation. To get the aspect ratio of the screen, we divide the smaller side into the larger. Determining if we are in Portrait orientation is done by dividing height by width and checking to see if that number is greater than one in a Conditional.

Quartz Composer Screenshot

Step 3: Learn stuff about the device

Once we know the orientation of the device, we correct the X position in one of two ways: if we are in portrait mode, we adjust based on the aspect ratio of the window, the device aspect ratio, and a fixed number that represents the size of the simulated device relative to the window (which I badly named origamiConstant):

mouseXPosition * (phoneAspectRatio / origamiConstant) * windowAspectRatio

If we are in landscape mode, we can just divide the mouse position by the origamiConstant. These values are piped into a Multiplexer which selects the value to output based on our Is Portrait conditional:

Quartz Composer Screenshot

Step 4: Adjusting the X Position

Adjusting the Y position is similar to adjusting the X, but backwards! In portrait, we do a straight division by the origamiConstant, but in landscape we have to account for the window and device aspect ratios:

mouseYPosition * (phoneAspectRatio / origamiConstant) / windowAspectRatio

Again, these two values are sent to a multiplexer that outputs the correct one based on our calculated device orientation:

Quartz Composer Screenshot

Step 5: Adjusting the Y Position

Mmmm, Fudge!

There’s one glaring omission, and that’s the value of origamiConstant. Where did that come from? Well, from another Macro patch I made that takes in the maximum value of the device screen size, and outputs the appropriate magic number based on that:

Quartz Composer Screenshot

Step 6: In goes a number, out comes magic!

How does this work? Nothing fancy, I’m afraid. I use the screen size to tell what device you are using, and I spit out the right value based on that. How do I know the right value? Because I made my Quartz Composer window exactly 1000px wide, took screen shots of all the devices, then measured how many pixels across the screen was. How lazy is that? Very. But it works. Mostly2.

Quartz Composer Screenshot

Step 7: It’s not really magic, just brute force

Here are the fudge factors I got if you would like to use them for some other reason:

Enjoy!

Here’s the file link again just in case you missed it: MouseAnger.qtz.zip (889k)


1: The coordinates will start to not be accurate if the Viewer window itself is “more portrait” than a portrait device, or “more landscape” than a landscape device. This is because the ratio of the screen to the window stops being constant at that point.

Since I saw in a GitHub issue that Facebook was looking into this, I most likely will not go through the effort to calculate everything the “right” way, since they will probably do it much better than I. Until then, this works for the most part.

2: See note 1

back to top