iphone scribble webapp

As already mentioned through twitter i’m playing around with the iphone and the canvas element to build a scribble webapp running on the device (and android devices as well). It should be possible to save/upload the scribbled image afterwards. Here’s a first code snippet

<!DOCTYPE html>

<html>
  <head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
    <script type="text/javascript" src="http://jasonkuhn.net/mobile/jqui/js/jquery.iphoneui.js"></script>

    <meta content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" name="viewport" />
    <meta charset="utf-8">
  </head>

  <body style="margin: 0; padding: 0; -webkit-text-size-adjust: none; padding-left: 10px; padding-top: 10px;">
    <button id="save" style="position: absolute; margin-left: 10px; margin-top: 10px;">save</button>

    <script type="text/javascript">
      $(document).ready(
        function() {
          $("body").append("<canvas id='canvas' style='border: 1px solid #000;'></canvas>");

          $("#canvas").attr("width", (window.innerWidth ? window.innerWidth : $(window).width()) - 20);
          $("#canvas").attr("height", (window.innerHeight ? window.innerHeight : $(window).height())- 20);

          $("#canvas").addTouch();

          var ctx = $("#canvas")[0].getContext("2d");

          ctx.lineCap = "round";
          ctx.lineWidth = 15;

          var start_x = null, start_y = null, drawing = false;

          $("#canvas").bind("mousedown",
            function(e) {
              drawing = true;

              start_x = e.pageX - $("#canvas").offset().left;
              start_y = e.pageY - $("#canvas").offset().top;
            }
          );

          $("#canvas").bind("mouseup",
            function(e) {
              drawing = false;
            }
          );

          $("#canvas").bind("mousemove",
            function(e) {
              if(!drawing)
                return;

              var x = e.pageX - $("#canvas").offset().left;
              var y = e.pageY - $("#canvas").offset().top;

              ctx.beginPath();
              ctx.moveTo(start_x, start_y);
              ctx.lineTo(x, y);
              ctx.stroke();

              e.preventDefault();

              start_x = x;
              start_y = y;
            }
          );

          $("#save").click(
            function() {
              var data = $("#canvas")[0].toDataURL("image/png").replace(/^[^,] ,/, "");

              $.ajax({
                 type: "post",
                 url: "/images/upload",
                 data: "image="   encodeURIComponent(data),
                 processData: false
              });
            }
          );
        }
      );
    </script>
  </body>
</html>

Step 1: Drawing

Drawing within the canvas is straight forward. We use mousedown, mouseup and mousemove to recognize the mouse events and draw lines between the coordinates.

Step 2: Upload

Uploading the the scribbled image is straight forward too, thanks canvas.toDataURL. toDataURL encodes the canvas using base64 what allows us to upload the encoded image using ajax or a form.

Of couse we need some server side processing. Using rails this could look like

class ImagesController < ApplicationController
  def upload
    open("#{RAILS_ROOT}/public/images/upload.png", "w") do |stream|
      stream.write decode64(params[:image])
     end 

    render(:update) { |page| page.alert("saved") }
  end
end

Step 3: Iphone

Thanks to this jquery plugin getting this to work on the iphone is as easy as including a javascript file. It translates the iphone’s javascript touch events (touchstart, touchmove, touchend) to mousedown, mouseup, mousemove, … if you addTouch() to the element.

That’s it. Maybe it’s worth to continue working on it and publishing it as a real project, because adding a scribble-webapp (within an iframe maybe?) could be a nice feature for many mobile webapps.

Leave a Reply

CAPTCHA Image Audio Version
Reload Image