+ - 0:00:00

Canvas Accessibility

Past, Present and Future

Inclusive Design 24
15 MAY 2014 #GAAD
Mark Sadecki (@cptvitamin)
http://j.mp/a11y-canvas

1 / 36

The past,
the present,
and the future
walked into a bar.

It was tense.

2 / 36

Introductions

Mark Sadecki (@cptvitamin)

  • World Wide Web Consortium (W3C)
    • Web Accessibility Initiative (WAI)
  • Staff Contact
    • HTML Accessibility Task Force
    • Canvas Sub Group
    • Media Sub Group *
    • Bug Triage *

* Looking for recruits (contact mark@w3.org)

4 / 36

<canvas>
Accessibility Challenges

5 / 36

What is <canvas>?

Canvas is:

A 2D drawing API that includes drawing functions for rendering interactive bitmap images

What is it Good For?

  • Graphs
  • Animations
  • Games
  • Image Manipulation
  • Appeared in OS X in 2004
  • Appeared in WHAT WG spec in 2006
6 / 36

Challenge #1

No content to interact with

<canvas id="magic"
  width="350" height="196">
Animated gif: Actor Shia LaBeouf wearing a sparkly unicorn shirt and wiggling his fingers independent while mouthing the word magic.
</canvas>

What happens in the canvas, stays in the canvas.

7 / 36

Solution #1

Extreme Trustfall: Cartoon character falling backwards of the roof of a tall building

Fallback content

<canvas id="magic"
  width="350" height="196">
  <h1 id="magic-recipe">Making magic</h1>
  <ol>
    <li>Find a unicorn</li>
    <li>Coax it under
        your coat tails</li>
    <li>Misdirect audience
        (flash of smoke?)</li>
    <li>Reveal unicorn like a boss</li>
  </ol>
  <button id="button">Abracadabra!</button>
</canvas>
8 / 36

Fallback Content

  • Solution has been around since @2010
  • Well supported by browsers and AT
  • Was an HTML5 solution, not a <canvas> one

Pros

  • Useful if author wants to provide a text alternative for canvas content

Cons

  • Not programmatically linked with the <canvas> itself
9 / 36

Challenge #2

No association between pixels/paths and fallback elements

  • Anything drawn to <canvas> is just a bitmap/pixels
  • No programmatic relationship between those pixels and fallback elements
  • No way to inform AAPIs of the location of those pixels
  • No way to pass Events on the canvas to the associated fallback elements.
10 / 36

Solution #2

Hit Regions

  • Defines the 'hit region' and 'hit region list'
  • Defines how MouseEvents are handled
  • addHitRegion(id, control)
    • Method for associating a current path with a fallback element
  • removeHitRegion(id)
    • Removes a hit region from the 'hit region list'
  • clearHitRegions()
    • Removes all hit regions from the 'hit region list'
11 / 36

Challenge #3

A square with cross hair indicators at the mid point of each side

No visual focus indicators

  • Focus indicators are crucial for anyone using a keyboard
  • No (specified) standard method for indicating focus in HTML5 <canvas>
  • Without standard/native method for doing so, authors are unlikely to roll their own.
12 / 36

Solution #3

drawFocusIfNeeded(element)

  • New method with a new name
  • Draws a focus indicator around the current path if the fallback element associated with that path currently has focus.
  • Scrolls current path into view if path is off screen (not beyond bounds of canvas)
  • Informs Accessibility API of the location of the currently focused element.
13 / 36

Can I Use?

30 MAY 2014

So present it could be future

Logo: Firefox Nightly

Currently only supported by Firefox Nightly 32.0a1 (2014-05-30) with experimental flags enabled:

canvas.focusrings.enabled       true
canvas.hitregions.enabled       true

Setting flags in Firefox

Screenshot of Firefox Nightly browser address bar containing the words about and config, separated by a colon

To enable expermental flags in Firefox, type about:config (a colon seperates the two words) in your browser's address bar and then limit the results by searching for canvas.

14 / 36

Building an Accessible Game using HTML5 Canvas

15 / 36

Challenges

  • I'm NOT a game designer
  • The game needs to use all of these new features...
  • ...that were implemented a few weeks ago
  • The game needs to showcase the accessibility benefits of these new features
  • I only have one week to design/build/test (in free time)

This will be no "Call of Duty"

16 / 36

Guiding Principles

Game should be:

  • Useable by keyboard users
  • Useable by screen reader users
  • Useable by screen magnification users
  • Equally challenging for all
17 / 36

Whac-a-mole

  • Easy enough
  • Simple concept
  • Should allow me to showcase new features and satisfy all my guiding principles
18 / 36

Deviations from Whac-a-mole

  • There will be two characters rather than one
    • One is bad and should be "Whacked" (+10 points)
    • The other is good and should not be "Whacked" (-10 points)
  • Fixed number of opportunities to score (10)
  • We're not whacking moles here
    • My daughter suggested characters from her favorite video game, Minecraft
    • I agreed since they would be relatively easy to draw using <canvas>
    • We chose "Creepers" (bad) and "Steve" (good)
  • Game will be called "Whac a creeper, not a Steve"
19 / 36

Game play

  • Player moves focus to, and then activates Start button
  • Characters randomly appear on the board, pausing between each
  • Player either clicks or hits "Enter" key on Creepers to score 10 points
  • Game ends when 10 Creepers have appeared on the board
20 / 36

Game mechanics

21 / 36

The Board

<canvas id="game" width="150" height="200">
  <p id="status" tabindex="0" aria-live="assertive">Start</p>
  <p id="00"></p>
  <p id="01"></p>
  <p id="02"></p>
  <p id="10"></p>
  <p id="11"></p>
  <p id="12"></p>
  <p id="20"></p>
  <p id="21"></p>
  <p id="22"></p>
  <p id="oob" tabindex="0">Out of Bounds!</p>
</canvas>
<p aria-live="polite">Score: <span id="score">0</span></p>
22 / 36

Draw the character

  • Game starts
  • A random character is drawn in one of 9 grids
  • A transparent hit region is drawn over the character and associated with corresponding fallback element
  • That element is made focusable (tabindex=0)
  • That element's text content is updated with the name of that character (for screen reader users)
  • Focus is moved to a neutral location (next tab will move focus to character)
23 / 36

Drawing the character

Drawing squares in <canvas> is easy

// draw a 5px by 5px square
ctx.beginPath();
ctx.fillStyle = color;
ctx.rect(x, y, 5, 5);
ctx.fill();

// color grid for creeper, loop over to draw character
var creeper = [
["#7D9C79", "#008000", "#348828", ... "#366B36"],
["#599A4C", "#7D9C79", "#62A853", ... "#789776"],
["#008000", "#292929", "#2B2B2B", ... "#366B36"],
["#348828", "#2D2D2D", "#000000", ... "#93939C"],
...
["#789776", "#7D9C79", "#4A4A4A", ... "#62A853"],
];
24 / 36

Steve!

A rendering of Steve from Minecraft. Minecraft characters are composed of 3d grids of solid colored blocks, so Steve's face, shown here in 2d is an 8 x 8 grid of colored squares.

That's a an actual <canvas> element.
25 / 36

Player takes action (or not)

  • Player clicks on character or
  • Uses Tab key to move focus to that character and press the Enter key
  • If player is using a screenreader, the name of the character will be read aloud when focus is moved to it
  • Score is calculated and updated
  • If player does not take action, the game times out and the board is refreshed
26 / 36

Accessibility

27 / 36

Hit Regions

  • Each time a character is drawn on the grid, a transparent square is drawn over the character.
  • A Hit Region associates that square with the corresponding <p>
  • Accessibility APIs are informed of the location of that region as if it were the location of the fallback element
  • The player's screen will move to that location if the player is using magnification software
28 / 36

Hit Region Script

// draw a button and assign a Hit Region to it
function drawButton( id ) {
  ctx.beginPath();
  ctx.fillStyle = "green";
  ctx.rect( 0, 0, 100, 30 );
  ctx.fill();
  ctx.addHitRegion(
    { id: id,
      control: document.getElementById(id)
    });
}
29 / 36

drawFocusIfNeeded(element)

Whenever a focus change event occurs, the drawFocusIfNeeded() method is invoked and an indicator, consistent with the default focus indicator for the browser and operating system is drawn on the canvas.

  • Focus change events
    • Mouse click on a Hit Region
    • Tab press
    • Clear grid/Reset board
30 / 36

Draw Focus Script

I called this function whenever I drew a path to the Canvas that was associated with a fallback element and I wanted to move focus to it.

function drawFocus( elem ){
  elem.focus();
  ctx.drawFocusIfNeeded( elem );
}
31 / 36

Let's play!

  • This game only works in Firefox Nightly 32.0a1 (2014-05-30) with canvas.focusrings.enabled and canvas.hitregions.enabled set to true
  • It is currently short on features (Game Over, Play again, grid and speed adjustments, etc.)
  • Only limited testing with speech and magnification (works with NVDA screenreader, MAGic and ZoomText)

This is normally where the live demo would happen. If you are not having success in your environment, or don't have a screen reader or screen magnication software installed, feel free to watch the videos on the following slides.

32 / 36

Accessible Canvas Game Demo

View "Accessible Canvas Game Demo" on Youtube http://j.mp/cnv-demo

33 / 36

Accessible Canvas Game Demo using Screenreader

View "Game Demo using Screenreader" on Youtube http://j.mp/cnv-scr

34 / 36

Accessible Canvas Game Demo using Screen Magnification

View "Game Demo using Screen Magnification" on Youtube http://j.mp/cnv-mag

35 / 36

Stay in touch!

Inclusive Design 24
15 MAY 2014 #GAAD
Mark Sadecki (@cptvitamin)
http://j.mp/a11y-canvas

Github

Issues and Pull Requests
are welcome:
http://j.mp/a11y-whack

36 / 36

The past,
the present,
and the future
walked into a bar.

It was tense.

2 / 36
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
f Toggle fullscreen mode
c Clone slideshow
p Toggle presenter mode
w Pause/Resume the presentation
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow