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.

ellipse.js 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 shape the user is currently drawing or an empty string while the user is not drawing
  28. let curshape = "Ellipse";
  29. const icons = ["tools/ellipse/icon-ellipse.svg", "tools/ellipse/icon-circle.svg"];
  30. let end=false,
  31. curId = "",
  32. curUpdate = { //The data of the message that will be sent for every new point
  33. 'type': 'update',
  34. 'id': "",
  35. 'shape': curshape,
  36. 'x': 0,
  37. 'y': 0,
  38. 'x2': 0,
  39. 'y2': 0
  40. },
  41. lastTime = performance.now(); //The time at which the last point was drawn
  42. function start(x, y, evt) {
  43. //Prevent the press from being interpreted by the browser
  44. evt.preventDefault();
  45. curId = Tools.generateUID("e"); //"e" for ellipse
  46. Tools.drawAndSend({
  47. 'type': 'ellipse',
  48. 'id': curId,
  49. 'shape': curshape,
  50. 'color': Tools.getColor(),
  51. 'size': Tools.getSize(),
  52. 'opacity': Tools.getOpacity(),
  53. 'x': x,
  54. 'y': y,
  55. 'x2': x,
  56. 'y2': y
  57. });
  58. curUpdate.id = curId;
  59. curUpdate.shape = curshape;
  60. curUpdate.x = x;
  61. curUpdate.y = y;
  62. }
  63. function move(x, y, evt) {
  64. /*Wait 70ms before adding any point to the currently drawing shape.
  65. This allows the animation to be smother*/
  66. if (curId !== "") {
  67. curUpdate['x2'] = x; curUpdate['y2'] = y;
  68. if (performance.now() - lastTime > 70 || end) {
  69. Tools.drawAndSend(curUpdate);
  70. lastTime = performance.now();
  71. } else {
  72. draw(curUpdate);
  73. }
  74. }
  75. if (evt) evt.preventDefault();
  76. }
  77. function stop(x, y) {
  78. //Add a last point to the shape
  79. end=true;
  80. move(x, y);
  81. end=false;
  82. curId = "";
  83. }
  84. function draw(data) {
  85. Tools.drawingEvent=true;
  86. switch (data.type) {
  87. case "ellipse":
  88. createShape(data);
  89. break;
  90. case "update":
  91. var shape = svg.getElementById(data['id']);
  92. if (!shape) {
  93. console.error("Straight shape: Hmmm... I received a point of a shape that has not been created (%s).", data['id']);
  94. createShape({ //create a new shape in order not to loose the points
  95. "id": data['id'],
  96. "x": data['x2'],
  97. "y": data['y2']
  98. });
  99. }
  100. updateShape(shape, data, data.shape === "Circle");
  101. break;
  102. default:
  103. console.error("Straight shape: Draw instruction with unknown type. ", data);
  104. break;
  105. }
  106. }
  107. var svg = Tools.svg;
  108. function createShape(data) {
  109. //Creates a new shape on the canvas, or update a shape that already exists with new information
  110. var shape = svg.getElementById(data.id) || Tools.createSVGElement("ellipse");
  111. updateShape(shape, data, data.shape === "Circle");
  112. shape.id = data.id;
  113. //If some data is not provided, choose default value. The shape may be updated later
  114. shape.setAttribute("stroke", data.color || "black");
  115. shape.setAttribute("stroke-width", data.size || 10);
  116. shape.setAttribute("opacity", Math.max(0.1, Math.min(1, data.opacity)) || 1);
  117. svg.appendChild(shape);
  118. return shape;
  119. }
  120. function updateShape(shape, data, circle) {
  121. shape.cx.baseVal.value = Math.round((data['x2'] + data['x'])/2);
  122. shape.cy.baseVal.value = Math.round((data['y2'] + data['y'])/2);
  123. if (circle) {
  124. var r = Math.round(Math.sqrt(Math.pow(data['x2'] - data['x'],2)+Math.pow(data['y2'] - data['y'],2))/2);
  125. shape.rx.baseVal.value = r;
  126. shape.ry.baseVal.value = r;
  127. } else {
  128. shape.rx.baseVal.value = Math.abs(data['x2'] - data['x'])/2;
  129. shape.ry.baseVal.value = Math.abs(data['y2'] - data['y'])/2;
  130. }
  131. }
  132. function toggle(elem){
  133. let index = 0;
  134. if (curshape === "Ellipse") {
  135. curshape = "Circle";
  136. index = 1;
  137. } else {
  138. curshape = "Ellipse";
  139. }
  140. elem.getElementsByClassName("tool-icon")[0].src = icons[index];
  141. elem.getElementsByClassName("tool-name")[0].textContent = curshape;
  142. }
  143. Tools.add({ //The new tool
  144. "name": "Ellipse",
  145. "shortcut": "c",
  146. "listeners": {
  147. "press": start,
  148. "move": move,
  149. "release": stop,
  150. },
  151. "draw": draw,
  152. "toggle": toggle,
  153. "mouseCursor": "crosshair",
  154. "icon": icons[0],
  155. "stylesheet": "tools/ellipse/ellipse.css"
  156. });
  157. })(); //End of code isolation