Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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. var board = Tools.board;
  28. var input = document.createElement("input");
  29. input.id = "textToolInput";
  30. input.type = "text";
  31. input.setAttribute("autocomplete", "off");
  32. var curText = {
  33. "x": 0,
  34. "y": 0,
  35. "size": 36,
  36. "rawSize": 16,
  37. "oldSize": 0,
  38. "opacity": 1,
  39. "color": "#000",
  40. "id": 0,
  41. "sentText": "",
  42. "lastSending": 0
  43. };
  44. var active = false;
  45. function onStart() {
  46. curText.oldSize = Tools.getSize();
  47. Tools.setSize(curText.rawSize);
  48. }
  49. function onQuit() {
  50. stopEdit();
  51. Tools.setSize(curText.oldSize);
  52. }
  53. function clickHandler(x, y, evt, isTouchEvent) {
  54. //if(document.querySelector("#menu").offsetWidth>Tools.menu_width+3) return;
  55. if (evt.target === input) return;
  56. if (evt.target.tagName === "text") {
  57. editOldText(evt.target);
  58. evt.preventDefault();
  59. return;
  60. }
  61. curText.rawSize = Tools.getSize();
  62. curText.size = parseInt(curText.rawSize * 1.5 + 12);
  63. curText.opacity = Tools.getOpacity();
  64. curText.color = Tools.getColor();
  65. curText.x = x;
  66. curText.y = y + curText.size / 2;
  67. stopEdit();
  68. startEdit();
  69. evt.preventDefault();
  70. }
  71. function editOldText(elem) {
  72. curText.id = elem.id;
  73. var r = elem.getBoundingClientRect();
  74. var x = (r.left + document.documentElement.scrollLeft) / Tools.scale;
  75. var y = (r.top + r.height + document.documentElement.scrollTop) / Tools.scale;
  76. curText.x = x;
  77. curText.y = y;
  78. curText.sentText = elem.textContent;
  79. curText.size = parseInt(elem.getAttribute("font-size"));
  80. curText.opacity = parseFloat(elem.getAttribute("opacity"));
  81. curText.color = elem.getAttribute("fill");
  82. startEdit();
  83. input.value = elem.textContent;
  84. }
  85. function startEdit() {
  86. active = true;
  87. if (!input.parentNode) board.appendChild(input);
  88. input.value = "";
  89. var left = curText.x - document.documentElement.scrollLeft + 'px';
  90. var clientW = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  91. var x = curText.x * Tools.scale - document.documentElement.scrollLeft;
  92. if (x + 250 > clientW) {
  93. x = Math.max(60, clientW - 260)
  94. }
  95. input.style.left = x + 'px';
  96. input.style.top = curText.y * Tools.scale - document.documentElement.scrollTop + 20 + 'px';
  97. input.focus();
  98. input.addEventListener("keyup", textChangeHandler);
  99. input.addEventListener("blur", textChangeHandler);
  100. input.addEventListener("blur", blur);
  101. }
  102. function stopEdit() {
  103. try { input.blur(); } catch (e) { /* Internet Explorer */ }
  104. active = false;
  105. blur();
  106. curText.id = 0;
  107. curText.sentText = "";
  108. input.value = "";
  109. input.removeEventListener("keyup", textChangeHandler);
  110. }
  111. function blur() {
  112. if (active) return;
  113. input.style.top = '-1000px';
  114. }
  115. function textChangeHandler(evt) {
  116. if (evt.which === 13) { // enter
  117. curText.y += 1.5 * curText.size;
  118. stopEdit();
  119. startEdit();
  120. } else if (evt.which === 27) { // escape
  121. stopEdit();
  122. }
  123. if (performance.now() - curText.lastSending > 100) {
  124. if (curText.sentText !== input.value) {
  125. //If the user clicked where there was no text, then create a new text field
  126. if (curText.id === 0) {
  127. curText.id = Tools.generateUID("t"); //"t" for text
  128. Tools.drawAndSend({
  129. 'type': 'new',
  130. 'id': curText.id,
  131. 'color': curText.color,
  132. 'size': curText.size,
  133. 'opacity': curText.opacity,
  134. 'x': curText.x,
  135. 'y': curText.y
  136. })
  137. }
  138. Tools.drawAndSend({
  139. 'type': "update",
  140. 'id': curText.id,
  141. 'txt': input.value.slice(0, 280)
  142. });
  143. curText.sentText = input.value;
  144. curText.lastSending = performance.now();
  145. }
  146. } else {
  147. clearTimeout(curText.timeout);
  148. curText.timeout = setTimeout(textChangeHandler, 500, evt);
  149. }
  150. }
  151. function draw(data, isLocal) {
  152. Tools.drawingEvent = true;
  153. switch (data.type) {
  154. case "new":
  155. createTextField(data);
  156. break;
  157. case "update":
  158. var textField = document.getElementById(data.id);
  159. if (textField === null) {
  160. console.error("Text: Hmmm... I received text that belongs to an unknown text field");
  161. return false;
  162. }
  163. updateText(textField, data.txt);
  164. break;
  165. default:
  166. console.error("Text: Draw instruction with unknown type. ", data);
  167. break;
  168. }
  169. }
  170. function updateText(textField, text) {
  171. textField.textContent = text;
  172. }
  173. function createTextField(fieldData) {
  174. var elem = Tools.createSVGElement("text");
  175. elem.id = fieldData.id;
  176. elem.setAttribute("x", fieldData.x);
  177. elem.setAttribute("y", fieldData.y);
  178. elem.setAttribute("font-size", fieldData.size);
  179. elem.setAttribute("fill", fieldData.color);
  180. elem.setAttribute("opacity", Math.max(0.1, Math.min(1, fieldData.opacity)) || 1);
  181. if (fieldData.txt) elem.textContent = fieldData.txt;
  182. Tools.drawingArea.appendChild(elem);
  183. return elem;
  184. }
  185. Tools.add({ //The new tool
  186. "name": "Text",
  187. "shortcut": "t",
  188. "listeners": {
  189. "press": clickHandler,
  190. },
  191. "onstart": onStart,
  192. "onquit": onQuit,
  193. "draw": draw,
  194. "stylesheet": "tools/text/text.css",
  195. "icon": "tools/text/icon.svg",
  196. "mouseCursor": "text"
  197. });
  198. })(); //End of code isolation