Posted By

jatkins on 05/22/12


Tagged

image library graphics Drawing


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

hurcy


2D Graphics Library (work in progress)


 / Published in: JavaScript
 

Released into the public domain

  1. Object.prototype.extend = function(ns_string) { // original version from http://addyosmani.com/blog/essential-js-namespacing/
  2. var parts = ns_string.split('.'), parent = this, i;
  3. for(i=0;i<parts.length;i++) {
  4. if(typeof parent[parts[i]]=='undefined')
  5. parent[parts[i]] = {};
  6. parent = parent[parts[i]];
  7. }
  8. return parent;
  9. }
  10.  
  11. if(!Object.keys) Object.keys = function(o) { // from http://tokenposts.blogspot.com.au/2012/04/javascript-objectkeys-browser.html
  12. if(o!==Object(o))
  13. throw new TypeError('Object.keys called on a non-object');
  14. var k = [], p;
  15. for (p in o) {
  16. if(Object.prototype.hasOwnProperty.call(o,p))
  17. k.push(p);
  18. }
  19. return k;
  20. }
  21.  
  22. // draw object released into the public domain by josh atkins (2012)
  23.  
  24. var draw = {}; // use a single global variable
  25.  
  26. draw.init = function() {
  27. draw.extend('misc.str.clean');
  28. draw.extend('misc.math.pythagoras');
  29. draw.extend('misc.js.loadScript');
  30.  
  31. // miscellaneous functions
  32. // str
  33. draw.misc.str.clean = function(strToClean) {
  34. return strToClean.replace(/[\.]{2,}/g, '.').replace(/\<[^\>]+?>/g, '');
  35. };
  36.  
  37. // math
  38. draw.misc.math.pythagoras = function(length1, length2) {
  39. return Math.sqrt(Math.pow(length1, 2)+Math.pow(length2, 2));
  40. }
  41. draw.misc.math.distanceBetweenTwoPoints = function(point1, point2) {
  42. return this.pythagoras(Math.abs(point2.xPos-point1.xPos), Math.abs(point2.yPos-point1.yPos));
  43. }
  44.  
  45. // js
  46. draw.misc.js.loadScript = function(scriptName) {
  47. var newScript = document.createElement('script');
  48. newScript.type = 'text/javascript';
  49. newScript.src = 'assets/scripts/'+this.str.clean(scriptName)+'.js';
  50. document.body.appendChild(newScript);
  51. };
  52.  
  53. draw.canvas = function(id) {
  54. this.id = id;
  55. var canvasID = id;
  56.  
  57. // setup the canvas <div>
  58. var canvasDiv = document.createElement('div');
  59. canvasDiv.id = id;
  60. canvasDiv.className = 'canvas';
  61. document.body.appendChild(canvasDiv);
  62.  
  63. // setup a stylesheet for the canvas
  64. var canvasStyleSheet = document.createElement('style');
  65. canvasStyleSheet.type = 'text/css';
  66. document.body.appendChild(canvasStyleSheet);
  67. canvasStyleSheet = document.styleSheets[document.styleSheets.length-1];
  68.  
  69. // delete the reference to the canvas <div>
  70. canvasDiv = null;
  71. delete canvasDiv;
  72.  
  73. var renderPoint = function(xPos, yPos) {
  74. var newPoint = document.createElement('div');
  75. newPoint.style.left = xPos + 'px';
  76. newPoint.style.top = yPos + 'px';
  77. return newPoint;
  78. };
  79.  
  80. var renderLine = function(startPoint, endPoint, lineDiv) {
  81. var tempPoint, width, height, gradient, yIntercept, distance;
  82.  
  83. if(draw.misc.math.distanceBetweenTwoPoints(startPoint, {xPos: 0, yPos: 0})>draw.misc.math.distanceBetweenTwoPoints({xPos: 0, yPos: 0}, endPoint)) {
  84. tempPoint = startPoint;
  85. startPoint = endPoint;
  86. endPoint = tempPoint;
  87. }
  88.  
  89. width = Math.abs(endPoint.xPos - startPoint.xPos);
  90. height = Math.abs(endPoint.yPos - startPoint.yPos);
  91. gradient = (endPoint.yPos - startPoint.yPos) / (endPoint.xPos - startPoint.xPos);
  92.  
  93. yIntercept = endPoint.yPos - gradient * endPoint.xPos;
  94. distance = draw.misc.math.distanceBetweenTwoPoints(startPoint, endPoint);
  95.  
  96. var calcXCoord = function(yPos) {
  97. var xPos = (yPos - yIntercept) / gradient;
  98. return ((gradient == Infinity) || (Math.abs(xPos) == Infinity)) ? startPoint.xPos : xPos;
  99. };
  100. var calcYCoord = function(xPos) {
  101. return Math.abs(gradient) == Infinity ? startPoint.yPos : gradient * xPos + yIntercept;
  102. };
  103.  
  104. var i = 0, pointCount, switchPos = false;
  105. pointCount = width > height ? width : height;
  106.  
  107. if(width>height) {
  108. if(endPoint.xPos<startPoint.xPos)
  109. switchPos = true;
  110. }
  111. else {
  112. if(endPoint.yPos<startPoint.yPos)
  113. switchPos = true;
  114. }
  115.  
  116. while(i<pointCount) {
  117. if(width>height)
  118. lineDiv.appendChild(renderPoint(parseInt((switchPos?endPoint:startPoint).xPos)+i, calcYCoord(parseInt((switchPos?endPoint:startPoint).xPos)+i)));
  119. else
  120. lineDiv.appendChild(renderPoint(calcXCoord(parseInt((switchPos?endPoint:startPoint).yPos)+i), parseInt((switchPos?endPoint:startPoint).yPos)+i));
  121. i++;
  122. }
  123. };
  124.  
  125. // define (artificial) constants
  126. var BORDER_STYLE = {
  127. DEFAULT: 1
  128. };
  129.  
  130. this.pen = {
  131. width: 1,
  132. style: BORDER_STYLE.DEFAULT,
  133. color: '#000000'
  134. };
  135. var pen = this.pen;
  136.  
  137. var shapes = function() {
  138. var shape, objects = {};
  139.  
  140. shape = function(shapeNumber) {
  141. var shapeDiv = document.createElement('div'), shapeRule, ruleText;
  142. shapeDiv.id = 'shape'+shapeNumber;
  143. document.getElementById(canvasID).appendChild(shapeDiv);
  144.  
  145. ruleText = 'background: '+pen.color+'; height: '+pen.width+'px; width: '+pen.width+'px;';
  146.  
  147. if(canvasStyleSheet.insertRule) // NS/FF
  148. canvasStyleSheet.insertRule('div.canvas div#shape'+shapeNumber+' div { '+ruleText+' }');
  149. else if(canvasStyleSheet.addRule) // IE
  150. canvasStyleSheet.addRule('div.canvas div#shape'+shapeNumber+' div', ruleText);
  151.  
  152. return {
  153. shapeRule: shapeRule,
  154. shapeName: 'shape' + shapeNumber,
  155. style: {
  156. border: {
  157. width: pen.width,
  158. color: pen.color,
  159. style: pen.style
  160. }
  161. },
  162. points: new (function() {
  163. var point, objects = {};
  164.  
  165. point = function(pointNumber, xPos, yPos, linkedTo) {
  166. return {
  167. pointName: 'point' + pointNumber,
  168. xPos: xPos,
  169. yPos: yPos,
  170. linkedTo: linkedTo
  171. };
  172. };
  173.  
  174. return {
  175. list: function() {
  176. for(pointObject in objects)
  177. alert(objects[pointObject].pointName + ': ['+objects[pointObject].xPos+', '+objects[pointObject].yPos+']');
  178. },
  179. add: function(xPos, yPos, linkedTo) {
  180. var newPoint = new point(Object.keys(objects).length, xPos, yPos, linkedTo);
  181. objects[newPoint.pointName] = newPoint;
  182.  
  183. if(linkedTo)
  184. renderLine(newPoint, linkedTo, shapeDiv);
  185.  
  186. return newPoint;
  187. },
  188. remove: function(pointOrName) {
  189. var pointToRemove;
  190.  
  191. if(typeof pointOrName == 'string')
  192. pointToRemove = pointOrName;
  193. else
  194. pointToRemove = pointOrName.pointName;
  195.  
  196. delete objects[pointToRemove];
  197. delete pointToRemove;
  198. }
  199. };
  200. })
  201. };
  202. };
  203.  
  204. return {
  205. list: function() {
  206. for(shapeObject in objects)
  207. alert(objects[shapeObject].shapeName);
  208. },
  209. add: function() {
  210. var newShape = new shape(Object.keys(objects).length);
  211. objects[newShape.shapeName] = newShape;
  212.  
  213. return newShape;
  214. },
  215. remove: function(shapeOrName) {
  216. var shapeToRemove;
  217.  
  218. if(typeof shapeOrName == 'string')
  219. shapeToRemove = shapeOrName;
  220. else
  221. shapeToRemove = shapeOrName.shapeName;
  222.  
  223. // delete the stylesheet rule
  224.  
  225. delete objects[shapeToRemove];
  226. delete shapeToRemove;
  227. }
  228. };
  229. };
  230. this.shapes = new shapes;
  231. shapes = this.shapes;
  232.  
  233. this.scribbling = {
  234. currentScribble: null,
  235. previousPoint: null,
  236. begin: function() {
  237. this.enabled = true;
  238. this.currentScribble = shapes.add();
  239. return false;
  240. },
  241. scribble: function() {
  242. if(this.enabled)
  243. this.previousPoint = this.currentScribble.points.add((event.pageX - 16) || (event.clientX - 16), (event.pageY - 16) || (event.clientY - 16), this.previousPoint);
  244. },
  245. end: function() {
  246. this.currentScribble = null;
  247. this.previousPoint = null;
  248. this.enabled = false;
  249. return false;
  250. },
  251. enabled: false
  252. };
  253. }
  254.  
  255. draw.mainCanvas = new draw.canvas('mainCanvas');
  256.  
  257. draw.mainCanvas.pen.width = 5;
  258.  
  259. var shape1, shape2, shape1_point1, shape1_point2;
  260. shape1 = draw.mainCanvas.shapes.add();
  261. shape1.points.add(5, 10, shape1.points.add(20, 100));
  262.  
  263. draw.mainCanvas.pen.width = 15;
  264. draw.mainCanvas.pen.color = '#ffa500';
  265. }

Report this snippet  

You need to login to post a comment.