<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>O&#039;Reilly Radar &#187; Sanders Kleinfeld</title>
	<atom:link href="http://radar.oreilly.com/sandersk/feed" rel="self" type="application/rss+xml" />
	<link>http://radar.oreilly.com</link>
	<description>Insight, analysis, and research about emerging technologies</description>
	<lastBuildDate>Fri, 24 May 2013 12:45:24 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>HTML5 for publishers: Drawing on the screen</title>
		<link>http://radar.oreilly.com/2011/11/html5-for-publishers-canvas.html</link>
		<comments>http://radar.oreilly.com/2011/11/html5-for-publishers-canvas.html#comments</comments>
		<pubDate>Tue, 15 Nov 2011 14:00:00 +0000</pubDate>
		<dc:creator>Sanders Kleinfeld</dc:creator>
				<category><![CDATA[Publishing]]></category>
		<category><![CDATA[@editpick]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[publishers]]></category>

		<guid isPermaLink="false">http://blogs.oreilly.com/radar/2011/11/html5-for-publishers-canvas.html</guid>
		<description><![CDATA[This excerpt from &#34;HTML5 for Publishers&#34; shows how a simple finger painting canvas can be added to an HTML5-based children&apos;s book ]]></description>
				<content:encoded><![CDATA[<p><em>Most publishers have at least a vague sense that HTML5 is an important content technology, but what does that content actually look like? What can it do? The following excerpt from the free ebook &#8220;<a href="http://shop.oreilly.com/product/0636920022473.do">HTML5 for Publishers</a>&#8221; shows how a simple finger painting canvas can be added to an HTML5-based book.</em></p>
<hr />
<p>Doing animations on the <a href="http://en.wikipedia.org/wiki/Canvas_element">HTML5 Canvas</a> is cool, but what&#8217;s even cooler is letting the user draw on the Canvas herself. With the advent of<br />
    touchscreen phones, tablets, and ereaders, this becomes even more<br />
    compelling, as the user can draw directly on the screen with her finger,<br />
    rather than using a mouse or trackpad. In this section, we&#8217;ll look at how<br />
    to implement a simple &#8220;finger painting&#8221; app in the Canvas, which would be<br />
    a nice fit for a children&#8217;s ebook&#8212;for example, a story that lets kids draw<br />
    their own illustrations to accompany the text, or a preschool textbook<br />
    that uses the finger painting to teach colors and shapes.</p>
<p>Here&#8217;s the HTML we&#8217;ll use to construct the Finger Painting page; the<br />
    <code>&lt;canvas&gt;</code> tag which will hold the drawing area is<br />
    highlighted in <span class="bold"><strong>bold</strong></span>:</p>
<pre>
&lt;!doctype html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;title&gt;Finger Painting&lt;/title&gt;
&lt;script src="modernizr-1.6.min.js"&gt;&lt;/script&gt;
&lt;script src="finger_painting.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div&gt;
<span class="bold"><strong>&lt;canvas id="canvas" width="500" height="500"&gt;</strong></span>
 Your browser does not support the HTML 5 Canvas.
<span class="bold"><strong>&lt;/canvas&gt;</strong></span>
&lt;/div&gt;
&lt;div&gt;
&lt;h1&gt;Finger Painting&lt;/h1&gt;
&lt;p&gt;Click/tap a color below to select a color, and then drag/swipe on the
  canvas above to draw a picture.&lt;/p&gt;
&lt;p&gt;Color selected: &lt;span id="color_chosen"&gt;Black&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&lt;input type="button" id="Red" style="background-color: red; width: 25px;
height: 25px;"/&gt;
&lt;input type="button" id="Orange" style="background-color: orange; width: 25px;
height: 25px;"/&gt;
&lt;input type="button" id="Yellow" style="background-color: yellow; width: 25px;
height: 25px;"/&gt;
&lt;input type="button" id="Green" style="background-color: green; width: 25px;
height: 25px;"/&gt;
&lt;input type="button" id="Blue" style="background-color: blue; width: 25px;
height: 25px;"/&gt;
&lt;input type="button" id="Purple" style="background-color: purple; width: 25px;
height: 25px;"/&gt;
&lt;input type="button" id="Brown" style="background-color: brown; width: 25px;
height: 25px;"/&gt;
&lt;input type="button" id="Black" style="background-color: black; width: 25px;
height: 25px;"/&gt;
&lt;input type="button" id="White" style="background-color: white; width: 25px;
height: 25px;"/&gt;
&lt;/p&gt;
&lt;p&gt;&lt;input type="button" id="reset_image" value="Reset Drawing"/&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Note that the color palette below the Canvas has been implemented<br />
    using <code>&lt;input&gt;</code> buttons, which are styled with CSS<br />
    to be the appropriate color and size. The image below displays the page in Chrome for<br />
    Mac.</p>
<p class="image-box-580">
<a href="http://s.radar.oreilly.com/2011/11/11/1111-finger-painting1-lg.png"><img src="http://s.radar.oreilly.com/2011/11/11/1111-finger-painting1.png" border="0" width="580" alt="Finger painting interface in Google Chrome" style="margin-bottom: 15px" /></a><br />Finger painting interface in Google Chrome (<a href="http://s.radar.oreilly.com/2011/11/11/1111-finger-painting1-lg.png">click to enlarge</a>).</p>
<p>In order for the user to be able to draw on the screen, we&#8217;ll need<br />
    to be able to track his cursor motions and clicks within the Canvas. We<br />
    can do so by adding event listeners to the <code>&lt;canvas&gt;</code> element as follows:</p>
<pre>
theCanvas.addEventListener('mousedown', mouse_pressed_down, false);
theCanvas.addEventListener('mousemove', mouse_moved, false);
theCanvas.addEventListener('mouseup', mouse_released, false);</pre>
<p>Now when a user presses down on the mouse within the<br />
    <code>&lt;canvas&gt;</code>, a <code>mousemove</code> event is<br />
    triggered in the browser, and our event listener calls the<br />
    <code>mouse_pressed_down</code> function. Similarly, when the mouse<br />
    is moved within the dimensions of the Canvas, the<br />
    <code>mouse_moved</code> function is called, and when the mouse<br />
    button is released, the <code>mouse_released</code> function is<br />
    called. Let&#8217;s take a look at these three functions:</p>
<pre>
    function mouse_pressed_down (ev) {
    begin_drawing = true;
    context.fillStyle = colorChosen.innerHTML;
}

function mouse_moved (ev) {
    var x, y;
    <em><span class="lineannotation">// Get the mouse position in the canvas</span></em>
    x = ev.pageX;
    y = ev.pageY;

    if (begin_drawing) {
        context.beginPath();
        context.arc(x, y, 7, (Math.PI/180)*0, (Math.PI/180)*360, false);
        context.fill();
        context.closePath();
    }
}

function mouse_released (ev) {
   begin_drawing = false;
}</pre>
<p>The <code>mouse_pressed_down</code> function serves to &#8220;turn<br />
    on&#8221; a drawing event on the canvas. It sets the variable<br />
    <code>begin_drawing</code> to <code>true</code>, and then sets<br />
    the fill color to be used to the current color selected from the color<br />
    palette.</p>
<p>Then when the <code>mouse_moved</code> function is called<br />
    (which occurs any time the mouse is moved somewhere within the Canvas), we<br />
    get the cursor&#8217;s coordinates using the<br />
    <code>pageX</code>/<code>pageY</code> properties. We check if<br />
    the <code>begin_drawing</code> variable is set to<br />
    <code>true</code>, which means that the user has the mouse button<br />
    pressed down, and if so, we draw a circle of the designated color with a<br />
    radius of 7 pixels at the cursor location.</p>
<p>As long as the mouse button is held down while the mouse is moved<br />
    over the Canvas, the <code>mouse_moved</code> function will be<br />
    called every single time the cursor location changes, which means that<br />
    circles will continue to be drawn as the mouse moves, resulting in an<br />
    effect quite similar to the Paintbrush tool in many image-editing<br />
    applications.</p>
<p>When the mouse button is released, the<br />
    <code>begin_drawing</code> variable is set back to<br />
    <code>false</code>, which &#8220;turns off&#8221; the drawing event. This<br />
    ensures that drawing occurs only when the mouse is held down, and not when<br />
    the mouse is moved over the Canvas without the button being<br />
    pressed.</p>
<p>The above code works great on desktop and laptop browsers, where a<br />
    mouse is used to interface with screen elements, but what about<br />
    touchscreen devices like the iPad? In general, touchscreen browsers do not<br />
    support<br />
    <code>mousedown</code>/<code>mousemove</code>/<code>mouseup</code><br />
    events, as there is no mouse button or mouse cursor that they can track;<br />
    all those features are replaced with finger taps and swipes. However,<br />
    <a class="ulink" href="http://www.webkit.org/">WebKit</a>-based browsers support<br />
    a corresponding set of events for tracking finger motions in the browser:<br />
    <code>touchstart</code>/<code>touchend</code>/<code>touchmove</code>.<br />
    So we can implement the same drawing functionality as above using a<br />
    <code>touchmove</code> event listener:</p>
<pre>theCanvas.addEventListener('touchmove', touch_move_gesture, false);</pre>
<p>And the following <code>touch_move_gesture</code><br />
    function:</p>
<pre>function touch_move_gesture (ev) {
    <em><span class="lineannotation">// For touchscreen browsers/readers that support touchmove</span></em>
    var x, y;
    context.beginPath();
    context.fillStyle = colorChosen.innerHTML;
    if(ev.touches.length == 1){
        var touch = ev.touches[0];
        x = touch.pageX;
        y = touch.pageY;
        context.arc(x, y, 7, (Math.PI/180)*0, (Math.PI/180)*360, false);
        context.fill();
    }
}</pre>
<p>(Note: The <code>touchmove</code> handling for touchscreen devices<br />
      is actually much simpler than the mouse-based version, because we don&#8217;t<br />
      even need to track <code>touchstart</code> and<br />
      <code>touchend</code> events. When dealing with a mouse, we need<br />
      to keep track of whether the mouse button is pressed or not when it&#8217;s<br />
      being moved on the canvas. In the touch version, we know that if the<br />
      <code>touchmove</code> event has been triggered, the user has his<br />
      finger on the screen and is intending to draw.)</p>
<p>And that&#8217;s the meat of the finger painting code. All that&#8217;s left is<br />
    the code to initialize the event listeners, track color palette<br />
    selections, and implement the Reset Drawing button functionality. The example below shows the full JavaScript code for our<br />
    finger painting application. (The finger painting JavaScript code <a class="ulink" href="https://github.com/sandersk/HTML5-for-Publishers/blob/master/finger_painting/finger_painting.js">can be downloaded here</a>.)</p>
<pre>
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() {
    canvasApp();
}

function canvasSupport () {
    return Modernizr.canvas;
}


function canvasApp(){
    if (!canvasSupport()) {
        return;
    }else{
        var theCanvas = document.getElementById('canvas');
        var context = theCanvas.getContext('2d');
        var redButton = document.getElementById("Red");
        var orangeButton = document.getElementById("Orange");
        var yellowButton = document.getElementById("Yellow");
        var greenButton = document.getElementById("Green");
        var blueButton = document.getElementById("Blue");
        var purpleButton = document.getElementById("Purple");
        var brownButton = document.getElementById("Brown");
        var blackButton = document.getElementById("Black");
        var whiteButton = document.getElementById("White");
        var colorChosen = document.getElementById("color_chosen");
        var resetButton = document.getElementById("reset_image");
        redButton.addEventListener('click', colorPressed, false);
        orangeButton.addEventListener('click', colorPressed, false);
        yellowButton.addEventListener('click', colorPressed, false);
        greenButton.addEventListener('click', colorPressed, false);
        blueButton.addEventListener('click', colorPressed, false);
        purpleButton.addEventListener('click', colorPressed, false);
        brownButton.addEventListener('click', colorPressed, false);
        blackButton.addEventListener('click', colorPressed, false);
        whiteButton.addEventListener('click', colorPressed, false);
        resetButton.addEventListener('click', resetPressed, false);
        drawScreen();
    }

    function drawScreen() {
        theCanvas.addEventListener('mousedown', mouse_pressed_down, false);
        theCanvas.addEventListener('mousemove', mouse_moved, false);
        theCanvas.addEventListener('mouseup', mouse_released, false);
        theCanvas.addEventListener('touchmove', touch_move_gesture, false);
        context.fillStyle = 'white';
        context.fillRect(0, 0, theCanvas.width, theCanvas.height);
        context.strokeStyle = '#000000';
        context.strokeRect(1,  1, theCanvas.width-2, theCanvas.height-2);
    }

    // For the mouse_moved event handler.
    var begin_drawing = false;

    function mouse_pressed_down (ev) {
        begin_drawing = true;
        context.fillStyle = colorChosen.innerHTML;
    }

    function mouse_moved (ev) {
        var x, y;
        // Get the mouse position in the canvas
        x = ev.pageX;
        y = ev.pageY;

        if (begin_drawing) {
            context.beginPath();
            context.arc(x, y, 7, (Math.PI/180)*0, (Math.PI/180)*360, false);
            context.fill();
            context.closePath();
        }
    }

    function mouse_released (ev) {
        begin_drawing = false;
    }

    function touch_move_gesture (ev) {
        // For touchscreen browsers/readers that support touchmove
        var x, y;
        context.beginPath();
        context.fillStyle = colorChosen.innerHTML;
        if(ev.touches.length == 1){
            var touch = ev.touches[0];
            x = touch.pageX;
            y = touch.pageY;
            context.arc(x, y, 7, (Math.PI/180)*0, (Math.PI/180)*360, false);
            context.fill();
        }
    }

    function colorPressed(e) {
        var color_button_selected = e.target;
        var color_id = color_button_selected.getAttribute('id');
        colorChosen.innerHTML = color_id;
    }

    function resetPressed(e) {
        theCanvas.width = theCanvas.width; // Reset grid
        drawScreen();
    }
}</pre>
<p>You can experiment with the Finger Painting app <a class="ulink" href="http://examples.oreilly.com/0636920022473/finger_painting/finger_painting.html">on examples.oreilly.com</a>. The image below shows a completed drawing in the Finger Painting app in the iBooks reader for iPad.</p>
<div align="center">
<p class="image-box-300">
<img src="http://s.radar.oreilly.com/2011/11/11/1111-finger-painting2.png" border="0" width="300" alt="Author self-portrait in Finger Painting app in iBook" style="margin-bottom: 15px" /></a><br />Author self-portrait in Finger Painting app in iBook.</p>
</div>
<p>Pretty cool, right? Although maybe not as impressive as what you can do in some <a class="ulink" href="http://www.hongkiat.com/blog/beautiful-ipad-fingerpaint-piece-de-resistance/">other touchscreen finger painting apps</a>.</p>
<div style="float: left;border-top: thin gray solid;border-bottom: thin gray solid;padding: 20px;margin: 20px 2px;clear: both"><a href="http://shop.oreilly.com/product/0636920022473.do?cmp=il-radar-ebooks-html5-finger-painting-example"><img style="float: left;border: none;padding-right: 10px" src="http://s.radar.oreilly.com/2011/11/11/1111-html5-for-publishers-cover.png" /></a><a href="http://shop.oreilly.com/product/0636920022473.do?cmp=il-radar-ebooks-html5-finger-painting-example"><strong>HTML5 for Publishers</strong></a> &mdash;  This free ebook provides an overview of some of the most exciting features HTML5 provides to ebook content creators &mdash; audio/video, geolocation, and the Canvas &mdash; and shows how to put them in action.</div>
<p><strong>Related:</strong></p>
<ul>
<li> <a href="http://shop.oreilly.com/product/0636920022473.do">HTML5 for publishers</a> (free ebook)</li>
<li> <a href="http://radar.oreilly.com/2011/07/what-is-html5.html">What is HTML5?</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://radar.oreilly.com/2011/11/html5-for-publishers-canvas.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
