whitebophir/client-data/tools/text/text.js
Ophir LOJKINE a6eba9b293 Fix #107
2020-07-27 12:11:27 +02:00

219 lines
6 KiB
JavaScript

/**
* WHITEBOPHIR
*********************************************************
* @licstart The following is the entire license notice for the
* JavaScript code in this page.
*
* Copyright (C) 2013 Ophir LOJKINE
*
*
* The JavaScript code in this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License (GNU GPL) as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version. The code is distributed WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
*
* As additional permission under GNU GPL version 3 section 7, you
* may distribute non-source (e.g., minimized or compacted) forms of
* that code without the copy of the GNU GPL normally required by
* section 4, provided you include this license notice and a URL
* through which recipients can access the Corresponding Source.
*
* @licend
*/
(function () { //Code isolation
var board = Tools.board;
var input = document.createElement("input");
input.id = "textToolInput";
input.type = "text";
input.setAttribute("autocomplete", "off");
var curText = {
"x": 0,
"y": 0,
"size": 36,
"rawSize": 16,
"oldSize": 0,
"opacity": 1,
"color": "#000",
"id": 0,
"sentText": "",
"lastSending": 0
};
var active = false;
function onStart() {
curText.oldSize = Tools.getSize();
Tools.setSize(curText.rawSize);
}
function onQuit() {
stopEdit();
Tools.setSize(curText.oldSize);
}
function clickHandler(x, y, evt, isTouchEvent) {
//if(document.querySelector("#menu").offsetWidth>Tools.menu_width+3) return;
if (evt.target === input) return;
if (evt.target.tagName === "text") {
editOldText(evt.target);
evt.preventDefault();
return;
}
curText.rawSize = Tools.getSize();
curText.size = parseInt(curText.rawSize * 1.5 + 12);
curText.opacity = Tools.getOpacity();
curText.color = Tools.getColor();
curText.x = x;
curText.y = y + curText.size / 2;
stopEdit();
startEdit();
evt.preventDefault();
}
function editOldText(elem) {
curText.id = elem.id;
var r = elem.getBoundingClientRect();
var x = (r.left + document.documentElement.scrollLeft) / Tools.scale;
var y = (r.top + r.height + document.documentElement.scrollTop) / Tools.scale;
curText.x = x;
curText.y = y;
curText.sentText = elem.textContent;
curText.size = parseInt(elem.getAttribute("font-size"));
curText.opacity = parseFloat(elem.getAttribute("opacity"));
curText.color = elem.getAttribute("fill");
startEdit();
input.value = elem.textContent;
}
function startEdit() {
active = true;
if (!input.parentNode) board.appendChild(input);
input.value = "";
var left = curText.x - document.documentElement.scrollLeft + 'px';
var clientW = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var x = curText.x * Tools.scale - document.documentElement.scrollLeft;
if (x + 250 > clientW) {
x = Math.max(60, clientW - 260)
}
input.style.left = x + 'px';
input.style.top = curText.y * Tools.scale - document.documentElement.scrollTop + 20 + 'px';
input.focus();
input.addEventListener("keyup", textChangeHandler);
input.addEventListener("blur", textChangeHandler);
input.addEventListener("blur", blur);
}
function stopEdit() {
try { input.blur(); } catch (e) { /* Internet Explorer */ }
active = false;
blur();
curText.id = 0;
curText.sentText = "";
input.value = "";
input.removeEventListener("keyup", textChangeHandler);
}
function blur() {
if (active) return;
input.style.top = '-1000px';
}
function textChangeHandler(evt) {
if (evt.which === 13) { // enter
curText.y += 1.5 * curText.size;
stopEdit();
startEdit();
} else if (evt.which === 27) { // escape
stopEdit();
}
if (performance.now() - curText.lastSending > 100) {
if (curText.sentText !== input.value) {
//If the user clicked where there was no text, then create a new text field
if (curText.id === 0) {
curText.id = Tools.generateUID("t"); //"t" for text
Tools.drawAndSend({
'type': 'new',
'id': curText.id,
'color': curText.color,
'size': curText.size,
'opacity': curText.opacity,
'x': curText.x,
'y': curText.y
})
}
Tools.drawAndSend({
'type': "update",
'id': curText.id,
'txt': input.value.slice(0, 280)
});
curText.sentText = input.value;
curText.lastSending = performance.now();
}
} else {
clearTimeout(curText.timeout);
curText.timeout = setTimeout(textChangeHandler, 500, evt);
}
}
function draw(data, isLocal) {
Tools.drawingEvent = true;
switch (data.type) {
case "new":
createTextField(data);
break;
case "update":
var textField = document.getElementById(data.id);
if (textField === null) {
console.error("Text: Hmmm... I received text that belongs to an unknown text field");
return false;
}
updateText(textField, data.txt);
break;
default:
console.error("Text: Draw instruction with unknown type. ", data);
break;
}
}
function updateText(textField, text) {
textField.textContent = text;
}
function createTextField(fieldData) {
var elem = Tools.createSVGElement("text");
elem.id = fieldData.id;
elem.setAttribute("x", fieldData.x);
elem.setAttribute("y", fieldData.y);
elem.setAttribute("font-size", fieldData.size);
elem.setAttribute("fill", fieldData.color);
elem.setAttribute("opacity", Math.max(0.1, Math.min(1, fieldData.opacity)) || 1);
if (fieldData.txt) elem.textContent = fieldData.txt;
Tools.drawingArea.appendChild(elem);
return elem;
}
Tools.add({ //The new tool
"name": "Text",
"shortcut": "t",
"listeners": {
"press": clickHandler,
},
"onstart": onStart,
"onquit": onQuit,
"draw": draw,
"stylesheet": "tools/text/text.css",
"icon": "tools/text/icon.svg",
"mouseCursor": "text"
});
})(); //End of code isolation