1 /*
  2  * © 2009 ROBO Design
  3  * http://www.robodesign.ro
  4  *
  5  * $Date: 2009-04-21 14:31:15 +0300 $
  6  */
  7 
  8 /**
  9  * @author <a lang="ro" href="http://www.robodesign.ro/mihai">Mihai Şucan</a>
 10  * @fileOverview The paint application core code.
 11  */
 12 
 13 /**
 14  * @class The paint tool application object.
 15  */
 16 function Painter () {
 17   var _self = this;
 18 
 19   /**
 20    * Holds the buffer canvas and context references.
 21    * @type Object
 22    */
 23   this.buffer = {canvas: null, context: null};
 24 
 25   /**
 26    * Holds the current layer ID, canvas and context references.
 27    * @type Object
 28    */
 29   this.layer = {id: null, canvas: null, context: null};
 30 
 31   /**
 32    * The instance of the active tool object.
 33    *
 34    * @type Object
 35    * @see Painter#tool_default holds the ID of the tool which is activated when 
 36    * the application loads.
 37    * @see PaintTools The object which holds the implementation of each drawing 
 38    * tool.
 39    */
 40   this.tool = null;
 41 
 42   /**
 43    * The default tool ID.
 44    *
 45    * @type String
 46    * @see PaintTools The object which holds the implementation of each drawing 
 47    * tool.
 48    */
 49   this.tool_default = 'line';
 50 
 51   /**
 52    * Initialize the paint application.
 53    * @private
 54    */
 55   function init () {
 56     if (!window.lang) {
 57       alert('Error: The language object is not available!');
 58       return;
 59     }
 60 
 61     if (!window.PaintTools) {
 62       alert(lang.PaintToolsNotFound);
 63       return;
 64     }
 65 
 66     // This application does not yet implement layers support.
 67     // However, there's only little additional work to be done for layers 
 68     // support.
 69     _self.layer.id = 1;
 70 
 71     // Find the canvas element.
 72     _self.layer.canvas = document.getElementById('imageLayer');
 73     if (!_self.layer.canvas) {
 74       alert(lang.errorCanvasNotFound);
 75       return;
 76     }
 77 
 78     if (!_self.layer.canvas.getContext) {
 79       alert(lang.errorGetContext);
 80       return;
 81     }
 82 
 83     // Get the 2D canvas context.
 84     _self.layer.context = _self.layer.canvas.getContext('2d');
 85     if (!_self.layer.context) {
 86       alert(lang.errorGetContext);
 87       return;
 88     }
 89 
 90     // Add the buffer canvas.
 91     var container = _self.layer.canvas.parentNode;
 92     _self.buffer.canvas = document.createElement('canvas');
 93     if (!_self.buffer.canvas) {
 94       alert(lang.errorCanvasCreate);
 95       return;
 96     }
 97 
 98     _self.buffer.canvas.id     = 'imageBuffer';
 99     _self.buffer.canvas.width  = _self.layer.canvas.width;
100     _self.buffer.canvas.height = _self.layer.canvas.height;
101     container.appendChild(_self.buffer.canvas);
102 
103     _self.buffer.context = _self.buffer.canvas.getContext('2d');
104 
105     // Get the tools drop-down.
106     var tool_select = document.getElementById('tool');
107     if (!tool_select) {
108       alert(lang.errorToolSelect);
109       return;
110     }
111     tool_select.addEventListener('change', ev_tool_change, false);
112 
113     // Activate the default tool.
114     if (PaintTools[_self.tool_default]) {
115       _self.tool = new PaintTools[_self.tool_default](_self);
116       tool_select.value = _self.tool_default;
117     }
118 
119     // Attach the mousedown, mousemove and mouseup event listeners.
120     _self.buffer.canvas.addEventListener('mousedown', ev_canvas, false);
121     _self.buffer.canvas.addEventListener('mousemove', ev_canvas, false);
122     _self.buffer.canvas.addEventListener('mouseup',   ev_canvas, false);
123   };
124 
125   /**
126    * The Canvas event handler.
127    * 
128    * <p>This method determines the mouse position relative to the canvas 
129    * element, after which it invokes the method of the currently active tool 
130    * with the same name as the current event type. For example, for the 
131    * <code>mousedown</code> event the <code><var>tool</var>.mousedown()</code> 
132    * method is invoked.
133    *
134    * <p>The mouse coordinates are added to the <var>ev</var> DOM Event object: 
135    * <var>ev.x_</var> and <var>ev.y_</var>.
136    *
137    * @private
138    * @param {Event} ev The DOM Event object.
139    */
140   function ev_canvas (ev) {
141     if (typeof ev.layerX != 'undefined') { // Firefox
142       ev.x_ = ev.layerX;
143       ev.y_ = ev.layerY;
144     } else if (typeof ev.offsetX != 'undefined') { // Opera
145       ev.x_ = ev.offsetX;
146       ev.y_ = ev.offsetY;
147     }
148 
149     // Call the event handler of the active tool.
150     var func = _self.tool[ev.type];
151     if (typeof func == 'function') {
152       func(ev);
153     }
154   };
155 
156   /**
157    * The event handler for any changes made to the tool selector.
158    * @private
159    */
160   function ev_tool_change () {
161     if (PaintTools[this.value]) {
162       _self.tool = new PaintTools[this.value](_self);
163     }
164   };
165 
166   /**
167    * This method draws the buffer canvas on top of the current image layer, 
168    * after which the buffer is cleared. This function is called each time when 
169    * the user completes a drawing operation.
170    */
171   this.layerUpdate = function () {
172 		_self.layer.context.drawImage(_self.buffer.canvas, 0, 0);
173 		_self.buffer.context.clearRect(0, 0, _self.buffer.canvas.width, _self.buffer.canvas.height);
174   };
175 
176   init();
177 };
178 
179 if(window.addEventListener) {
180 window.addEventListener('load', function () {
181   if (window.Painter) {
182     // Create a Painter object instance.
183     window.PainterInstance = new Painter();
184   }
185 }, false); }
186 
187 // vim:set spell spl=en fo=wan1croql tw=80 ts=2 sw=2 sts=2 sta et ai cin fenc=utf-8 ff=unix:
188