Record and Playback Drawing in HTML5 Canvas

A few months back I had created an application that recorded and played back drawings on HTML5 Canvas. For some time now I wanted to refactor the code in that application and create a reusable ‘component’ from it. Which is what I did this week.

Go ahead and try the demo first – Press ‘Record’ key below and then draw some strokes/lines in the box with the mouse (holding down left button). Once you are done, click Stop button. Click ‘Play’ button to play back the drawing you just drew. You can pause and resume too.


 

Interesting piece of code in this application is to record strokes. You would have observed that, when playing back the drawing, the component does not draw all strokes at once, but it plays them backs in the sequence you had drawn, maintaining the time line. To do this, I collect all the strokes that are drawn in a certain time interval (in this application, it is 100 millis) and create a linked list. Each collection (of strokes) in this linked list stores time elapsed from the start of the recording.

When playing back, I use time elapsed in the first collection to start drawing strokes. Each subsequent collection is drawn after the difference between time elapsed for that collection and the previous collection.

You can find all the code in this file. ‘RecordableDrawing’ is the object you would create by passing id of the canvas –

drawing = new RecordableDrawing("canvas1");

This object captures strokes and draws them. ‘Recording’ object handles time slotting each stroke and playing them back, as described above. ‘ActionsSet’ object contains collection of strokes and also time interval from the start of the recording.

If you want Mobile version of this component, created using JQueryMobile, then you can find the demo here. All objects/functions for drawing are defined in RecordableDrawing.js.

-Ram Kulkarni

Update :

See the updated version of code and example (with features to set stroke color and size) in my blog post Record and Playback Drawing in HTML5 Canvas – Part II

34 Replies to “Record and Playback Drawing in HTML5 Canvas”

  1. Hello Ram,

    This coding is totally different and distinguishing your code from other “frame set” recording methodologies implementation. It only saves the points and time-lapse information, which means a lot smaller in size for the same effect of recording and playing-back. Even though, I cannot understand every piece of your coding, it seems a great idea for hand-writing “whiteboard” application.

    Can you possibly provide a hint for saving the recording in a file and playing back at a later time?
    Thank you.
    Woogon

    1. In the application that I build using this code, I save and load recordings using JSON. Each recording contains chain of actions sets. Each action set contains array of actions. The approach I have taken is to create a copy of recording object with array of action sets (instead of linked list of actions sets), which contains array of actions. Then I simply call stringify method of JSON on the copy of recording object.

      Loading of recording is also similar. I read text from a file and call JSON.parse. This gives me recording object. Then I create linked list of actions sets from array of action sets.

      If I get time, I will update this example with save and load options, but that doesn’t seem possible very soon.

      1. hi ram, i have been trying to play with your code to run with different line width and color, but it seems that the configuration on top of recordableDrawing isn’t taking effect. I was able to change background color, but linewidth and drawingcolor never got applied. Could you try it on your end and see if it works?

      2. Dear mr. Kulkarni, The replay is wonderful! Please allow me to ask your advice in a matter that concerns many painters. Our files are trapped in a famous painting app for iPad called ‘Brushes’. Brushes (open source) uses a desktop ‘Brushes viewer’ that enables to replay brushstrokes and export paintings at 6x their size without loss of resolution. This wonderful feature is indispensable for printing. However the viewer doesn’t work and paintings can’t be printed. The issue exists for at least four years. Some artists have years of work in the app. We have history.json files and they seem o.k. The image container also has a file ‘image.json’ but this seems to have a syntax error. I don’t know anything about errors or programming (I suppose few painters do). How should we go about this? Could this problem be fixed? Do you know if it would be possible to use these files with some other program that allows a resize of the brushstrokes? Thank you for showing your work and provide a way to make contact.

    1. I did not test my blog post in Android Chrome. But when I did that after reading your comment, I see that mouse events are not captured by the Canvas but are propagated to Browser Window. That could be the reason why drawing does not work in Android browser.

      However I have used the code in a standalone Android application and it had worked fine. Unfortunately presently I don’t have enough time to debug this issue in Android Chrome.

  2. Could you package this in say a github or .zip file?

    I am going to try to implement this canvas drawing over a video and utilize audio recording!

    Thanks!

  3. Hi Ram, i mentioned about above code not work android chrome. But i noticed your mobile version and i used it. But it was good on chrome v34..v36 but now v39 bad. I read your answer. You said “I have used the code in a standalone Android application and it had worked fine. ” what do you mean stand alone android application. Can you explain. Thanks

    1. I had created an HTML5 Android app using the Canvas described in this post. It worked fine with Android WebView. It was a couple of years back. Haven’t tried that app with the latest Android WebView.

  4. hey there Ram – thanks for this blog post – truly helpful. I was trying to run your code provided here but i keep getting a blank result could you also provide link to your html code to jun your .js file. thanks

    1. Yes, it is possible. Inserting image in the Canvas should be easy. To record it, you will need to serialize this action. If an image is coming from a URL then you could serialize the URL, or you could convert the image to base64 and serialize it. Similarly deserializer would construct image either from a URL or base64 data.

  5. Hi Ram
    This is really awesome. I extend your library and add voice recording and image functionalities. Now I want to add image dragging and resize functionalities. please help me in this regard.

    Regards
    Aftab Aslam

  6. Hi Ram,

    This is totally awesome. I would like to add another button (ex: Rectangle) that would in turn perform the same functions but draw a rectangle. Can you help point me in the right direction?

    thank you!

    Wade

    1. Add a (toggle) button to select rectangle mode. You may need to add a state variable for this in the RecordableDrawing class/function. You will also need to add an action class for Rectangle, similar to the Point class which is already there. When rectangle mode is selected, on mouse down event, create a Rectangle action. Mouse move event will not create Point actions, but will probable just draw an outline of the rectangle (erase previous outline with the background color and draw a new one with current co-ordinates). On mouseup event set the final co-ordinates of the rectangle, add the rectangle action to current recording (if one exists) and draw the rectangle (you will need to add a case statement for rectangle in RecordableDrawing.drawAction).

  7. Superb i really enjoyed very much with this article here. Really its a amazing article i had ever read. I hope it will help a lot for all. Thank you so much for this amazing posts and please keep update like this excellent article.

  8. Awesome Work Ram ,
    how can i smooth drawing on canvas ? i tried QuadraticCurve but , it doesnt work , how can i draw like sketchtoy.com ?? it so importtant for me , pls help me , help us .

  9. sorry very bad at coding how do i connect my canvas with this drawing = new RecordableDrawing(“canvas1”) what is supposed to be the “drawing” ?

  10. Ram, I have a canvas stock chart which gets updated with new data points. How can I record the entire action going on in that canvas over time into a video which I can later save to aws and share a link. Any form of guidance would be helpful

  11. Very nice tutorial. But I have noticed something.

    1. When I’m playing back the recording after pausing, then the playback starts after few seconds, that is, the next element gets drawn after a while which was not the original case while drawing it.

    2. Is it possible to save the recording to db, then play it again later? If yes, then which objects of the recording should be saved and how?

Leave a Reply

Social