mirror of
https://github.com/lovasoa/whitebophir
synced 2024-11-10 06:24:17 +00:00
Merge branch 'master' into prod
This commit is contained in:
commit
c7d900d03f
10 changed files with 147 additions and 32 deletions
|
@ -101,4 +101,4 @@
|
|||
<script src="../js/canvascolor.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -314,6 +314,7 @@ Tools.pendingMessages = {};
|
|||
function messageForTool(message) {
|
||||
var name = message.tool,
|
||||
tool = Tools.list[name];
|
||||
|
||||
if (tool) {
|
||||
Tools.applyHooks(Tools.messageHooks, message);
|
||||
tool.draw(message, false);
|
||||
|
@ -323,6 +324,11 @@ function messageForTool(message) {
|
|||
if (!Tools.pendingMessages[name]) Tools.pendingMessages[name] = [message];
|
||||
else Tools.pendingMessages[name].push(message);
|
||||
}
|
||||
|
||||
if (message.tool !== 'Hand' && message.deltax != null && message.deltay != null) {
|
||||
//this message has special info for the mover
|
||||
messageForTool({ tool: 'Hand', type: 'update', deltax: message.deltax || 0, deltay: message.deltay || 0, id: message.id });
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the function to all arguments by batches
|
||||
|
@ -612,6 +618,7 @@ Tools.getOpacity = (function opacity() {
|
|||
};
|
||||
})();
|
||||
|
||||
|
||||
//Scale the canvas on load
|
||||
Tools.svg.width.baseVal.value = document.body.clientWidth;
|
||||
Tools.svg.height.baseVal.value = document.body.clientHeight;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* WHITEBOPHIR
|
||||
* WHITEBOPHIR
|
||||
*********************************************************
|
||||
* @licstart The following is the entire license notice for the
|
||||
* JavaScript code in this page.
|
||||
* JavaScript code in this page.
|
||||
*
|
||||
* Copyright (C) 2013 Ophir LOJKINE
|
||||
*
|
||||
|
@ -24,39 +24,120 @@
|
|||
* @licend
|
||||
*/
|
||||
|
||||
(function () { //Code isolation
|
||||
(function hand() { //Code isolation
|
||||
var selected = null;
|
||||
var last_sent = 0;
|
||||
|
||||
var orig = { x: 0, y: 0 };
|
||||
var pressed = false;
|
||||
function press(x, y, evt, isTouchEvent) {
|
||||
|
||||
function startMovingElement(x, y, evt) {
|
||||
//Prevent the press from being interpreted by the browser
|
||||
evt.preventDefault();
|
||||
if (!evt.target || !Tools.drawingArea.contains(evt.target)) return;
|
||||
var tmatrix = get_translate_matrix(evt.target);
|
||||
selected = { x: x - tmatrix.e, y: y - tmatrix.f, elem: evt.target };
|
||||
}
|
||||
|
||||
function moveElement(x, y) {
|
||||
if (!selected) return;
|
||||
var deltax = x - selected.x;
|
||||
var deltay = y - selected.y;
|
||||
var msg = { type: "update", id: selected.elem.id, deltax: deltax, deltay: deltay };
|
||||
var now = performance.now();
|
||||
if (now - last_sent > 70) {
|
||||
last_sent = now;
|
||||
Tools.drawAndSend(msg);
|
||||
} else {
|
||||
draw(msg);
|
||||
}
|
||||
}
|
||||
|
||||
function get_translate_matrix(elem) {
|
||||
// Returns the first translate or transform matrix or makes one
|
||||
var translate = null;
|
||||
for (var i = 0; i < elem.transform.baseVal.numberOfItems; ++i) {
|
||||
var baseVal = elem.transform.baseVal[i];
|
||||
// quick tests showed that even if one changes only the fields e and f or uses createSVGTransformFromMatrix
|
||||
// the brower may add a SVG_TRANSFORM_MATRIX instead of a SVG_TRANSFORM_TRANSLATE
|
||||
if (baseVal.type === SVGTransform.SVG_TRANSFORM_TRANSLATE || baseVal.type === SVGTransform.SVG_TRANSFORM_MATRIX) {
|
||||
translate = baseVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (translate == null) {
|
||||
translate = elem.transform.baseVal.createSVGTransformFromMatrix(Tools.svg.createSVGMatrix());
|
||||
elem.transform.baseVal.appendItem(translate);
|
||||
}
|
||||
return translate.matrix;
|
||||
}
|
||||
|
||||
function draw(data) {
|
||||
switch (data.type) {
|
||||
case "update":
|
||||
var elem = Tools.svg.getElementById(data.id);
|
||||
if (!elem) throw new Error("Mover: Tried to move an element that does not exist.");
|
||||
var tmatrix = get_translate_matrix(elem);
|
||||
tmatrix.e = data.deltax || 0;
|
||||
tmatrix.f = data.deltay || 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Mover: 'move' instruction with unknown type. ", data);
|
||||
}
|
||||
}
|
||||
|
||||
function startHand(x, y, evt, isTouchEvent) {
|
||||
if (!isTouchEvent) {
|
||||
pressed = true;
|
||||
orig.x = document.documentElement.scrollLeft + evt.clientX;
|
||||
orig.y = document.documentElement.scrollTop + evt.clientY;
|
||||
selected = {
|
||||
x: document.documentElement.scrollLeft + evt.clientX,
|
||||
y: document.documentElement.scrollTop + evt.clientY,
|
||||
}
|
||||
}
|
||||
}
|
||||
function move(x, y, evt, isTouchEvent) {
|
||||
if (pressed && !isTouchEvent) { //Let the browser handle touch to scroll
|
||||
window.scrollTo(orig.x - evt.clientX, orig.y - evt.clientY);
|
||||
function moveHand(x, y, evt, isTouchEvent) {
|
||||
if (selected && !isTouchEvent) { //Let the browser handle touch to scroll
|
||||
window.scrollTo(selected.x - evt.clientX, selected.y - evt.clientY);
|
||||
}
|
||||
}
|
||||
function release() {
|
||||
pressed = false;
|
||||
}
|
||||
|
||||
Tools.add({ //The new tool
|
||||
function press(x, y, evt, isTouchEvent) {
|
||||
if (!handTool.secondary.active) startHand(x, y, evt, isTouchEvent);
|
||||
else startMovingElement(x, y, evt, isTouchEvent);
|
||||
}
|
||||
|
||||
|
||||
function move(x, y, evt, isTouchEvent) {
|
||||
if (!handTool.secondary.active) moveHand(x, y, evt, isTouchEvent);
|
||||
else moveElement(x, y, evt, isTouchEvent);
|
||||
}
|
||||
|
||||
function release(x, y, evt, isTouchEvent) {
|
||||
move(x, y, evt, isTouchEvent);
|
||||
selected = null;
|
||||
}
|
||||
|
||||
function switchTool() {
|
||||
selected = null;
|
||||
}
|
||||
|
||||
var handTool = { //The new tool
|
||||
"name": "Hand",
|
||||
"shortcut": "h",
|
||||
"listeners": {
|
||||
"press": press,
|
||||
"move": move,
|
||||
"release": release
|
||||
"release": release,
|
||||
},
|
||||
"icon": "tools/hand/icon.svg",
|
||||
"secondary": {
|
||||
"name": "Mover",
|
||||
"icon": "tools/hand/mover.svg",
|
||||
"active": false,
|
||||
"switch": switchTool,
|
||||
},
|
||||
"draw": draw,
|
||||
"icon": "tools/hand/hand.svg",
|
||||
"mouseCursor": "move",
|
||||
"showMarker": true,
|
||||
});
|
||||
|
||||
//The hand tool is selected by default
|
||||
Tools.change("Hand");
|
||||
};
|
||||
Tools.add(handTool);
|
||||
Tools.change("Hand"); // Use the hand tool by default
|
||||
})(); //End of code isolation
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<svg viewBox="0 0 72 72" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg viewBox="0 0 70 70" xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
|
||||
<path d="M18.66 19.24a3.53 3.53 0 10-5.57 4.25l11.54 15.1 2.69 3.39-7.9-10.33a3.53 3.53 0 10-5.56 4.24l7.9 10.34 6.26 7.9c5.47 6.27 14.52 5.93 20.79.46a19.62 19.62 0 006.51-12.31c.39-4.23.81-15.3.81-15.3-.18-2.6-3.13-4.52-3.51-3.18l-4.9 9.76-3.36-4.23 3.36 4.23-3.36-4.23-13.47-17.2a3.53 3.53 0 10-5.56 4.24l4.25 5.57L36 30.42 22.58 12.74a3.53 3.53 0 10-5.56 4.25L31.69 36"/>
|
||||
<path stroke-miterlimit="10" d="M11.67 42.87c0 2.57 1.75 4.64 3.9 4.64M7.06 42.44c0 5.6 3.81 10.12 8.52 10.12M45.26 21.24c0-2.57-1.75-4.65-3.9-4.65M49.87 21.67c0-5.6-3.8-10.12-8.51-10.12"/>
|
Before Width: | Height: | Size: 757 B After Width: | Height: | Size: 757 B |
10
client-data/tools/hand/mover.svg
Normal file
10
client-data/tools/hand/mover.svg
Normal file
|
@ -0,0 +1,10 @@
|
|||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 70" >
|
||||
<path id="arrow" stroke="black" fill="none" stroke-width="2" stroke-linecap="round"
|
||||
d="M 8 28 h 54
|
||||
M 8 42 h 54
|
||||
M 57 22 L 70 35 L 57 48
|
||||
" />
|
||||
<use href="#arrow" transform="rotate(90 35 35)"/>
|
||||
<use href="#arrow" transform="rotate(180 35 35)"/>
|
||||
<use href="#arrow" transform="rotate(-90 35 35)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 429 B |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "whitebophir",
|
||||
"description": "Online collaborative whiteboard",
|
||||
"version": "1.5.0",
|
||||
"version": "1.6.0",
|
||||
"keywords": [
|
||||
"collaborative",
|
||||
"whiteboard"
|
||||
|
|
|
@ -70,10 +70,13 @@ BoardData.prototype.addChild = function (parentId, child) {
|
|||
|
||||
/** Update the data in the board
|
||||
* @param {string} id - Identifier of the data to update.
|
||||
* @param {object} data - Object containing the the values to update.
|
||||
* @param {object} data - Object containing the values to update.
|
||||
* @param {boolean} create - True if the object should be created if it's not currently in the DB.
|
||||
*/
|
||||
BoardData.prototype.update = function (id, data, create) {
|
||||
delete data.type;
|
||||
delete data.tool;
|
||||
|
||||
var obj = this.board[id];
|
||||
if (typeof obj === "object") {
|
||||
for (var i in data) {
|
||||
|
|
|
@ -11,7 +11,9 @@ function htmlspecialchars(str) {
|
|||
case '>': return '>';
|
||||
case '&': return '&';
|
||||
case '"': return '"';
|
||||
case "'": return '''; }});
|
||||
case "'": return ''';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renderPath(el, pathstring) {
|
||||
|
@ -23,6 +25,8 @@ function renderPath(el, pathstring) {
|
|||
('opacity="' + parseFloat(el.opacity) + '" ') : '') +
|
||||
'stroke="' + htmlspecialchars(el.color) + '" ' +
|
||||
'd="' + pathstring + '" ' +
|
||||
(el.deltax || el.deltay ?
|
||||
('transform="translate(' + (+el.deltax) + ',' + (+el.deltay) + ')"') : '') +
|
||||
'/>';
|
||||
}
|
||||
|
||||
|
@ -37,6 +41,7 @@ const Tools = {
|
|||
'y="' + (el.y | 0) + '" ' +
|
||||
'font-size="' + (el.size | 0) + '" ' +
|
||||
'fill="' + htmlspecialchars(el.color || "#000") + '" ' +
|
||||
(el.deltax || el.deltay ? ('transform="translate(' + (el.deltax || 0) + ',' + (el.deltay || 0) + ')"') : '') +
|
||||
'>' + htmlspecialchars(el.txt || "") + '</text>';
|
||||
},
|
||||
/**
|
||||
|
@ -65,6 +70,7 @@ const Tools = {
|
|||
'height="' + (el.y2 - el.y) + '" ' +
|
||||
'stroke="' + htmlspecialchars(el.color) + '" ' +
|
||||
'stroke-width="' + (el.size | 0) + '" ' +
|
||||
(el.deltax || el.deltay ? ('transform="translate(' + (el.deltax || 0) + ',' + (el.deltay || 0) + ')"') : '') +
|
||||
'/>';
|
||||
},
|
||||
/**
|
||||
|
@ -100,9 +106,10 @@ async function toSVG(obj, writeable) {
|
|||
const margin = 400;
|
||||
const elems = Object.values(obj);
|
||||
const dim = elems.reduce(function (dim, elem) {
|
||||
if (elem._children) elem = elem._children[0];
|
||||
return [
|
||||
Math.max(elem.x + margin | 0, dim[0]),
|
||||
Math.max(elem.y + margin | 0, dim[1]),
|
||||
Math.max(elem.x + margin + elem.deltax | 0, dim[0]),
|
||||
Math.max(elem.y + margin + elem.deltay | 0, dim[1]),
|
||||
]
|
||||
}, [margin, margin]);
|
||||
writeable.write(
|
||||
|
|
|
@ -140,7 +140,6 @@ async function saveHistory(boardName, message) {
|
|||
if (id) board.delete(id);
|
||||
break;
|
||||
case "update":
|
||||
delete message.type;
|
||||
if (id) board.update(id, message);
|
||||
break;
|
||||
case "child":
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"click_to_toggle": "click to toggle",
|
||||
"menu": "Menu",
|
||||
"text": "Text",
|
||||
"mover": "Mover",
|
||||
"straight_line": "Straight line",
|
||||
"pencil": "Pencil",
|
||||
"grid": "Grid",
|
||||
|
@ -54,6 +55,7 @@
|
|||
"eraser": "Gomme",
|
||||
"white-out": "Blanco",
|
||||
"hand": "Main",
|
||||
"mover": "Déplacer un élément",
|
||||
"straight_line": "Ligne droite",
|
||||
"grid": "Grille",
|
||||
"keyboard_shortcut": "raccourci clavier",
|
||||
|
@ -73,6 +75,7 @@
|
|||
},
|
||||
"de": {
|
||||
"hand": "Hand",
|
||||
"mover": "Verschiebung",
|
||||
"loading": "Lädt",
|
||||
"tagline": "Ein freies quelloffenes kollaboratives Zeichentool. Zeichnet eure Ideen zusammen auf WBO!",
|
||||
"configuration": "Konfiguration",
|
||||
|
@ -110,6 +113,7 @@
|
|||
},
|
||||
"ja": {
|
||||
"hand": "手のひらツール",
|
||||
"mover": "変位",
|
||||
"loading": "読み込み中",
|
||||
"tagline": "無料でオープンソースの協同作業できるオンラインホワイトボード。WBOでアイディアを共有しましょう!",
|
||||
"configuration": "設定",
|
||||
|
@ -157,7 +161,7 @@
|
|||
"text": "Текст",
|
||||
"eraser": "Ластик",
|
||||
"white-out": "Корректор",
|
||||
"hand": "Движение",
|
||||
"hand": "Рука",
|
||||
"straight_line": "Прямая линия",
|
||||
"rectangle": "Прямоугольник",
|
||||
"square": "Квадрат",
|
||||
|
@ -165,8 +169,9 @@
|
|||
"ellipse": "Эллипс",
|
||||
"click_to_toggle": "нажмите, чтобы переключиться",
|
||||
"zoom": "Лупа",
|
||||
"mover": "Сдвинуть объект",
|
||||
"grid": "Сетка",
|
||||
"configuration": "Настроики",
|
||||
"configuration": "Настройки",
|
||||
"keyboard_shortcut": "горячая клавиша",
|
||||
"mousewheel": "колёсико мыши ",
|
||||
"tagline": "Бесплатная и открытая доска для совместной работы в интернете. Рисуете свои идеи вместе в WBO !",
|
||||
|
@ -200,6 +205,7 @@
|
|||
"eraser": "橡皮",
|
||||
"white-out": "修正液",
|
||||
"hand": "移动",
|
||||
"mover": "平移",
|
||||
"straight_line": "直线",
|
||||
"configuration": "刷设置",
|
||||
"keyboard_shortcut": "键盘快捷键",
|
||||
|
@ -220,6 +226,7 @@
|
|||
},
|
||||
"es": {
|
||||
"hand": "Mano",
|
||||
"mover": "Desplazamiento",
|
||||
"loading": "Cargando",
|
||||
"tagline": "Una herramienta de dibujo colaborativa en línea gratuita y de código abierto. Esboce nuevas ideas en la pizarra colaborativa WBO !",
|
||||
"configuration": "Configuration",
|
||||
|
@ -257,6 +264,7 @@
|
|||
},
|
||||
"it": {
|
||||
"hand": "Mano",
|
||||
"mover": "Spostamento",
|
||||
"loading": "Caricamento in corso",
|
||||
"tagline": "Uno strumento collaborativo per disegnare online, gratuito e open source. Disegniamo insieme nuove idee su WBO!",
|
||||
"configuration": "Configurazione",
|
||||
|
|
Loading…
Reference in a new issue