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.

text.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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, svg = Tools.svg;
  28. var input = document.createElement("input");
  29. input.id = "textToolInput";
  30. input.setAttribute("autocomplete", "off");
  31. var curText = {
  32. "x": 0,
  33. "y": 0,
  34. "size": 0,
  35. "opacity": 1,
  36. "color": "#000",
  37. "id": 0,
  38. "sentText": "",
  39. "lastSending": 0
  40. };
  41. function clickHandler(x, y, evt) {
  42. if (evt.target == input) return;
  43. if (evt.target.tagName === "text") {
  44. editOldText(evt.target);
  45. evt.preventDefault();
  46. return;
  47. }
  48. curText.size = parseInt(Tools.getSize() * 1.5 + 12);
  49. curText.opacity = Tools.getOpacity();
  50. curText.color = Tools.getColor();
  51. curText.x = x;
  52. curText.y = y + curText.size / 2;
  53. drawCurText();
  54. evt.preventDefault();
  55. }
  56. function editOldText(elem) {
  57. curText.id = elem.id;
  58. curText.x = elem.x.baseVal[0].value;
  59. curText.y = elem.y.baseVal[0].value;
  60. curText.size = parseInt(elem.getAttribute("font-size"));
  61. curText.opacity = parseFloat(elem.getAttribute("opacity"));
  62. curText.color = elem.getAttribute("fill");
  63. startEdit();
  64. input.value = elem.textContent;
  65. }
  66. function drawCurText() {
  67. stopEdit();
  68. //If the user clicked where there was no text, then create a new text field
  69. curText.id = Tools.generateUID("t"); //"t" for text
  70. Tools.drawAndSend({
  71. 'type': 'new',
  72. 'id': curText.id,
  73. 'color': curText.color,
  74. 'size': curText.size,
  75. 'opacity': curText.opacity,
  76. 'x': curText.x,
  77. 'y': curText.y
  78. });
  79. startEdit();
  80. }
  81. function startEdit() {
  82. if (!input.parentNode) board.appendChild(input);
  83. input.value = "";
  84. input.focus();
  85. input.addEventListener("keyup", textChangeHandler);
  86. input.addEventListener("blur", textChangeHandler);
  87. }
  88. function stopEdit() {
  89. input.blur();
  90. input.removeEventListener("keyup", textChangeHandler);
  91. }
  92. function textChangeHandler(evt) {
  93. if (evt.which === 13) {
  94. curText.y += 1.5 * curText.size;
  95. return drawCurText();
  96. }
  97. if (performance.now() - curText.lastSending > 100) {
  98. if (curText.sentText !== input.value) {
  99. Tools.drawAndSend({
  100. 'type': "update",
  101. 'id': curText.id,
  102. 'txt': input.value.slice(0, 280)
  103. });
  104. curText.sentText = input.value;
  105. curText.lastSending = performance.now();
  106. }
  107. } else {
  108. clearTimeout(curText.timeout);
  109. curText.timeout = setTimeout(textChangeHandler, 500, evt);
  110. }
  111. }
  112. function draw(data, isLocal) {
  113. switch (data.type) {
  114. case "new":
  115. createTextField(data);
  116. break;
  117. case "update":
  118. var textField = document.getElementById(data.id);
  119. if (textField === null) {
  120. console.error("Text: Hmmm... I received text that belongs to an unknown text field");
  121. return false;
  122. }
  123. updateText(textField, data.txt);
  124. break;
  125. default:
  126. console.error("Text: Draw instruction with unknown type. ", data);
  127. break;
  128. }
  129. }
  130. function updateText(textField, text) {
  131. textField.textContent = text;
  132. }
  133. function createTextField(fieldData) {
  134. var elem = Tools.createSVGElement("text");
  135. elem.id = fieldData.id;
  136. elem.setAttribute("x", fieldData.x);
  137. elem.setAttribute("y", fieldData.y);
  138. elem.setAttribute("font-size", fieldData.size);
  139. elem.setAttribute("fill", fieldData.color);
  140. elem.setAttribute("opacity", Math.max(0.1, Math.min(1, fieldData.opacity)) || 1);
  141. if (fieldData.txt) elem.textContent = fieldData.txt;
  142. svg.appendChild(elem);
  143. return elem;
  144. }
  145. Tools.add({ //The new tool
  146. "name": "Text",
  147. "icon": "T",
  148. "listeners": {
  149. "press": clickHandler,
  150. },
  151. "draw": draw,
  152. "stylesheet": "tools/text/text.css",
  153. "mouseCursor": "text"
  154. });
  155. })(); //End of code isolation