Friday 13 September 2013

Adding plugin for static canvas

 Overview

In this tutorial we will learn how to create plugin for the static layer. The example described in this tutorial will allow you to create a blur brush. You can use the plugin attached with this tutorial by following the steps described in overview tutorial http://paindoodlerplugindev.blogspot.co.uk/2013/05/overview.html. You can unzip the file to understand the contents.


Prerequisite

  1. Basic understanding of paint doodler interface http://paintdoodler.blogspot.co.uk/p/paint-doodler-user-interface.html
  2. Basic understanding of the paint doodler drawing layer architecture http://paintdoodler.blogspot.co.uk/p/layer.html
  3. Paint doodler plugin overview http://paindoodlerplugindev.blogspot.co.uk/2013/05/overview.html
  4. Basic understanding of HTML 5 canvas image manipulation. This tutorial used a pixel by pixel manipulation of the underlying image.
  5. Basic understanding of java script.

Components of the blur brush plugin

  1. tools.txt -  Used to associate an icon to plugin on toolbox  http://www.paintdoodler.com/plugins/blurbrushpaintdoodlertutorial/tools.txt
  2.  setUpUIPaintDoodlerTutorial function attached to onclick event of the tool bar icon is used to initialize and start the plugin.
  3. control.txt - Used to define input controls for plugin. Initialized and opened using the function setUpUIPaintDoodlerTutorial attached to onclick event   http://www.paintdoodler.com/plugins/blurbrushpaintdoodlertutorial/control.txt
  4. js.txt - Script file containing the plugin code   http://www.paintdoodler.com/plugins/blurbrushpaintdoodlertutorial/js.txt

Attaching /Initializing new plugin to existing static canvas layer plugins

// function to associate plugin to static canvas layer
function initializeBlurBrushPluginPaintDoodlerTutorial(){
    //canvasList global variable to contain the list of existing canvas layers names
    //Associated plugin to static cavas layer by checking the type property of canvaslayer
    for (var i = canvasList.length - 1; i >= 0; i--) {
        if (canvasMap[canvasList[i]].type == 'static' && typeof canvasMap[canvasList[i]].drawingStyle['blurbrushpaintdoodlertutorial'] == 'undefined' ) {
        //drawingstyle map of plugins attached to current static layer. Please note that toolShape variable should be initialized with key ('blurbrushpaintdoodlertutorial') see below
          //canvasMap global variable containing list of canvasLayerObject
          canvasMap[canvasList[i]].drawingStyle['blurbrushpaintdoodlertutorial'] = new BlurBrushPaintDoodlerTutorial(canvasMap[canvasList[i]].ctx) ;
        }
    }
}
// function associated to onclick event associated to toolbar icon
function setUpUIPaintDoodlerTutorial(){
    //hide any controls if already open
    hideControls('control');
    //show control associated to blur brush plugin
   document.getElementById('blurBrushPaintDoodlerTutorialControl').style.display='';
    //attach the plugin to static canvas layer
    initializeBlurBrushPluginPaintDoodlerTutorial();
    //toolShape a global variable to describe which plug in should be used. Please note the string in toolshape should be same as string used to attach plugin to drawingStyle
    toolShape='blurbrushpaintdoodlertutorial';
  //open ControlBox to open the controls
     openControlBox();
}
Construction function
We start creating the plugin by defining a prototype construction function as below
Prototype constructor must pass an argument context
//plugin prototype constructor function
function BlurBrushPaintDoodlerTutorial(context) {
    //HTML 5 canvas context passed during attach plugin proceess by getting the context associated to canvas layer using canvasMap see above for plugin initialization
    this.context = context;
    //boolean flag to describe if enable and cancel drawing using this plugin
    this.shouldDraw = false;
    //copy of the pixel data of the underlying canvas layer
    this.srcIData =null;


}
Attaching to mouse and touch events
Prototype constructed above must have following methods with same method signatures as defined below
  1. strokeStart
  2. draw
  3. strokeEnd
//prototype function called on touch start or mouse down event mouseX and MouseY contain the current co-ordinates of the mouse pointer on the underlying canvas layer
BlurBrushPaintDoodlerTutorial.prototype.strokeStart = function(mouseX, mouseY) {
    //take a copy of the canvas layer pixel data
    this.srcIData =this.context.getImageData(0,0,canvasWidth,canvasHeight);
    this.shouldDraw = true;
}
//prototype function called on touch move or mouse move event
BlurBrushPaintDoodlerTutorial.prototype.draw = function(mouseX, mouseY) {

    var srcIDataCopy =this.context.getImageData(0,0,canvasWidth,canvasHeight);
    var data = this.srcIData.data;
    var dataCopy=srcIDataCopy.data;
    //size of drawing brush
    var sizeelm=document.getElementById('blurbrushpaintdoodlertutorialsize');

    if (typeof sizeelm =='undefined'){
        return;
    }
    var size = parseInt(sizeelm.value);
    var countPixels=0;
    var rmean,gmean,bmean;
    rmean=0;
    gmean=0;
    bmean=0;
    //iterate through the pixels under drawing brush
    for(var x = mouseX-size/2; x < mouseX+size/2; x++) {
        for(var y = mouseY-size/2; y < mouseY+size/2; y++) {
            if (x<0||y<0||x>=canvasWidth||y>=canvasHeight){


            }   else{
                countPixels++;
                rmean=rmean+data[((canvasWidth * y) + x) * 4 + 0];
                gmean=gmean+data[((canvasWidth * y) + x) * 4 + 1];
                bmean=bmean+data[((canvasWidth * y) + x) * 4 + 2];
            }
        }
    }
    //replace the canvas data with the average value of the surrounding pxel
    dataCopy[((canvasWidth * mouseY) + mouseX) * 4 + 0]=rmean/countPixels;
    dataCopy[((canvasWidth * mouseY) + mouseX) * 4 + 1]=gmean/countPixels;
    dataCopy[((canvasWidth * mouseY) + mouseX) * 4 + 2]=bmean/countPixels;
    //replace the canvas data with the manipulated pixel data
    this.context.putImageData(srcIDataCopy,0,0);


}
//prototype function called on touch end or mouse up event
BlurBrushPaintDoodlerTutorial.prototype.strokeEnd = function() {
    this.shouldDraw = false;
}

Note

  1. paintdoodlertutorial is added at the end of each method variable to create a unique name. It is the responsibility of developer to create unique names so that it does not conflicts with other plugin names and is globally unique
This post is part of series plugin development tutorial series for Paint Doodler app.

This is the official blog for paint doodler app
Online painting,drawing and image editing platform . paint doodler is based html5 canvas and is purely java script diven
Doodle Paint is a full featured painting and image editing platform providing users with versatile collection of tools and enabling users to contribute to ever growing community of doodlers with new features through plug-in.
visit - http://www.paintdoodler.com/

Monday 13 May 2013

Overview

Uploading Plugin

In order to upload a plugin
Step 1 - Go to File|Plugin.
Step 2 - Select you zipped file with the plugin.
Step 3 - Click on the upload button.

Plugin will be uploaded and browser will be refreshed to include the requested changes.

Delete Plugin

In order to delete a plugin
Step 1 - Go to File|Plugin.
Step 2 - Select your  plugin it should be highlighted with yellow color.
Step 3 - Click on the delete button.
Plugin will be removed from the paint doodler  app after the page refresh.

Creating Plugin

 Create a zip file with following files. Please ensure that the file names are as specified below
Following is the list of mandatory files for the plugin

  • info.txt
  • js.txt
  • tools.txt
Following is the list of optional files for the plugin
  • control.txt
  • stylesheet.txt

Contents of info.txt

Sample content of info.txt can should be as follows
name=<your plugin name>
shortDescription=<Your plugin description>
url=<URL to your page>

Content of js.txt

A sample java script file could look like following. The content of this file will be read and placed under the <head></head> section of the app page.
<script>
function myFunction()
{
document.write("hello world")
}
</script>

Content of tools.txt

Sample content of tools page could like follows. The content of this page will be used to create the toolbox. Clickng the added icon will call the myFunction defined in js.txt. If you are not familiar with the Paint doodler user interface kindly refer to blog page at 
To use an image/icon in toolbar we are using base64 encoded image.
<tr><td colspan=2><img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGwAAABsCAYAAACPZlfNAAAAAXNSR0ICQMB9xQAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUATWljcm9zb2Z0IE9mZmljZX/tNXEAAAMaSURBVHja7dwhcMIwFMbxyMnJSeQkcnJyshKJRCIni5qsnEROTiKRyEkkchKJZO2N7UovL023Ql+SP3ff3a5wXMNvlNf0NcYYcyRBhQ8BMAIYAQwwAhgBDDACGAEMMBIE2GKxMKS/AAYYYIARwAADDDACmO0DuC/zAFg4YKsyH4AFAFY+stq+TgFTDFY+bsp81va1+vsGML0DLyz7mwOmc9DjMgfL/lbb7gDTN+i1Y5+XgOka8MRjv8eA6RjsbaPQkLIBTG+hISUDbPhCo8u+7zSW+SmBbf4w2Dlgwwxy+sd+iL22Mj96sA6FhpQCsOsO8LWHziM1ZX7UYI5C43AqKprbpW/iO2DXGdyHsF8vwmxHtX2rucyPFqx8zFzlugCTNy651KPimlmUYFVl5zi8ZafX7KTZesdc4+Blfqxgr22/RS1g0m9f9U9wC1j/3y6p0Bj5gJ2eXwrvkwN2ncowb7zOBjZrwNuuma0B639Q67Z5QQFs2nhNbqskAbvMYfGnpF/afnd8wCxo66EnhFPu6fACqx1mVfQupgx28AVjLlHvwAEDDDDAAPvNE2BhDfwRMMAAAyy9Vu0RYIABBhhggEUGdg9YWGAjwAADDLD0wB4B09UiMDm1pO1tXU5dwKorzeZ78ZXCKLiTJdauqYPUDdUFzNI9vKOno/8B2Tqdzu7z8gEz32tQ2doIJoD1OyCpp75oA2u8z0rjNbMYwZpLEtU7f8c+YEa+IWLLIfEyg5obR2+9C8wBruKKdLRlvZHvDctawF5My40UgF1mYNJhrYKcCs+NjfI1qKI+ca6+FQ4023bpvrBnTpyvd052/GcGLzSSmpoy3ZYrUt/6lgKYdJ+XT9SsHpDU5K+jzHdF5WKXqYC5zq2O2guNJC+vOMp8qYpUuWBzUtfDHOV8MM04qYH5lPlvWrGSA2s5mVZbaKQO5irz55qxkgRznEyrLTQAs5f5aguN5MEsJ9OqCw3Azst89YUGYOcn0+oLDcACDmCAAQYYAQwwwAAjgAEGGGAEMMBIOOFDAIwARgADjABGAAOMAEYAA4wMkS8PspERTFkqgQAAAABJRU5ErkJggg==" onClick ="myFunction()"/></td></tr>

Content of this page will be read and added to html used to create toolbox. Skeleton code for tool box is shown below.
 <div id="draggabletool" class="ui-widget-content showtooltip">
                            <table>
</table>

Global Variables

Getting access to canvas layers are standard HTML5 canvas element. You can get the ordered list of document is using the java script global variable canvasList (Array). All the global variables are defined in file http://www.paintdoodler.com/design/js/windowload.js

Top Menu

If you need to change any element under top menu, you can access the HTML code for the top menu at Top Menu and  use java script to modify.

Please note at the moment we are allowing use of single plugin file. It is for in order to keep the storage space in control.  It is not a limitation and in near future we will open it to as many plugin as you want.

Do email us at admin@paintdoodler.com to increase the number allowed plugin and we will increase it on a case by case basis.Decision of the pant doodler admin in this regard will be final.

Plugins and tutorials

Adding plugin for static canvas -  http://paindoodlerplugindev.blogspot.co.uk/2013/09/adding-plugin-for-static-canvas.html

This post is part of series plugin development tutorial series for Paint Doodler app.

This is the official blog for paint doodler app
Online painting,drawing and image editing platform . paint doodler is based html5 canvas and is purely java script diven
Doodle Paint is a full featured painting and image editing platform providing users with versatile collection of tools and enabling users to contribute to ever growing community of doodlers with new features through plug-in.
visit - http://www.paintdoodler.com/