Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save stevefaulkner/9248685 to your computer and use it in GitHub Desktop.
Save stevefaulkner/9248685 to your computer and use it in GitHub Desktop.
<body onload="initDrawingArea();">
<canvas id="example" height="200" width="750">
<!-- Canvas Subtree acts as Shadow DOM that the browser maps to the platform accessibility API -->
<label for="showA"><input id="showA" type="checkbox"> Show As </label>
<label for="showB"><input id="showB" type="checkbox"> Show Bs </label>
<!-- ... -->
</canvas>
</body>
function initDrawingArea() {
//Add the event listeners
document.getElementById('showA').addEventListener('focus', redraw, true);
document.getElementById('showB').addEventListener('focus', redraw, true);
document.getElementById('showA').addEventListener('blur', redraw, true);
document.getElementById('showB').addEventListener('blur', redraw, true);
document.getElementsByTagName('canvas')[0].addEventListener('change', redraw, true);
document.getElementsByTagName('canvas')[0].addEventListener('click', processClick, false);
// Draw the shadow DOM checkboxes on the canvas. Think model view controller
redraw();
}
/*
drawCheckbox
Draws a checkbox from a checkbox element in the shadow DOM
Parameters:
context - device Context
element - Checkbox element in the shadow DOM or <canvas> subtree
x - x coordinate position of the checkbox
y - y coordinate positon of the checkbox
*/
function drawCheckbox(context, element, x, y) {
context.save();
context.font = '15px sans-serif';
context.textAlign = 'left';
context.textBaseline = 'middle';
var metrics = context.measureText(element.parentNode.textContent);
context.beginPath();
context.strokeStyle = 'black';
context.rect(x-5, y-10, 15, 15);
context.stroke();
if (element.checked) {
context.fillStyle = 'black';
context.fill();
}
context.fillText(element.parentNode.textContent, x+10, y);
context.beginPath();
context.rect(x-7, y-12, 12 + metrics.width+2, 20);
if (document.activeElement == element)
context.drawFocusIfNeeded(element);
context.addHitRegion({control: element});
context.restore();
}
//Non-essential functions
function drawBase() { /* ... */ }
function drawAs() { /* ... */ }
function drawBs() { /* ... */ }
/*
redraw
Redraws the canvas rendering of the shadow DOM checkboxes
*/
function redraw() {
var canvas = document.getElementsByTagName('canvas')[0];
var context = canvas.getContext('2d');
// erase the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
//Draw checkboxes showA and showB
drawCheckbox(context, document.getElementById('showA'), 20, 40);
drawCheckbox(context, document.getElementById('showB'), 20, 60);
//These functions are nice to have but unnecessary
drawBase();
if (document.getElementById('showA').checked)
drawAs();
if (document.getElementById('showB').checked)
drawBs();
}
/*
processClick
Canvas event handler that processes canvas element checkbox clicks, and
updates the shadow DOM with the visual canvas.
Parameters:
event mouse click event
*/
function processClick(event){
/* Determine if the clicks are in the checkboxes and if so toggles the
corresponding canvas subtree checkbox and manage the focus */
var canvas = document.getElementsByTagName('canvas')[0];
var context = canvas.getContext('2d');
var x = event.clientX - canvas.offsetLeft;
var y = event.clientY - canvas.offsetTop;
drawCheckbox(context, document.getElementById('showA'), 20, 40);
if (context.isPointInPath(x, y)) {
element = document.getElementById('showA');
document.getElementById('showA').checked = !(element.checked);
//Since the element was clicked, give it focus
element.focus();
}
drawCheckbox(context, document.getElementById('showB'), 20, 60);
if (context.isPointInPath(x, y)) {
element = document.getElementById('showB');
document.getElementById('showB').checked = !(element.checked);
//Since the element was clicked, give it focus
element.focus();
}
// Redraw the canvas
redraw();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment