You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

line.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /**
  2. * WHITEBOPHIR
  3. *********************************************************
  4. * @licstart The following is the entire license notice for the
  5. * JavaScript code in this page.
  6. *
  7. * Copyright (C) 2013 Ophir LOJKINE
  8. *
  9. *
  10. * The JavaScript code in this page is free software: you can
  11. * redistribute it and/or modify it under the terms of the GNU
  12. * General Public License (GNU GPL) as published by the Free Software
  13. * Foundation, either version 3 of the License, or (at your option)
  14. * any later version. The code is distributed WITHOUT ANY WARRANTY;
  15. * without even the implied warranty of MERCHANTABILITY or FITNESS
  16. * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
  17. *
  18. * As additional permission under GNU GPL version 3 section 7, you
  19. * may distribute non-source (e.g., minimized or compacted) forms of
  20. * that code without the copy of the GNU GPL normally required by
  21. * section 4, provided you include this license notice and a URL
  22. * through which recipients can access the Corresponding Source.
  23. *
  24. * @licend
  25. */
  26. (function () { //Code isolation
  27. //Indicates the id of the line the user is currently drawing or an empty string while the user is not drawing
  28. var curLine = null,
  29. lastTime = performance.now(); //The time at which the last point was drawn
  30. //The data of the message that will be sent for every update
  31. function UpdateMessage(x, y) {
  32. this.type = 'update';
  33. this.id = curLine.id;
  34. this.x2 = x;
  35. this.y2 = y;
  36. }
  37. function startLine(x, y, evt) {
  38. //Prevent the press from being interpreted by the browser
  39. evt.preventDefault();
  40. curLine = {
  41. 'type': 'straight',
  42. 'id': Tools.generateUID("s"), //"s" for straight line
  43. 'color': Tools.getColor(),
  44. 'size': Tools.getSize(),
  45. 'opacity': Tools.getOpacity(),
  46. 'x': x,
  47. 'y': y
  48. }
  49. Tools.drawAndSend(curLine);
  50. }
  51. function continueLine(x, y, evt) {
  52. /*Wait 70ms before adding any point to the currently drawing line.
  53. This allows the animation to be smother*/
  54. if (curLine !== null) {
  55. if (lineTool.secondary.active) {
  56. var alpha = Math.atan2(y - curLine.y, x - curLine.x);
  57. var d = Math.hypot(y - curLine.y, x - curLine.x);
  58. var increment = 2 * Math.PI / 16;
  59. alpha = Math.round(alpha / increment) * increment;
  60. x = curLine.x + d * Math.cos(alpha);
  61. y = curLine.y + d * Math.sin(alpha);
  62. }
  63. if (performance.now() - lastTime > 70) {
  64. Tools.drawAndSend(new UpdateMessage(x, y));
  65. lastTime = performance.now();
  66. } else {
  67. draw(new UpdateMessage(x, y));
  68. }
  69. }
  70. if (evt) evt.preventDefault();
  71. }
  72. function stopLine(x, y) {
  73. //Add a last point to the line
  74. continueLine(x, y);
  75. curLine = null;
  76. }
  77. function draw(data) {
  78. switch (data.type) {
  79. case "straight":
  80. createLine(data);
  81. break;
  82. case "update":
  83. var line = svg.getElementById(data['id']);
  84. if (!line) {
  85. console.error("Straight line: Hmmm... I received a point of a line that has not been created (%s).", data['id']);
  86. createLine({ //create a new line in order not to loose the points
  87. "id": data['id'],
  88. "x": data['x2'],
  89. "y": data['y2']
  90. });
  91. }
  92. updateLine(line, data);
  93. break;
  94. default:
  95. console.error("Straight Line: Draw instruction with unknown type. ", data);
  96. break;
  97. }
  98. }
  99. var svg = Tools.svg;
  100. function createLine(lineData) {
  101. //Creates a new line on the canvas, or update a line that already exists with new information
  102. var line = svg.getElementById(lineData.id) || Tools.createSVGElement("line");
  103. line.id = lineData.id;
  104. line.x1.baseVal.value = lineData['x'];
  105. line.y1.baseVal.value = lineData['y'];
  106. line.x2.baseVal.value = lineData['x2'] || lineData['x'];
  107. line.y2.baseVal.value = lineData['y2'] || lineData['y'];
  108. //If some data is not provided, choose default value. The line may be updated later
  109. line.setAttribute("stroke", lineData.color || "black");
  110. line.setAttribute("stroke-width", lineData.size || 10);
  111. line.setAttribute("opacity", Math.max(0.1, Math.min(1, lineData.opacity)) || 1);
  112. Tools.drawingArea.appendChild(line);
  113. return line;
  114. }
  115. function updateLine(line, data) {
  116. line.x2.baseVal.value = data['x2'];
  117. line.y2.baseVal.value = data['y2'];
  118. }
  119. var lineTool = {
  120. "name": "Straight line",
  121. "shortcut": "l",
  122. "listeners": {
  123. "press": startLine,
  124. "move": continueLine,
  125. "release": stopLine,
  126. },
  127. "secondary": {
  128. "name": "Straight line",
  129. "icon": "tools/line/icon-straight.svg",
  130. "active": false,
  131. },
  132. "draw": draw,
  133. "mouseCursor": "crosshair",
  134. "icon": "tools/line/icon.svg",
  135. "stylesheet": "tools/line/line.css"
  136. };
  137. Tools.add(lineTool);
  138. })(); //End of code isolation