Advertisement
Guest User

Untitled

a guest
Nov 2nd, 2017
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Declare global variables */
  2. var spacing = 18;
  3. var spacing_interior = spacing - 2;
  4. var canvas;
  5. var ctx;
  6. var line;
  7. var actions;
  8. var popup;
  9. var toolset_coord;
  10. var tool;
  11.  
  12.  
  13. //Handles when the user changes which tool they are using
  14. function toolChange() {
  15.   tool = document.getElementById("tool_select").value;
  16.  
  17.   if (tool == 'fill') {
  18.     document.getElementById("line_width_p").style.display = 'none';
  19.   } else {
  20.     document.getElementById("line_width_p").style.display = 'block';
  21.   }
  22.   //console.log("Changed tool to " + tool);
  23. }
  24.  
  25. //Handles file upload event
  26. function handleFileSelect(evt) {
  27.   console.log("Saw upload evt");
  28.  
  29.   var files = evt.target.files; // FileList object
  30.  
  31.   //Read the first file only, couldn't get the file picker to work without input being multiple. Will open as GitHub issue
  32.   var f = files[0];
  33.   var reader = new FileReader();
  34.  
  35.   reader.onload = (function(theFile) {
  36.     return function(e) {
  37.       actions.upload(e.target.result);
  38.  
  39.     };
  40.   })(f);
  41.  
  42.   reader.readAsText(f);
  43.  
  44. }
  45.  
  46. function roundQuarter(num) {
  47.   return Math.round(num * 4) / 4;
  48. }
  49.  
  50. function getDocumentPPI() {
  51.   var elem = document.createElement('div');
  52.   elem.style.width = '1in';
  53.   document.body.appendChild(elem);
  54.   var ppi = elem.offsetWidth;
  55.   //document.body.removeChild(elem);
  56.   return ppi;
  57. }
  58.  
  59. /* Called when everything is ready */
  60. function BodyLoad() {
  61.   /* Assign elements to variables */
  62.   popup = document.getElementById('popup');
  63.   canvas = document.getElementById('canvas');
  64.   toolset_coord = document.getElementById('coord');
  65.   tool = 'line';
  66.  
  67.   /* Set up the canvas context (ctx) */
  68.   ctx = canvas.getContext('2d');
  69.  
  70.   /* Set some canvas properties */
  71.   canvas.width = window.innerWidth;
  72.   canvas.height = window.innerHeight;
  73.   canvas.w = canvas.width; // short-hand
  74.   canvas.h = canvas.height; // short-hand
  75.   canvas.mousedown = false;
  76.  
  77.  
  78.   /* Update the coordinates in the toolset */
  79.   toolset_coord.update = function(x, y) {
  80.     this.innerHTML = roundQuarter(x / spacing) + ',' + roundQuarter(y / spacing);
  81.   }
  82.  
  83.  
  84.   /* For keeping up with what we've done */
  85.   actions = {
  86.     data: [], // empty on start
  87.     /* Store to the array */
  88.     save: function() { //Take whatever is saved in the drawing vars and write them to the next space in the array
  89.       t = tool;
  90.       if (t == "line") {
  91.         this.data[this.data.length] = {
  92.           x1: line.x1,
  93.           y1: line.y1,
  94.           x2: line.x2,
  95.           y2: line.y2,
  96.           type: 'line',
  97.           color: line.color,
  98.           width: line.width
  99.         }
  100.       } else if (t == "fill") {
  101.         this.data[this.data.length] = {
  102.           x: fill.x,
  103.           y: fill.y,
  104.           color: fill.color,
  105.           type: 'fill'
  106.         }
  107.       }
  108.       // Checking If browser Supports Local Storage, Then Save
  109.       if (typeof(Storage) !== "undefined") {
  110.         sessionStorage.setItem('data', JSON.stringify(this.data));
  111.       }
  112.       // console.log(this.data);
  113.     },
  114.     /* Loop through the array and re-draw lines */
  115.     restore: function() {
  116.  
  117.       for (var i = 0; i < this.data.length; i++) {
  118.         //do all the fills
  119.         if (this.data[i].type == 'fill') {
  120.           fill.draw(this.data[i].x, this.data[i].y, this.data[i].color, true);
  121.           //do all the lines
  122.         } else if (this.data[i].type == 'line') {
  123.           line.draw(this.data[i].x1, this.data[i].y1, this.data[i].x2, this.data[i].y2, 'restore', this.data[i].color, this.data[i].width);
  124.         }
  125.       }
  126.     },
  127.     /* Remove the last action */
  128.     undo: function() {
  129.       console.log("Removing from data array:\n" + JSON.stringify(this.data[this.data.length - 1]));
  130.       this.data.splice(this.data.length - 1, 1);
  131.       canvas.redraw();
  132.       //this.restore();
  133.     },
  134.     /* Wipe the slate clean */
  135.     purge: function() {
  136.       sessionStorage.clear();
  137.       for (var i = this.data.length; i > 0; i--)
  138.         this.undo();
  139.       // location.reload();
  140.     },
  141.     /* Export to PNG */
  142.     png: function() {
  143.       alert('This will open the image in a new window. Right-click and choose Save As to download the image.');
  144.       window.open(canvas.toDataURL('image/png'), 'Save as PNG');
  145.     },
  146.  
  147.     /* Download a txt file containing JSON that stores the drawing to be continued later */
  148.     download: function() {
  149.  
  150.       var uri = 'data:text;charset=utf-8,' + JSON.stringify(this.data);
  151.  
  152.       var downloadLink = document.createElement("a");
  153.       downloadLink.href = uri;
  154.       downloadLink.download = "paper.json";
  155.  
  156.       document.body.appendChild(downloadLink);
  157.       downloadLink.click();
  158.       document.body.removeChild(downloadLink);
  159.     },
  160.  
  161.     /* Load and draw new lines based on JSON text input, intended for use with file upload */
  162.     upload: function(inString) {
  163.       this.purge();
  164.       this.data = JSON.parse(inString);
  165.       console.log(this.data.length);
  166.       this.save();
  167.       this.restore();
  168.       console.log(this.data.length);
  169.     }
  170.   }
  171.  
  172.  
  173.   /* Draw lines with this */
  174.   line = {
  175.     snap: true, // Snap to grid is enabled by default // As of v2 this is probably unneeded
  176.     color: 'blue', // Default color is blue
  177.     width: 2, // Default width is 2
  178.     x1: 0,
  179.     y1: 0,
  180.     x2: 0,
  181.     y2: 0, // Default coordinates are all 0,0
  182.     /* Record our starting x,y */
  183.     start: function(x, y) {
  184.       this.x1 = this.snap_to_grid(x);
  185.       this.y1 = this.snap_to_grid(y);
  186.     },
  187.     /* Record our stopping x,y and draw */
  188.     stop: function(x, y) {
  189.       this.x2 = this.snap_to_grid(x);
  190.       this.y2 = this.snap_to_grid(y);
  191.  
  192.       this.draw(this.x1, this.y1, this.x2, this.y2, 'line');
  193.     },
  194.     /* Draw a line */
  195.     draw: function(x1, y1, x2, y2, type, color, width) {
  196.       if (x1 != x2 || y1 != y2) { //If the length of the line is nonzero
  197.         /* If we don't know what type, let's assume it's a plain old line */
  198.         if (type == undefined)
  199.           type = 'line';
  200.  
  201.         /* Only get the options if it's a plain old line */
  202.         if (type == 'line')
  203.           this.update_options();
  204.  
  205.         /* No color? It's this color! */
  206.         if (color == undefined)
  207.           ctx.strokeStyle = this.color;
  208.         else
  209.           ctx.strokeStyle = color;
  210.  
  211.         /* Even skinny people have width */
  212.         if (width == undefined)
  213.           ctx.lineWidth = this.width;
  214.         else
  215.           ctx.lineWidth = width;
  216.  
  217.         /* Draw the line */
  218.         ctx.beginPath(); // Set up the path
  219.         ctx.moveTo(x1, y1); // The start of the line
  220.         ctx.lineTo(x2, y2); // The end of the line
  221.         ctx.closePath(); // Close the path
  222.         ctx.stroke(); // Draw it
  223.  
  224.         /* If it's a plain line, save it and clean up and guide lines */
  225.         if (type == 'line') {
  226.           actions.save();
  227.           canvas.redraw();
  228.           actions.restore();
  229.         }
  230.       }
  231.     },
  232.     /* For drawing a handy guide line */
  233.     guide: function(x, y) {
  234.       this.update_options();
  235.  
  236.       canvas.redraw();
  237.       actions.restore();
  238.  
  239.       this.draw(this.x1, this.y1, this.snap_to_grid(x), this.snap_to_grid(y), 'guide');
  240.     },
  241.     /* Calculate the nearest snap point (calculated by spacing) */
  242.     snap_to_grid: function(p) {
  243.       var p2;
  244.  
  245.       for (var i = p - (spacing / 2); i < p + (spacing / 2); i++)
  246.         if (i % spacing == 0)
  247.           p2 = i;
  248.  
  249.       return p2;
  250.     },
  251.     /* Get all the set options from the toolset */
  252.     update_options: function() {
  253.       if (canvas.in_restore)
  254.         return false;
  255.  
  256.       this.color = document.getElementById('line_color').value;
  257.       this.width = document.getElementById('line_width').value;
  258.     }
  259.   }
  260.  
  261.   /* Fill tool, use this to fill boxes */
  262.   fill = {
  263.     color: 'black', // Default color is black
  264.     x: 0,
  265.     y: 0, // Default coordinates are all 0,0
  266.     /* Record our starting x,y */
  267.  
  268.     //Create a new fill object and draw it
  269.     create: function(x, y) {
  270.       this.update_options();
  271.       this.draw(x, y, this.color, false);
  272.     },
  273.  
  274.     /* fill a space */
  275.     //Putting in x,y here fills the space between x,y and x+1,y+1.
  276.     draw: function(x, y, color, restore) {
  277.       console.log("Called draw with x=" + x + ",  y=" + y + ", color=" + color);
  278.       /* No color? It's this color! */
  279.       if (color == undefined)
  280.         ctx.fillStyle = this.color;
  281.       else
  282.         ctx.fillStyle = color;
  283.  
  284.       /* Draw the line */
  285.       var xstart = (x * spacing) + 1;
  286.       var xstop = xstart + spacing - 2;
  287.       var ystart = (y * spacing) + 1;
  288.       var ystop = ystart + spacing - 2;
  289.  
  290.       console.log("Filling rectangle " + xstart + ", " + xstop + ", " + ystart + ", " + ystop);
  291.  
  292.       ctx.fillRect(xstart, ystart, xstop - xstart, ystop - ystart);
  293.  
  294.       /* Save it and clean up and guide lines */
  295.       if (!restore) {
  296.         actions.save();
  297.         canvas.redraw();
  298.         actions.restore();
  299.       }
  300.     },
  301.  
  302.     /* Get all the set options from the toolset */
  303.     update_options: function() {
  304.       if (canvas.in_restore)
  305.         return false;
  306.  
  307.       this.color = document.getElementById('line_color').value;
  308.     }
  309.   }
  310.  
  311.  
  312.   /* Clear out everything */
  313.   canvas.clear = function() {
  314.     ctx.clearRect(0, 0, this.width, this.height);
  315.   }
  316.  
  317.  
  318.   /* Redraw everything */
  319.   //Original comment here said (not by me) that this draws just the lines, not the other stuff. That wasn't the case.
  320.   canvas.redraw = function() {
  321.     this.clear();
  322.  
  323.     /* Prepare to draw the grid */
  324.     ctx.beginPath();
  325.     ctx.strokeStyle = 'lightblue';
  326.     ctx.lineWidth = 1;
  327.  
  328.     /* Vertical rule */
  329.     for (var y = spacing; y < this.h; y = y + spacing) {
  330.       ctx.moveTo(0, y);
  331.       ctx.lineTo(this.w, y);
  332.     }
  333.  
  334.     /* Horizontal rule */
  335.     for (var x = spacing; x < this.w; x = x + spacing) {
  336.       ctx.moveTo(x, 0);
  337.       ctx.lineTo(x, this.h);
  338.     }
  339.  
  340.     /* Draw the grid */
  341.     ctx.closePath();
  342.     ctx.stroke();
  343.  
  344.     /* Restore any saved actions */
  345.     actions.restore();
  346.   }
  347.  
  348.  
  349.   /* When the user moves the mouse */
  350.   canvas.onmousemove = function(e) {
  351.  
  352.     if (!e) var e = window.event;
  353.  
  354.     if (tool == "line") { //different actions for the fill tool and the line tool
  355.       var x = e.clientX;
  356.       var y = e.clientY;
  357.  
  358.       /* Update the coordinates */
  359.       toolset_coord.update(x, y);
  360.       popup.show(x, y);
  361.  
  362.       /* If we're drawing a line, show the guide line */
  363.       if (this.mousedown)
  364.         line.guide(x, y);
  365.     } else if (tool == "fill") {
  366.       var x = e.clientX;
  367.       var y = e.clientY;
  368.       fill.x = Math.floor(roundQuarter(x / spacing));
  369.       fill.y = Math.floor(roundQuarter(y / spacing));
  370.  
  371.       toolset_coord.update(x, y);
  372.  
  373.     }
  374.   }
  375.  
  376.  
  377.   /* When the clicker goes down (but not back up) */
  378.   canvas.onmousedown = function(e) {
  379.     if (!e) var e = window.event;
  380.  
  381.     /* Confirm it's down (handy for later) */
  382.     this.mousedown = true;
  383.  
  384.     var x = e.clientX;
  385.     var y = e.clientY;
  386.  
  387.     /* Set the start of the line and show the pop-up */
  388.     console.log("Mousedown, tool is " + tool);
  389.     if (tool == "line") {
  390.       line.start(x, y);
  391.       popup.show(x, y);
  392.     } else {
  393.       fill.create(Math.floor(roundQuarter(x / spacing)), Math.floor(roundQuarter(y / spacing)));
  394.     }
  395.   }
  396.  
  397.  
  398.   /* When the clicker comes back up */
  399.   canvas.onmouseup = function(e) {
  400.     if (!e) var e = window.event;
  401.  
  402.     this.mousedown = false;
  403.  
  404.     if (tool == 'line') {
  405.       /* We're no longer holding down */
  406.  
  407.  
  408.       var x = e.clientX;
  409.       var y = e.clientY;
  410.  
  411.       /* Set the stop point and hide the pop-up */
  412.       line.stop(x, y);
  413.       popup.hide();
  414.     }
  415.   }
  416.  
  417.  
  418.   /* Show the pop-up */
  419.   popup.show = function(x, y) {
  420.     if (!canvas.mousedown)
  421.       return false;
  422.  
  423.     /* Offset it from the cursor a little bit */
  424.     this.style.left = (x + 30) + 'px';
  425.     this.style.top = (y + 30) + 'px';
  426.  
  427.     /* Display coordinates and distance */
  428.     this.innerHTML = roundQuarter(x / spacing) + ', ' + roundQuarter(y / spacing);
  429.     this.innerHTML += ', ' + this.distance(line.x1, line.y1, line.snap_to_grid(x), line.snap_to_grid(y)) + " units";
  430.  
  431.     /* Show the pop-up */
  432.     this.style.display = 'block';
  433.   }
  434.  
  435.  
  436.   /* Use Pythagora's theorem to calculate distance */
  437.   popup.distance = function(x1, y1, x2, y2) {
  438.     var scale = 1;
  439.  
  440.     var a = x1 - x2;
  441.     var b = y1 - y2;
  442.  
  443.     if (a < 0) a *= -1;
  444.     if (b < 0) b *= -1;
  445.  
  446.     var retval = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
  447.  
  448.     retval = Math.round(parseFloat(retval * scale / spacing) * 100) / 100;
  449.  
  450.     return retval;
  451.   }
  452.  
  453.  
  454.   /* Hide the pop-up */
  455.   popup.hide = function() {
  456.     this.style.display = 'none';
  457.   }
  458.  
  459.  
  460.   /* Now that all functions and objects are set, draw the grid */
  461.   canvas.redraw();
  462.  
  463.   if (sessionStorage.length) {
  464.     if (confirm('Restore Previous Drawings?')) {
  465.       var data = JSON.parse(sessionStorage['data'])
  466.       actions.data = data;
  467.       for (var i = 0; i < data.length; ++i) {
  468.         if (data[i].type == 'fill') {
  469.           fill.draw(data[i].x, data[i].y, data[i].color, true);
  470.           //do all the lines
  471.         } else if (data[i].type == 'line') {
  472.           line.draw(data[i].x1, data[i].y1, data[i].x2, data[i].y2, 'restore', data[i].color, data[i].width);
  473.         }
  474.       }
  475.  
  476.     } else {
  477.       actions.purge();
  478.     }
  479.   }
  480. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement