Re: Basic code examples for pointer regions

On Sat, Nov 12, 2011 at 8:50 AM, Charles Pritchard <chuck@jumis.com> wrote:

> On 11/11/2011 3:48 PM, Jonas Sicking wrote:
>
>> On Wed, Nov 2, 2011 at 5:52 PM, Charles Pritchard<chuck@jumis.com>
>>  wrote:
>>
>>> setPathForElement is all that's needed by authors to fulfil WCAG.
>>> Compared
>>>
>>> to beginElement it's shorter with far less restrictions and
>>> considerations.
>>>
>>> Blob Sallad is an excellent tech demo for interactivity; I use it all the
>>> time, it has a free license.
>>> http://www.blobsallad.se/**blobsallad.js<http://www.blobsallad.se/blobsallad.js>
>>> http://www.blobsallad.se/**iframedsallad.html<http://www.blobsallad.se/iframedsallad.html>
>>>
>>> To enable accessible hit testing, I'd go to line 880 in the this.draw
>>> method:
>>>    this.drawBody(ctx, scaleFactor);
>>> And change it to:
>>>    ctx.beginElement(element);
>>>    this.drawBody(ctx, scaleFactor);
>>>    ctx.endElement();
>>> Or, simpler:
>>>    this.drawBody(ctx, scaleFactor);
>>>    this.setPathForElement(**element);
>>>
>> This only works because drawBody is able to do the whole drawing as a
>> single path. What would you do if the bob character required 5
>> separate paths to be drawn? Or if his eyes were drawn using drawImage
>> and resided outside his main body (like the cookie monster who's eyes
>> are on top of his head).
>>
>
> I'd prefer to work with existing code examples. It's more appropriate as
> the code has been done, and
> refactoring is less needed. But, it's good to be flexible.
>
> ...
>
> Taking this in reverse: if his eyes were drawn outside his body, with
> drawImage, I'd use punch-out techniques to first draw a circle, then use
> clip or a composite operator like source-in, as the final touch for the
> eyes.
> We don't need separate beginPath (separate paths): we can work with
> sub-paths. beginPath and closePath are very different methods. beginPath
> clears all the sub-paths, closePath just closes the current sub-path to
> start a new one.
>
> If cases where the drawing is a complex set of paths, I'd adapt my path
> processing, possibly to the point of just setting the entire region as
> clickable by using a rectangle. I want people to have the expected
> experience of moving over and tapping in the right area, otherwise, you're
> setting them up for a game of Operation. Could be fun, but not as useful.
> http://en.wikipedia.org/wiki/**Operation_(game)<http://en.wikipedia.org/wiki/Operation_%28game%29>
>
> On the web today, you're either working with rectangular regions, or
> you're working with very basic shapes. That's actually a good thing. I hate
> it when UI requires very precise mouse movements to do basic daily tasks.
> Such requirements should either be part of game-play or otherwise run afoul
> of the practices setup by WCAG. Remember, we are now targeting mobile
> phones, tiny screens and big fingers.
> ...
>
> I think the drawEars method (line 635) is the best match for what you're
> bringing up.
>
> drawEars is not currently used by the demo, I suspect that closePath could
> have been used instead of running two sets of beginPath/fill/stroke
> commands. The method is not used, so the author likely didn't clean up the
> method.
>
> There are a few options here: I might create an element for each ear, to
> distinguish right and left ear. Depends on what I'm trying to present to
> the user.
> If I'm allowing the user to pin an accessory onto the ear (such as an
> ear-ring), it makes sense to distinguish the ears. If it's just an
> additional area for dragging onto with no special
> semantics, then I may as well associate it with the same element as the
> body.
>
> In that first case (an ear-ring), I'm just doing the same as I did with
> drawBody, running setPathForElement once for each ear.
>
> In the second case, if I'm trying to catch it in the same call as the
> drawBody path, I'd add another argument to drawEars,
> one that says "give me a path" instead of the default behavior of "stroke
> and paint a path".
>
> I'd have an if statement, to use  closePath instead of beginPath, and I'd
> have if statements skip the paint/fill commands.
> Again, drawEars could be simplified in its current form, but if I were
> making minimal changes, I'd have a few extra if statements.
>
> Example (for line 641):
> if(onlyPath) ctx.closePath(); else ctx.beginPath();
> ...
> if(!onlyPath) { ctx.fill(); ctx.stroke(); }
>
> These hooks end up making debugging a little easier and more fun, because
> more functionality is exposed throughout the program.
> Now, with the onlyPath flag added in, I can do things like setup a
> background or a shadow or do other color-effects with the path.
>
> You can easily colorize the clickable regions. For debugging or as another
> use mode.
>

So it sounds to me that if your object is drawn using a single path, you'd
prefer to use setPathForElement since it's just a single line of additional
code to get hit-testing.

If your object is drawn using multiple paths, you'd prefer to go through
what sounds like fairly complex operations to merge those paths into a
single path which you could then use together with setPathForElement.

If your object is drawn using text or drawImage function, you'd set up
hit-testing specific paths and call setPathForElement.

Based on this. It sounds like you'd only have fewer lines of code added,
and fewer lines of code changed in the first scenario. While you can get
the second and third scenario working with setPathForElement, it seems to
me to require more changes and more additions.

If that's the case, I don't understand why setPathForElement is the
preferred option. Are you simply hoping that the first scenario is common
enough that the wins there outweigh the losses for the other scenarios?

Am I missing or misunderstanding something?

/ Jonas

Received on Monday, 14 November 2011 23:49:40 UTC