So, my task was to code a hand: one that could point and tap the index finger.
I suspect that, when large companies are given this task, they just send it over to the 3D graphics departments, whose cheerful minions happily generate a fifty thousand triangle mesh, manipulate it in cutting-edge software, then spit out some beautifully-rendered video files. Which is all well and good if you have that option.
But video files won’t cut it for me. If I’m future-proofing (like I always aim to do), then the number of video files needed would be ridiculous. The digit combinations alone must be 120 or so – and that’s just for opening and closing; still not enough to greet Mr Spock.
So: a 3D mesh. Is it doable? Well, yes, but 3D object construction is not exactly my forte, and it does seem a bit like overkill to add all those triangles for one little hand.
Time is always an issue so I decided to do what I do best when faced with thorny coding problems: I cheat. Realizing that I only needed to see the back of the hand, I decided to go 2D. Yes, some of the movements are 3D, but smart animation can compensate for that.
First step: trace my hand on squared paper.
I traced the open hand, and also a a fist, and then tried to work out where the joints were. I like coding in circles, so each point of interest is a circle. I chose a scale such that I could type in ratios. The y-axis goes to 100, which is obviously 1.0f as a ratio, and makes scaling that much easier.
Yes, this will be a glove, which means I don’t have to worry about drawing fingernails!
If I had had the time, I might have chosen to render the hand in Metal. But I picked plain old Quartz for convenience and expediency.
I originally wanted to do the entire outline as one shape, but quickly decided against it, due to fingers and thumb sometimes hiding behind other digits (and the palm). So I draw the thumb, then little, ring, index and middle fingers in that sequence, because that’s usually the z-order.
The main part of the hand has to be drawn twice. Once at the back, and once more without borders, to erase the lines at the base of all the fingers. This is the “hack” part of the hack-imation, along with the right-hand-side, which I decided was most easily simulated with a Bézier curve.
How to draw a finger? Well, if you can work out where the outer tangent lines meet for two circles, that’s most of the job done. After that it’s just straight lines and arcs.
I treated the thumb like a finger, with the same number of joints. Yes, the base joint is just above the wrist!
One funny thing: if (as my picture shows above) you have the wrist curve dipping down, then your hand will quickly resemble a foot with spidery finger-toes! I strongly advise to flip that smile upside-down to avoid that!
Animating in Code
The maths required for animating a finger or thumb is refreshingly simple. Each joint moves from angle A (zero) to angle B in a linear fashion. You can eyeball the end angles. Just a few cos and sin functions required.
There are one or two sticking points, for example when a fingertip passes below a knuckle. That case is simple enough to simulate from a top-down perspective, however: simply, by drawing to the knuckle and no further.
There are always the odd graphical glitches that crop up, but these can be dealt with – either cleanly or with special-case hacks.
Using as a Cursor
When the hand is finished, the next step is to use it with the cursor. This is easy enough to do with your input code in OSX. The trouble (as usual) lies with iOS: there’s still no way of working out where your finger-tip is until it presses the screen.
What you can do is show the cursor when you tap the screen. You can add a small delay to have the hand fade in and then, when you tap-up, the hand can glide serenely away, fading out as it does so. But this is not ideal. I needed the hand to know where I was going to press for the product video.
I had a brainwave to connect a mouse to my iPhone and have a cursor show up at all times. Well, this works nicely on Android but not on iOS. On iOS, you can’t even connect an Apple mouse or trackpad to an iPhone! You can connect a third-party mouse, but nothing further: there’s no cursor.
Yes, I could have simply cheated and used OSX for all my product videos. But I didn’t want to do that. So I had to think again.
I thought, what if the hand did know where I was going to press? Rather: the hand could be coded to move, click, rotate, fade in and out, and so on. What I needed was a class to automate this.
Then it occurred to me: this wouldn’t just be useful for product videos, but for inline help.
The automation class here goes hand-in-hand with the calling class. At each indexed stage, the calling class should update such details as duration-of-action, hand-state, action-type, alpha, angle etc, and, as necessary, supply destination co-ordinates relative to a view it also supplies.
Finally you get something like this. Still not perfect, but it’ll do. 🙂
I like it!