Needed a small area for children to practice writing letters in a DPS application about the Spanish alphabet.
The HTML5 canvas tag is relatively new and offered what was needed.
The final application,
Todas las letras, is free for iPad on the itunes app store.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
#canvas
{
width:346px;
height:190px;
margin-right:auto;
background-color:White;
}
#clearCanvasDiv
{
width:346px;
height:40px;
margin-right:auto;
background-color:LightGray;
}
body
{
margin:0px;
width:100%;
height:100%;
background-color:Blue;
}
.btn
{
text-align: center;
text-decoration: none;
color: Gray;
width:346px;
height:40px;
background-color:Yellow;
border: 0px;
display: block;
outline:none;
}
</style>
<title>DrawingCanvas</title>
<!--Prevent touch devices from scrolling and zooming -->
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
</head>
<body style="overflow:hidden">
<div id="canvas">
<canvas id="myCanvas" width="346" height="190"></canvas>
</div>
<div id="clearCanvasDiv">
<canvas id="clearCanvas" width="346" height="40"></canavs>
</div>
<script type="text/javascript">
//document.body.scroll = 'no';
// Stores the points during a draw
var currPoints = new Array();
// Last know position (used when drawing the line)
var moveFrom = { x: 0, y: 0 };
// Drawing color of the brush
var colorHex = "DimGray";
// True if drawing is in progress
var isDrawing;
// True if touch is supported (set on touchdown)
var hasTouch;
// Brush size
var diameter = 2;
// Canvas
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.lineCap = "round";
// Registers the mouse and touch events
registerInputListeners();
var clearCanvas = document.getElementById('clearCanvas');
var clearCtx = clearCanvas.getContext('2d');
clearCtx.font = "bold 14px arial";
clearCtx.fillText("Escribe - Borra", 124, 24);
clearText();
// Clears the canvas
function clearText() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = "6e9ef2";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(0,10);
ctx.lineTo(346,10);
ctx.moveTo(0,180);
ctx.lineTo(346,180);
ctx.stroke();
ctx.beginPath();
//ctx.strokeStyle = "red";
//ctx.moveTo(0,105);
//ctx.lineTo(346,105);
//ctx.stroke();
drawDash(ctx, 0,105, 346, 105, 10, "red");
}
function drawDash(can, x1, y1, x2, y2, dashLen, color) {
if (dashLen == undefined)
dashLen = 2;
can.beginPath();
can.strokeStyle = color;
can.moveTo(x1, y1);
var dX = x2 - x1;
var dY = y2 - y1;
var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen);
var dashX = dX / dashes;
var dashY = dY / dashes;
var q = 0;
while (q++ < dashes) {
x1 += dashX;
y1 += dashY;
can[q % 2 == 0 ? 'moveTo' : 'lineTo'](x1, y1);
}
can[q % 2 == 0 ? 'moveTo' : 'lineTo'](x2, y2);
can.stroke();
can.closePath();
}
// Register mouse events
function registerInputListeners() {
canvas.onmousedown = ev_mousedown;
canvas.onmousemove = ev_mousemove;
document.onmouseup = ev_mouseup;
canvas.ontouchstart = ev_touchstart;
canvas.ontouchmove = ev_touchmove;
document.ontouchend = ev_touchend;
clearCanvas.onmousedown = ev_mousedownClearCanvas;
clearCanvas.ontouchstart = ev_touchstartClearCanvas;
}
// ################# workaround for scrolling issue - start
function ev_mousedownClearCanvas(ev) {
if (hasTouch)
return;
//ctx.clearRect(0, 0, canvas.width, canvas.height);
clearText();
ev.preventDefault();
}
function ev_touchstartClearCanvas(ev) {
// Ignore any multi-touch
if (isDrawing)
return;
hasTouch = true;
//ctx.clearRect(0, 0, canvas.width, canvas.height);
clearText();
ev.preventDefault();
}
// ################# workaround for scrolling issue - end
// ###### Mouse functions
// ######### Drawing funcitons (shared by mouse and touch)
function startDrawing(x, y) {
isDrawing = true;
var point = { X: x, Y: y };
currPoints = new Array();
currPoints.push(point);
moveFrom.x = x;
moveFrom.y = y;
}
function draw(x, y) {
drawPoint(moveFrom.x, moveFrom.y, x, y, colorHex, diameter);
var point = { X: x, Y: y };
currPoints.push(point);
moveFrom.x = x;
moveFrom.y = y;
}
function endDrawing() {
isDrawing = false;
currPoints = new Array();
}
// ###### Mouse functions
function ev_mousedown(ev) {
if (hasTouch)
return;
var x = ev.pageX - canvas.offsetLeft;
var y = ev.pageY - canvas.offsetTop;
startDrawing(x, y);
ev.preventDefault();
}
function ev_mousemove(ev) {
if (hasTouch)
return;
if (!isDrawing)
return;
var x = ev.pageX - canvas.offsetLeft;
var y = ev.pageY - canvas.offsetTop;
draw(x, y);
ev.preventDefault();
}
function ev_mouseup(ev) {
if (hasTouch)
return;
if (isDrawing) {
if (currPoints.length > 4000) {
setStatus('Spray can malfunction');
return;
}
if (currPoints.length > 1) {
//addStroke();
}
}
endDrawing();
}
// ###### Touch functions
function ev_touchstart(ev) {
// Ignore any multi-touch
if (isDrawing)
return;
hasTouch = true;
// Find coord.
var x = ev.changedTouches[0].clientX - canvas.offsetLeft;
var y = ev.changedTouches[0].clientY - canvas.offsetTop;
startDrawing(x, y);
ev.preventDefault();
}
function ev_touchmove(ev) {
if (!isDrawing)
return;
hasTouch = true;
var x = ev.changedTouches[0].clientX - canvas.offsetLeft;
var y = ev.changedTouches[0].clientY - canvas.offsetTop;
draw(x, y);
ev.preventDefault();
}
function ev_touchend(ev) {
if (isDrawing) {
if (currPoints.length > 4000) {
setStatus('Spray can malfunction');
return;
}
if (currPoints.length > 1) {
//addStroke();
}
}
endDrawing();
}
// ###### Drawing
function drawPoint(x1, y1, x2, y2, color, brushSize) {
ctx.strokeStyle = color;
ctx.lineWidth = brushSize * 2;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
</script>
</body>
</html>