diff --git a/public/css/main.css b/public/css/main.css index db9942a..d62a19d 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -1,3 +1,16 @@ +body { + position: relative; + margin: 0px; + height: calc(var(--vh, 1vh) * 100); + width: 100%; + overflow: hidden; +} + +#whiteboardContainer { + height: calc(var(--vh, 1vh) * 100); + width: 100%; +} + .btn-group button { background: transparent; border: 1px solid #636060; diff --git a/public/index.html b/public/index.html index 4f416f7..6a51ddf 100644 --- a/public/index.html +++ b/public/index.html @@ -32,10 +32,9 @@ - + -
+
diff --git a/public/js/main.js b/public/js/main.js index 96663b0..a26c6f3 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -48,10 +48,10 @@ $(document).ready(function () { if (getQueryVariable("webdav") == "true") { $("#uploadWebDavBtn").show(); } - + console.log(myUsername) whiteboard.loadWhiteboard("#whiteboardContainer", { //Load the whiteboard whiteboardId: whiteboardId, - username: myUsername, + username: btoa(myUsername), sendFunction: function (content) { content["at"] = accessToken; signaling_socket.emit('drawToWhiteboard', content); @@ -102,17 +102,17 @@ $(document).ready(function () { // whiteboard clear button $("#whiteboardTrashBtn").click(function () { $("#whiteboardTrashBtnConfirm").show().focus(); - $(this).css({visibility: "hidden"}); + $(this).css({ visibility: "hidden" }); }); $("#whiteboardTrashBtnConfirm").mouseout(function () { $(this).hide(); - $("#whiteboardTrashBtn").css({visibility: "inherit"}); + $("#whiteboardTrashBtn").css({ visibility: "inherit" }); }); $("#whiteboardTrashBtnConfirm").click(function () { $(this).hide(); - $("#whiteboardTrashBtn").css({visibility: "inherit"}); + $("#whiteboardTrashBtn").css({ visibility: "inherit" }); whiteboard.clearWhiteboard(); }); @@ -175,31 +175,31 @@ $(document).ready(function () { if ($(".webdavUploadBtn").length > 0) { return; } - + var webdavserver = localStorage.getItem('webdavserver') || "" var webdavpath = localStorage.getItem('webdavpath') || "/" var webdavusername = localStorage.getItem('webdavusername') || "" - var webdavpassword =localStorage.getItem('webdavpassword') || "" + var webdavpassword = localStorage.getItem('webdavpassword') || "" var webDavHtml = $('
' + '' + '' + '' + - '' + + '' + '' + '' + '' + '' + - '' + + '' + '' + '' + '' + '' + - '' + + '' + '' + '' + '' + '' + - '' + + '' + '' + '' + '' + @@ -468,7 +468,7 @@ function isValidImageUrl(url, callback) { // handle pasting from clipboard window.addEventListener("paste", function (e) { - if($(".basicalert").length>0) { + if ($(".basicalert").length > 0) { return; } if (e.clipboardData) { diff --git a/public/js/whiteboard.js b/public/js/whiteboard.js index 9f1c2d0..dad81d4 100644 --- a/public/js/whiteboard.js +++ b/public/js/whiteboard.js @@ -1,863 +1,864 @@ var whiteboard = { - canvas: null, - ctx: null, - drawcolor: "black", - tool: "pen", - thickness: 4, - prevX: null, - prevY: null, - latestTouchCoods: [], - drawFlag: false, - oldGCO: null, - mouseover: false, - lineCap: "round", //butt, square - backgroundGrid: null, - canvasElement: null, - cursorContainer: null, - imgContainer: null, - svgContainer: null, //For draw prev - mouseOverlay: null, - ownCursor: null, - drawBuffer: [], - drawId: 0, //Used for undo function - imgDragActive: false, - latestActiveTextBoxId: false, //The id of the latest clicked Textbox (for font and color change) - pressedKeys: {}, - settings: { - whiteboardId: "0", - username: "unknown", - sendFunction: null, - backgroundGridUrl: './images/KtEBa2.png' - }, - loadWhiteboard: function (whiteboardContainer, newSettings) { - var svgns = "http://www.w3.org/2000/svg"; - var _this = this; - for (var i in newSettings) { - this.settings[i] = newSettings[i]; - } - this.settings["username"] = this.settings["username"].replace(/[^0-9a-z]/gi, ''); - this.settings["whiteboardId"] = this.settings["whiteboardId"].replace(/[^0-9a-z]/gi, ''); + canvas: null, + ctx: null, + drawcolor: "black", + tool: "pen", + thickness: 4, + prevX: null, + prevY: null, + latestTouchCoods: [], + drawFlag: false, + oldGCO: null, + mouseover: false, + lineCap: "round", //butt, square + backgroundGrid: null, + canvasElement: null, + cursorContainer: null, + imgContainer: null, + svgContainer: null, //For draw prev + mouseOverlay: null, + ownCursor: null, + drawBuffer: [], + drawId: 0, //Used for undo function + imgDragActive: false, + latestActiveTextBoxId: false, //The id of the latest clicked Textbox (for font and color change) + pressedKeys: {}, + settings: { + whiteboardId: "0", + username: "unknown", + sendFunction: null, + backgroundGridUrl: './images/KtEBa2.png' + }, + loadWhiteboard: function (whiteboardContainer, newSettings) { + var svgns = "http://www.w3.org/2000/svg"; + var _this = this; + for (var i in newSettings) { + this.settings[i] = newSettings[i]; + } + this.settings["username"] = this.settings["username"].replace(/[^0-9a-z]/gi, ''); + this.settings["whiteboardId"] = this.settings["whiteboardId"].replace(/[^0-9a-z]/gi, ''); - var startCoords = []; - var svgLine = null; - var svgRect = null; - var svgCirle = null; - //background grid (repeating image) and smallest screen indication - _this.backgroundGrid = $('
'); - // container for background images - _this.imgContainer = $('
'); - // whiteboard canvas - _this.canvasElement = $(''); - // SVG container holding drawing or moving previews - _this.svgContainer = $(''); - // drag and drop indicator, hidden by default - _this.dropIndicator = $('
') - // container for other users cursors - _this.cursorContainer = $('
'); - // container for texts by users - _this.textContainer = $('
'); - // mouse overlay for draw callbacks - _this.mouseOverlay = $('
'); + var startCoords = []; + var svgLine = null; + var svgRect = null; + var svgCirle = null; + //background grid (repeating image) and smallest screen indication + _this.backgroundGrid = $('
'); + // container for background images + _this.imgContainer = $('
'); + // whiteboard canvas + _this.canvasElement = $(''); + // SVG container holding drawing or moving previews + _this.svgContainer = $(''); + // drag and drop indicator, hidden by default + _this.dropIndicator = $('
') + // container for other users cursors + _this.cursorContainer = $('
'); + // container for texts by users + _this.textContainer = $('
'); + // mouse overlay for draw callbacks + _this.mouseOverlay = $('
'); - $(whiteboardContainer).append(_this.backgroundGrid) - .append(_this.imgContainer) - .append(_this.canvasElement) - .append(_this.svgContainer) - .append(_this.dropIndicator) - .append(_this.cursorContainer) - .append(_this.textContainer) - .append(_this.mouseOverlay); - this.canvas = $("#whiteboardCanvas")[0]; - this.canvas.height = $(window).height(); - this.canvas.width = $(window).width(); - this.ctx = this.canvas.getContext("2d"); - this.oldGCO = this.ctx.globalCompositeOperation; + $(whiteboardContainer).append(_this.backgroundGrid) + .append(_this.imgContainer) + .append(_this.canvasElement) + .append(_this.svgContainer) + .append(_this.dropIndicator) + .append(_this.cursorContainer) + .append(_this.textContainer) + .append(_this.mouseOverlay); + this.canvas = $("#whiteboardCanvas")[0]; + this.canvas.height = $(window).height(); + this.canvas.width = $(window).width(); + this.ctx = this.canvas.getContext("2d"); + this.oldGCO = this.ctx.globalCompositeOperation; - $(window).resize(function () { //Handel resize - var dbCp = JSON.parse(JSON.stringify(_this.drawBuffer)); //Copy the buffer - _this.canvas.width = $(window).width(); - _this.canvas.height = $(window).height(); //Set new canvas height - _this.drawBuffer = []; - _this.loadData(dbCp); //draw old content in - }); + $(window).resize(function () { //Handel resize + var dbCp = JSON.parse(JSON.stringify(_this.drawBuffer)); //Copy the buffer + _this.canvas.width = $(window).width(); + _this.canvas.height = $(window).height(); //Set new canvas height + _this.drawBuffer = []; + _this.loadData(dbCp); //draw old content in + }); - $(_this.mouseOverlay).on("mousedown touchstart", function (e) { - if (_this.imgDragActive || _this.drawFlag) { - return; - } + $(_this.mouseOverlay).on("mousedown touchstart", function (e) { + if (_this.imgDragActive || _this.drawFlag) { + return; + } - _this.drawFlag = true; - _this.prevX = (e.offsetX || e.pageX - $(e.target).offset().left) + 1; - _this.prevY = (e.offsetY || e.pageY - $(e.target).offset().top) + 1; - if (!_this.prevX || !_this.prevY || (_this.prevX == 1 && _this.prevY == 1)) { - var touche = e.touches[0]; - _this.prevX = touche.clientX - $(_this.mouseOverlay).offset().left + 1; - _this.prevY = touche.clientY - $(_this.mouseOverlay).offset().top + 1; - latestTouchCoods = [_this.prevX, _this.prevY]; - } + _this.drawFlag = true; + _this.prevX = (e.offsetX || e.pageX - $(e.target).offset().left) + 1; + _this.prevY = (e.offsetY || e.pageY - $(e.target).offset().top) + 1; + if (!_this.prevX || !_this.prevY || (_this.prevX == 1 && _this.prevY == 1)) { + var touche = e.touches[0]; + _this.prevX = touche.clientX - $(_this.mouseOverlay).offset().left + 1; + _this.prevY = touche.clientY - $(_this.mouseOverlay).offset().top + 1; + latestTouchCoods = [_this.prevX, _this.prevY]; + } - if (_this.tool === "pen") { - _this.drawPenLine(_this.prevX, _this.prevY, _this.prevX, _this.prevY, _this.drawcolor, _this.thickness); - _this.sendFunction({ "t": _this.tool, "d": [_this.prevX, _this.prevY, _this.prevX, _this.prevY], "c": _this.drawcolor, "th": _this.thickness }); - } else if (_this.tool === "eraser") { - _this.drawEraserLine(_this.prevX, _this.prevY, _this.prevX, _this.prevY, _this.thickness); - _this.sendFunction({ "t": _this.tool, "d": [_this.prevX, _this.prevY, _this.prevX, _this.prevY], "th": _this.thickness }); - } else if (_this.tool === "line") { - startCoords = [_this.prevX, _this.prevY]; - svgLine = document.createElementNS(svgns, 'line'); - svgLine.setAttribute('stroke', 'gray'); - svgLine.setAttribute('stroke-dasharray', '5, 5'); - svgLine.setAttribute('x1', _this.prevX); - svgLine.setAttribute('y1', _this.prevY); - svgLine.setAttribute('x2', _this.prevX); - svgLine.setAttribute('y2', _this.prevY); - _this.svgContainer.append(svgLine); - } else if (_this.tool === "rect" || _this.tool === "recSelect") { - _this.svgContainer.find("rect").remove(); - svgRect = document.createElementNS(svgns, 'rect'); - svgRect.setAttribute('stroke', 'gray'); - svgRect.setAttribute('stroke-dasharray', '5, 5'); - svgRect.setAttribute('style', 'fill-opacity:0.0;'); - svgRect.setAttribute('x', _this.prevX); - svgRect.setAttribute('y', _this.prevY); - svgRect.setAttribute('width', 0); - svgRect.setAttribute('height', 0); - _this.svgContainer.append(svgRect); - startCoords = [_this.prevX, _this.prevY]; - } else if (_this.tool === "circle") { - svgCirle = document.createElementNS(svgns, 'circle'); - svgCirle.setAttribute('stroke', 'gray'); - svgCirle.setAttribute('stroke-dasharray', '5, 5'); - svgCirle.setAttribute('style', 'fill-opacity:0.0;'); - svgCirle.setAttribute('cx', _this.prevX); - svgCirle.setAttribute('cy', _this.prevY); - svgCirle.setAttribute('r', 0); - _this.svgContainer.append(svgCirle); - startCoords = [_this.prevX, _this.prevY]; - } - }); + if (_this.tool === "pen") { + _this.drawPenLine(_this.prevX, _this.prevY, _this.prevX, _this.prevY, _this.drawcolor, _this.thickness); + _this.sendFunction({ "t": _this.tool, "d": [_this.prevX, _this.prevY, _this.prevX, _this.prevY], "c": _this.drawcolor, "th": _this.thickness }); + } else if (_this.tool === "eraser") { + _this.drawEraserLine(_this.prevX, _this.prevY, _this.prevX, _this.prevY, _this.thickness); + _this.sendFunction({ "t": _this.tool, "d": [_this.prevX, _this.prevY, _this.prevX, _this.prevY], "th": _this.thickness }); + } else if (_this.tool === "line") { + startCoords = [_this.prevX, _this.prevY]; + svgLine = document.createElementNS(svgns, 'line'); + svgLine.setAttribute('stroke', 'gray'); + svgLine.setAttribute('stroke-dasharray', '5, 5'); + svgLine.setAttribute('x1', _this.prevX); + svgLine.setAttribute('y1', _this.prevY); + svgLine.setAttribute('x2', _this.prevX); + svgLine.setAttribute('y2', _this.prevY); + _this.svgContainer.append(svgLine); + } else if (_this.tool === "rect" || _this.tool === "recSelect") { + _this.svgContainer.find("rect").remove(); + svgRect = document.createElementNS(svgns, 'rect'); + svgRect.setAttribute('stroke', 'gray'); + svgRect.setAttribute('stroke-dasharray', '5, 5'); + svgRect.setAttribute('style', 'fill-opacity:0.0;'); + svgRect.setAttribute('x', _this.prevX); + svgRect.setAttribute('y', _this.prevY); + svgRect.setAttribute('width', 0); + svgRect.setAttribute('height', 0); + _this.svgContainer.append(svgRect); + startCoords = [_this.prevX, _this.prevY]; + } else if (_this.tool === "circle") { + svgCirle = document.createElementNS(svgns, 'circle'); + svgCirle.setAttribute('stroke', 'gray'); + svgCirle.setAttribute('stroke-dasharray', '5, 5'); + svgCirle.setAttribute('style', 'fill-opacity:0.0;'); + svgCirle.setAttribute('cx', _this.prevX); + svgCirle.setAttribute('cy', _this.prevY); + svgCirle.setAttribute('r', 0); + _this.svgContainer.append(svgCirle); + startCoords = [_this.prevX, _this.prevY]; + } + }); - _this.textContainer.on("mousemove touchmove", function (e) { - e.preventDefault(); + _this.textContainer.on("mousemove touchmove", function (e) { + e.preventDefault(); - if (_this.imgDragActive || !$(e.target).hasClass("textcontainer")) { - return; - } + if (_this.imgDragActive || !$(e.target).hasClass("textcontainer")) { + return; + } - var currX = (e.offsetX || e.pageX - $(e.target).offset().left); - var currY = (e.offsetY || e.pageY - $(e.target).offset().top); - _this.sendFunction({ "t": "cursor", "event": "move", "d": [currX, currY], "username": _this.settings.username }); - }) + var currX = (e.offsetX || e.pageX - $(e.target).offset().left); + var currY = (e.offsetY || e.pageY - $(e.target).offset().top); + _this.sendFunction({ "t": "cursor", "event": "move", "d": [currX, currY], "username": _this.settings.username }); + }) - _this.mouseOverlay.on("mousemove touchmove", function (e) { - e.preventDefault(); - if (_this.imgDragActive) { - return; - } - var currX = (e.offsetX || e.pageX - $(e.target).offset().left); - var currY = (e.offsetY || e.pageY - $(e.target).offset().top); - window.requestAnimationFrame(function () { - if ((!currX || !currY) && e.touches && e.touches[0]) { - var touche = e.touches[0]; - currX = touche.clientX - $(_this.mouseOverlay).offset().left; - currY = touche.clientY - $(_this.mouseOverlay).offset().top; - } - _this.latestTouchCoods = [currX, currY]; + _this.mouseOverlay.on("mousemove touchmove", function (e) { + e.preventDefault(); + if (_this.imgDragActive) { + return; + } + var currX = (e.offsetX || e.pageX - $(e.target).offset().left); + var currY = (e.offsetY || e.pageY - $(e.target).offset().top); + window.requestAnimationFrame(function () { + if ((!currX || !currY) && e.touches && e.touches[0]) { + var touche = e.touches[0]; + currX = touche.clientX - $(_this.mouseOverlay).offset().left; + currY = touche.clientY - $(_this.mouseOverlay).offset().top; + } + _this.latestTouchCoods = [currX, currY]; - if (_this.drawFlag) { - if (_this.tool === "pen") { - _this.drawPenLine(currX, currY, _this.prevX, _this.prevY, _this.drawcolor, _this.thickness); - _this.sendFunction({ "t": _this.tool, "d": [currX, currY, _this.prevX, _this.prevY], "c": _this.drawcolor, "th": _this.thickness }); - } else if (_this.tool == "eraser") { - _this.drawEraserLine(currX, currY, _this.prevX, _this.prevY, _this.thickness); - _this.sendFunction({ "t": _this.tool, "d": [currX, currY, _this.prevX, _this.prevY], "th": _this.thickness }); - } - _this.prevX = currX; - _this.prevY = currY; - } + if (_this.drawFlag) { + if (_this.tool === "pen") { + _this.drawPenLine(currX, currY, _this.prevX, _this.prevY, _this.drawcolor, _this.thickness); + _this.sendFunction({ "t": _this.tool, "d": [currX, currY, _this.prevX, _this.prevY], "c": _this.drawcolor, "th": _this.thickness }); + } else if (_this.tool == "eraser") { + _this.drawEraserLine(currX, currY, _this.prevX, _this.prevY, _this.thickness); + _this.sendFunction({ "t": _this.tool, "d": [currX, currY, _this.prevX, _this.prevY], "th": _this.thickness }); + } + _this.prevX = currX; + _this.prevY = currY; + } - if (_this.tool === "eraser") { - var left = currX - _this.thickness; - var top = currY - _this.thickness; - if (_this.ownCursor) _this.ownCursor.css({ "top": top + "px", "left": left + "px" }); - } else if (_this.tool === "pen") { - var left = currX - _this.thickness / 2; - var top = currY - _this.thickness / 2; - if (_this.ownCursor) _this.ownCursor.css({ "top": top + "px", "left": left + "px" }); - } else if (_this.tool === "line") { - if (svgLine) { - if (_this.pressedKeys.shift) { - var angs = getRoundedAngles(currX, currY); - currX = angs.x; - currY = angs.y; - } - svgLine.setAttribute('x2', currX); - svgLine.setAttribute('y2', currY); - } - } else if (_this.tool === "rect" || (_this.tool === "recSelect" && _this.drawFlag)) { - if (svgRect) { - var width = Math.abs(currX - startCoords[0]); - var height = Math.abs(currY - startCoords[1]); - if (_this.pressedKeys.shift) { - height = width; - var x = currX < startCoords[0] ? startCoords[0] - width : startCoords[0]; - var y = currY < startCoords[1] ? startCoords[1] - width : startCoords[1]; - svgRect.setAttribute('x', x); - svgRect.setAttribute('y', y); - } else { - var x = currX < startCoords[0] ? currX : startCoords[0]; - var y = currY < startCoords[1] ? currY : startCoords[1]; - svgRect.setAttribute('x', x); - svgRect.setAttribute('y', y); - } + if (_this.tool === "eraser") { + var left = currX - _this.thickness; + var top = currY - _this.thickness; + if (_this.ownCursor) _this.ownCursor.css({ "top": top + "px", "left": left + "px" }); + } else if (_this.tool === "pen") { + var left = currX - _this.thickness / 2; + var top = currY - _this.thickness / 2; + if (_this.ownCursor) _this.ownCursor.css({ "top": top + "px", "left": left + "px" }); + } else if (_this.tool === "line") { + if (svgLine) { + if (_this.pressedKeys.shift) { + var angs = getRoundedAngles(currX, currY); + currX = angs.x; + currY = angs.y; + } + svgLine.setAttribute('x2', currX); + svgLine.setAttribute('y2', currY); + } + } else if (_this.tool === "rect" || (_this.tool === "recSelect" && _this.drawFlag)) { + if (svgRect) { + var width = Math.abs(currX - startCoords[0]); + var height = Math.abs(currY - startCoords[1]); + if (_this.pressedKeys.shift) { + height = width; + var x = currX < startCoords[0] ? startCoords[0] - width : startCoords[0]; + var y = currY < startCoords[1] ? startCoords[1] - width : startCoords[1]; + svgRect.setAttribute('x', x); + svgRect.setAttribute('y', y); + } else { + var x = currX < startCoords[0] ? currX : startCoords[0]; + var y = currY < startCoords[1] ? currY : startCoords[1]; + svgRect.setAttribute('x', x); + svgRect.setAttribute('y', y); + } - svgRect.setAttribute('width', width); - svgRect.setAttribute('height', height); - } - } else if (_this.tool === "circle") { - var a = currX - startCoords[0]; - var b = currY - startCoords[1]; - var r = Math.sqrt(a * a + b * b); - if (svgCirle) { - svgCirle.setAttribute('r', r); - } - } - }); - _this.sendFunction({ "t": "cursor", "event": "move", "d": [currX, currY], "username": _this.settings.username }); - }); + svgRect.setAttribute('width', width); + svgRect.setAttribute('height', height); + } + } else if (_this.tool === "circle") { + var a = currX - startCoords[0]; + var b = currY - startCoords[1]; + var r = Math.sqrt(a * a + b * b); + if (svgCirle) { + svgCirle.setAttribute('r', r); + } + } + }); + _this.sendFunction({ "t": "cursor", "event": "move", "d": [currX, currY], "username": _this.settings.username }); + }); - _this.mouseOverlay.on("mouseup touchend touchcancel", function (e) { - if (_this.imgDragActive) { - return; - } - _this.drawFlag = false; - _this.drawId++; - _this.ctx.globalCompositeOperation = _this.oldGCO; - var currX = (e.offsetX || e.pageX - $(e.target).offset().left); - var currY = (e.offsetY || e.pageY - $(e.target).offset().top); + _this.mouseOverlay.on("mouseup touchend touchcancel", function (e) { + if (_this.imgDragActive) { + return; + } + _this.drawFlag = false; + _this.drawId++; + _this.ctx.globalCompositeOperation = _this.oldGCO; + var currX = (e.offsetX || e.pageX - $(e.target).offset().left); + var currY = (e.offsetY || e.pageY - $(e.target).offset().top); - if (!currX || !currY) { - currX = _this.latestTouchCoods[0]; - currY = _this.latestTouchCoods[1]; - _this.sendFunction({ "t": "cursor", "event": "out", "username": _this.settings.username }); - } + if (!currX || !currY) { + currX = _this.latestTouchCoods[0]; + currY = _this.latestTouchCoods[1]; + _this.sendFunction({ "t": "cursor", "event": "out", "username": _this.settings.username }); + } - if (_this.tool === "line") { - if (_this.pressedKeys.shift) { - var angs = getRoundedAngles(currX, currY); - currX = angs.x; - currY = angs.y; - } - _this.drawPenLine(currX, currY, startCoords[0], startCoords[1], _this.drawcolor, _this.thickness); - _this.sendFunction({ "t": _this.tool, "d": [currX, currY, startCoords[0], startCoords[1]], "c": _this.drawcolor, "th": _this.thickness }); - _this.svgContainer.find("line").remove(); - } else if (_this.tool === "rect") { - if (_this.pressedKeys.shift) { - if ((currY - startCoords[1]) * (currX - startCoords[0]) > 0) { - currY = startCoords[1] + (currX - startCoords[0]); - } else { - currY = startCoords[1] - (currX - startCoords[0]); - } - } - _this.drawRec(startCoords[0], startCoords[1], currX, currY, _this.drawcolor, _this.thickness); - _this.sendFunction({ "t": _this.tool, "d": [startCoords[0], startCoords[1], currX, currY], "c": _this.drawcolor, "th": _this.thickness }); - _this.svgContainer.find("rect").remove(); - } else if (_this.tool === "circle") { - var a = currX - startCoords[0]; - var b = currY - startCoords[1]; - var r = Math.sqrt(a * a + b * b); - _this.drawCircle(startCoords[0], startCoords[1], r, _this.drawcolor, _this.thickness); - _this.sendFunction({ "t": _this.tool, "d": [startCoords[0], startCoords[1], r], "c": _this.drawcolor, "th": _this.thickness }); - _this.svgContainer.find("circle").remove(); - } else if (_this.tool === "recSelect") { - _this.imgDragActive = true; - if (_this.pressedKeys.shift) { - if ((currY - startCoords[1]) * (currX - startCoords[0]) > 0) { - currY = startCoords[1] + (currX - startCoords[0]); - } else { - currY = startCoords[1] - (currX - startCoords[0]); - } - } + if (_this.tool === "line") { + if (_this.pressedKeys.shift) { + var angs = getRoundedAngles(currX, currY); + currX = angs.x; + currY = angs.y; + } + _this.drawPenLine(currX, currY, startCoords[0], startCoords[1], _this.drawcolor, _this.thickness); + _this.sendFunction({ "t": _this.tool, "d": [currX, currY, startCoords[0], startCoords[1]], "c": _this.drawcolor, "th": _this.thickness }); + _this.svgContainer.find("line").remove(); + } else if (_this.tool === "rect") { + if (_this.pressedKeys.shift) { + if ((currY - startCoords[1]) * (currX - startCoords[0]) > 0) { + currY = startCoords[1] + (currX - startCoords[0]); + } else { + currY = startCoords[1] - (currX - startCoords[0]); + } + } + _this.drawRec(startCoords[0], startCoords[1], currX, currY, _this.drawcolor, _this.thickness); + _this.sendFunction({ "t": _this.tool, "d": [startCoords[0], startCoords[1], currX, currY], "c": _this.drawcolor, "th": _this.thickness }); + _this.svgContainer.find("rect").remove(); + } else if (_this.tool === "circle") { + var a = currX - startCoords[0]; + var b = currY - startCoords[1]; + var r = Math.sqrt(a * a + b * b); + _this.drawCircle(startCoords[0], startCoords[1], r, _this.drawcolor, _this.thickness); + _this.sendFunction({ "t": _this.tool, "d": [startCoords[0], startCoords[1], r], "c": _this.drawcolor, "th": _this.thickness }); + _this.svgContainer.find("circle").remove(); + } else if (_this.tool === "recSelect") { + _this.imgDragActive = true; + if (_this.pressedKeys.shift) { + if ((currY - startCoords[1]) * (currX - startCoords[0]) > 0) { + currY = startCoords[1] + (currX - startCoords[0]); + } else { + currY = startCoords[1] - (currX - startCoords[0]); + } + } - var width = Math.abs(startCoords[0] - currX); - var height = Math.abs(startCoords[1] - currY); - var left = startCoords[0] < currX ? startCoords[0] : currX; - var top = startCoords[1] < currY ? startCoords[1] : currY; - _this.mouseOverlay.css({ "cursor": "default" }); - var imgDiv = $('
' + - '' + - '
' + - ' ' + - '' + - '
' + - '
'); - var dragCanvas = $(imgDiv).find("canvas"); - var dragOutOverlay = $('
'); - _this.mouseOverlay.append(dragOutOverlay); - _this.mouseOverlay.append(imgDiv); + var width = Math.abs(startCoords[0] - currX); + var height = Math.abs(startCoords[1] - currY); + var left = startCoords[0] < currX ? startCoords[0] : currX; + var top = startCoords[1] < currY ? startCoords[1] : currY; + _this.mouseOverlay.css({ "cursor": "default" }); + var imgDiv = $('
' + + '' + + '
' + + ' ' + + '' + + '
' + + '
'); + var dragCanvas = $(imgDiv).find("canvas"); + var dragOutOverlay = $('
'); + _this.mouseOverlay.append(dragOutOverlay); + _this.mouseOverlay.append(imgDiv); - var destCanvasContext = dragCanvas[0].getContext('2d'); - destCanvasContext.drawImage(_this.canvas, left, top, width, height, 0, 0, width, height); - imgDiv.find(".xCanvasBtn").click(function () { - _this.imgDragActive = false; - _this.refreshCursorAppearance(); - imgDiv.remove(); - dragOutOverlay.remove(); - }); - imgDiv.find(".addToCanvasBtn").click(function () { - _this.imgDragActive = false; - _this.refreshCursorAppearance(); - var p = imgDiv.position(); - var leftT = Math.round(p.left * 100) / 100; - var topT = Math.round(p.top * 100) / 100; - _this.drawId++; - _this.sendFunction({ "t": _this.tool, "d": [left, top, leftT, topT, width, height] }); - _this.dragCanvasRectContent(left, top, leftT, topT, width, height); - imgDiv.remove(); - dragOutOverlay.remove(); - }); - imgDiv.draggable(); - _this.svgContainer.find("rect").remove(); - } - }); + var destCanvasContext = dragCanvas[0].getContext('2d'); + destCanvasContext.drawImage(_this.canvas, left, top, width, height, 0, 0, width, height); + imgDiv.find(".xCanvasBtn").click(function () { + _this.imgDragActive = false; + _this.refreshCursorAppearance(); + imgDiv.remove(); + dragOutOverlay.remove(); + }); + imgDiv.find(".addToCanvasBtn").click(function () { + _this.imgDragActive = false; + _this.refreshCursorAppearance(); + var p = imgDiv.position(); + var leftT = Math.round(p.left * 100) / 100; + var topT = Math.round(p.top * 100) / 100; + _this.drawId++; + _this.sendFunction({ "t": _this.tool, "d": [left, top, leftT, topT, width, height] }); + _this.dragCanvasRectContent(left, top, leftT, topT, width, height); + imgDiv.remove(); + dragOutOverlay.remove(); + }); + imgDiv.draggable(); + _this.svgContainer.find("rect").remove(); + } + }); - _this.mouseOverlay.on("mouseout", function (e) { - if (_this.imgDragActive) { - return; - } - _this.drawFlag = false; - _this.mouseover = false; - _this.ctx.globalCompositeOperation = _this.oldGCO; - if (_this.ownCursor) _this.ownCursor.remove(); - _this.svgContainer.find("line").remove(); - _this.svgContainer.find("rect").remove(); - _this.svgContainer.find("circle").remove(); - _this.sendFunction({ "t": "cursor", "event": "out" }); - }); + _this.mouseOverlay.on("mouseout", function (e) { + if (_this.imgDragActive) { + return; + } + _this.drawFlag = false; + _this.mouseover = false; + _this.ctx.globalCompositeOperation = _this.oldGCO; + if (_this.ownCursor) _this.ownCursor.remove(); + _this.svgContainer.find("line").remove(); + _this.svgContainer.find("rect").remove(); + _this.svgContainer.find("circle").remove(); + _this.sendFunction({ "t": "cursor", "event": "out" }); + }); - _this.mouseOverlay.on("mouseover", function (e) { - if (_this.imgDragActive) { - return; - } - if (!_this.mouseover) { - var color = _this.drawcolor; - var widthHeight = _this.thickness; - if (_this.tool === "eraser") { - color = "#00000000"; - widthHeight = widthHeight * 2; - } - if (_this.tool === "eraser" || _this.tool === "pen") { - _this.ownCursor = $('
'); - _this.cursorContainer.append(_this.ownCursor); - } - } - _this.mouseover = true; - }); + _this.mouseOverlay.on("mouseover", function (e) { + if (_this.imgDragActive) { + return; + } + if (!_this.mouseover) { + var color = _this.drawcolor; + var widthHeight = _this.thickness; + if (_this.tool === "eraser") { + color = "#00000000"; + widthHeight = widthHeight * 2; + } + if (_this.tool === "eraser" || _this.tool === "pen") { + _this.ownCursor = $('
'); + _this.cursorContainer.append(_this.ownCursor); + } + } + _this.mouseover = true; + }); - //On textcontainer click (Add a new textbox) - _this.textContainer.on("click", function (e) { - currX = (e.offsetX || e.pageX - $(e.target).offset().left); - currY = (e.offsetY || e.pageY - $(e.target).offset().top); - var fontsize = _this.thickness * 0.5; - var txId = 'tx' + (+new Date()); - _this.sendFunction({ "t": "addTextBox", "d": [_this.drawcolor, fontsize, currX, currY, txId] }); - _this.addTextBox(_this.drawcolor, fontsize, currX, currY, txId, true); - }); + //On textcontainer click (Add a new textbox) + _this.textContainer.on("click", function (e) { + currX = (e.offsetX || e.pageX - $(e.target).offset().left); + currY = (e.offsetY || e.pageY - $(e.target).offset().top); + var fontsize = _this.thickness * 0.5; + var txId = 'tx' + (+new Date()); + _this.sendFunction({ "t": "addTextBox", "d": [_this.drawcolor, fontsize, currX, currY, txId] }); + _this.addTextBox(_this.drawcolor, fontsize, currX, currY, txId, true); + }); - function getRoundedAngles(currX, currY) { //For drawing lines at 0,45,90° .... - var x = currX - startCoords[0]; - var y = currY - startCoords[1]; - var angle = Math.atan2(x, y) * (180 / Math.PI); - var angle45 = Math.round(angle / 45) * 45; - if (angle45 % 90 == 0) { - if (Math.abs(currX - startCoords[0]) > Math.abs(currY - startCoords[1])) { - currY = startCoords[1] - } else { - currX = startCoords[0] - } - } else { - if ((currY - startCoords[1]) * (currX - startCoords[0]) > 0) { - currX = startCoords[0] + (currY - startCoords[1]); - } else { - currX = startCoords[0] - (currY - startCoords[1]); - } - } - return { "x": currX, "y": currY }; - } - }, - entfKeyAction: function () { - var _this = this; - $.each(_this.mouseOverlay.find(".dragOutOverlay"), function () { - var width = $(this).width(); - var height = $(this).height(); - var p = $(this).position(); - var left = Math.round(p.left * 100) / 100; - var top = Math.round(p.top * 100) / 100; - _this.drawId++; - _this.sendFunction({ "t": "eraseRec", "d": [left, top, width, height] }); - _this.eraseRec(left, top, width, height); - }); - _this.mouseOverlay.find(".xCanvasBtn").click(); //Remove all current drops - }, - escKeyAction: function () { - var _this = this; - if (!_this.drawFlag) { - _this.svgContainer.empty(); - } - _this.mouseOverlay.find(".xCanvasBtn").click(); //Remove all current drops - }, - dragCanvasRectContent: function (xf, yf, xt, yt, width, height) { - var tempCanvas = document.createElement('canvas'); - tempCanvas.width = width; - tempCanvas.height = height; - var tempCanvasContext = tempCanvas.getContext('2d'); - tempCanvasContext.drawImage(this.canvas, xf, yf, width, height, 0, 0, width, height); - this.eraseRec(xf, yf, width, height); - this.ctx.drawImage(tempCanvas, xt, yt); - }, - eraseRec: function (fromX, fromY, width, height) { - var _this = this; - _this.ctx.beginPath(); - _this.ctx.rect(fromX, fromY, width, height); - _this.ctx.fillStyle = "rgba(0,0,0,1)"; - _this.ctx.globalCompositeOperation = "destination-out"; - _this.ctx.fill(); - _this.ctx.closePath(); - _this.ctx.globalCompositeOperation = _this.oldGCO; - }, - drawPenLine: function (fromX, fromY, toX, toY, color, thickness) { - var _this = this; - _this.ctx.beginPath(); - _this.ctx.moveTo(fromX, fromY); - _this.ctx.lineTo(toX, toY); - _this.ctx.strokeStyle = color; - _this.ctx.lineWidth = thickness; - _this.ctx.lineCap = _this.lineCap; - _this.ctx.stroke(); - _this.ctx.closePath(); - }, - drawEraserLine: function (fromX, fromY, toX, toY, thickness) { - var _this = this; - _this.ctx.beginPath(); - _this.ctx.moveTo(fromX, fromY); - _this.ctx.lineTo(toX, toY); - _this.ctx.strokeStyle = "rgba(0,0,0,1)"; - _this.ctx.lineWidth = thickness * 2; - _this.ctx.lineCap = _this.lineCap; - _this.ctx.globalCompositeOperation = "destination-out"; - _this.ctx.stroke(); - _this.ctx.closePath(); - _this.ctx.globalCompositeOperation = _this.oldGCO; - }, - drawRec: function (fromX, fromY, toX, toY, color, thickness) { - var _this = this; - toX = toX - fromX; - toY = toY - fromY; - _this.ctx.beginPath(); - _this.ctx.rect(fromX, fromY, toX, toY); - _this.ctx.strokeStyle = color; - _this.ctx.lineWidth = thickness; - _this.ctx.lineCap = _this.lineCap; - _this.ctx.stroke(); - _this.ctx.closePath(); - }, - drawCircle: function (fromX, fromY, radius, color, thickness) { - var _this = this; - _this.ctx.beginPath(); - _this.ctx.arc(fromX, fromY, radius, 0, 2 * Math.PI, false); - _this.ctx.lineWidth = thickness; - _this.ctx.strokeStyle = color; - _this.ctx.stroke(); - }, - clearWhiteboard: function () { - var _this = this; - _this.canvas.height = _this.canvas.height; - _this.imgContainer.empty(); - _this.textContainer.empty(); - _this.sendFunction({ "t": "clear" }); - _this.drawBuffer = []; - _this.drawId = 0; - }, - setStrokeThickness(thickness) { - var _this = this; - _this.thickness = thickness; + function getRoundedAngles(currX, currY) { //For drawing lines at 0,45,90° .... + var x = currX - startCoords[0]; + var y = currY - startCoords[1]; + var angle = Math.atan2(x, y) * (180 / Math.PI); + var angle45 = Math.round(angle / 45) * 45; + if (angle45 % 90 == 0) { + if (Math.abs(currX - startCoords[0]) > Math.abs(currY - startCoords[1])) { + currY = startCoords[1] + } else { + currX = startCoords[0] + } + } else { + if ((currY - startCoords[1]) * (currX - startCoords[0]) > 0) { + currX = startCoords[0] + (currY - startCoords[1]); + } else { + currX = startCoords[0] - (currY - startCoords[1]); + } + } + return { "x": currX, "y": currY }; + } + }, + entfKeyAction: function () { + var _this = this; + $.each(_this.mouseOverlay.find(".dragOutOverlay"), function () { + var width = $(this).width(); + var height = $(this).height(); + var p = $(this).position(); + var left = Math.round(p.left * 100) / 100; + var top = Math.round(p.top * 100) / 100; + _this.drawId++; + _this.sendFunction({ "t": "eraseRec", "d": [left, top, width, height] }); + _this.eraseRec(left, top, width, height); + }); + _this.mouseOverlay.find(".xCanvasBtn").click(); //Remove all current drops + }, + escKeyAction: function () { + var _this = this; + if (!_this.drawFlag) { + _this.svgContainer.empty(); + } + _this.mouseOverlay.find(".xCanvasBtn").click(); //Remove all current drops + }, + dragCanvasRectContent: function (xf, yf, xt, yt, width, height) { + var tempCanvas = document.createElement('canvas'); + tempCanvas.width = width; + tempCanvas.height = height; + var tempCanvasContext = tempCanvas.getContext('2d'); + tempCanvasContext.drawImage(this.canvas, xf, yf, width, height, 0, 0, width, height); + this.eraseRec(xf, yf, width, height); + this.ctx.drawImage(tempCanvas, xt, yt); + }, + eraseRec: function (fromX, fromY, width, height) { + var _this = this; + _this.ctx.beginPath(); + _this.ctx.rect(fromX, fromY, width, height); + _this.ctx.fillStyle = "rgba(0,0,0,1)"; + _this.ctx.globalCompositeOperation = "destination-out"; + _this.ctx.fill(); + _this.ctx.closePath(); + _this.ctx.globalCompositeOperation = _this.oldGCO; + }, + drawPenLine: function (fromX, fromY, toX, toY, color, thickness) { + var _this = this; + _this.ctx.beginPath(); + _this.ctx.moveTo(fromX, fromY); + _this.ctx.lineTo(toX, toY); + _this.ctx.strokeStyle = color; + _this.ctx.lineWidth = thickness; + _this.ctx.lineCap = _this.lineCap; + _this.ctx.stroke(); + _this.ctx.closePath(); + }, + drawEraserLine: function (fromX, fromY, toX, toY, thickness) { + var _this = this; + _this.ctx.beginPath(); + _this.ctx.moveTo(fromX, fromY); + _this.ctx.lineTo(toX, toY); + _this.ctx.strokeStyle = "rgba(0,0,0,1)"; + _this.ctx.lineWidth = thickness * 2; + _this.ctx.lineCap = _this.lineCap; + _this.ctx.globalCompositeOperation = "destination-out"; + _this.ctx.stroke(); + _this.ctx.closePath(); + _this.ctx.globalCompositeOperation = _this.oldGCO; + }, + drawRec: function (fromX, fromY, toX, toY, color, thickness) { + var _this = this; + toX = toX - fromX; + toY = toY - fromY; + _this.ctx.beginPath(); + _this.ctx.rect(fromX, fromY, toX, toY); + _this.ctx.strokeStyle = color; + _this.ctx.lineWidth = thickness; + _this.ctx.lineCap = _this.lineCap; + _this.ctx.stroke(); + _this.ctx.closePath(); + }, + drawCircle: function (fromX, fromY, radius, color, thickness) { + var _this = this; + _this.ctx.beginPath(); + _this.ctx.arc(fromX, fromY, radius, 0, 2 * Math.PI, false); + _this.ctx.lineWidth = thickness; + _this.ctx.strokeStyle = color; + _this.ctx.stroke(); + }, + clearWhiteboard: function () { + var _this = this; + _this.canvas.height = _this.canvas.height; + _this.imgContainer.empty(); + _this.textContainer.empty(); + _this.sendFunction({ "t": "clear" }); + _this.drawBuffer = []; + _this.drawId = 0; + }, + setStrokeThickness(thickness) { + var _this = this; + _this.thickness = thickness; - if (_this.tool == "text" && _this.latestActiveTextBoxId) { - _this.sendFunction({ "t": "setTextboxFontSize", "d": [_this.latestActiveTextBoxId, thickness] }); - _this.setTextboxFontSize(_this.latestActiveTextBoxId, thickness); - } - }, - addImgToCanvasByUrl: function (url) { - var _this = this; - var wasTextTool = false; - if (_this.tool === "text") { - wasTextTool = true; - _this.setTool("mouse"); //Set to mouse tool while dropping to prevent errors - } - _this.imgDragActive = true; - _this.mouseOverlay.css({ "cursor": "default" }); - var imgDiv = $('
' + - '' + - '
' + - ' ' + - ' ' + - '' + - '
' + - '' + - '
'); - imgDiv.find(".xCanvasBtn").click(function () { - _this.imgDragActive = false; - _this.refreshCursorAppearance(); - imgDiv.remove(); - if (wasTextTool) { - _this.setTool("text"); - } - }); - imgDiv.find(".addToCanvasBtn").click(function () { - var draw = $(this).attr("draw"); - _this.imgDragActive = false; - _this.refreshCursorAppearance(); - var width = imgDiv.width(); - var height = imgDiv.height(); - var p = imgDiv.position(); - var left = Math.round(p.left * 100) / 100; - var top = Math.round(p.top * 100) / 100; - if (draw == "1") { //draw image to canvas - _this.drawImgToCanvas(url, width, height, left, top); - } else { //Add image to background - _this.drawImgToBackground(url, width, height, left, top); - } - _this.sendFunction({ "t": "addImgBG", "draw": draw, "url": url, "d": [width, height, left, top] }); - _this.drawId++; - imgDiv.remove(); - if (wasTextTool) { - _this.setTool("text"); - } - }); - _this.mouseOverlay.append(imgDiv); - imgDiv.draggable(); - imgDiv.resizable(); - }, - drawImgToBackground(url, width, height, left, top) { - this.imgContainer.append('') - }, - addTextBox(textcolor, fontsize, left, top, txId, newLocalBox) { - var _this = this; - var textBox = $('
' + - '
' + - '
x
' + - '
' + - '
'); - _this.latestActiveTextBoxId = txId; - textBox.click(function (e) { - e.preventDefault(); - _this.latestActiveTextBoxId = txId; - return false; - }) - textBox.on("mousemove touchmove", function (e) { - e.preventDefault(); - if (_this.imgDragActive) { - return; - } - var textBoxPosition = textBox.position(); - var currX = (e.offsetX + textBoxPosition.left); - var currY = (e.offsetY + textBoxPosition.top); - if ($(e.target).hasClass("removeIcon")) { - currX += textBox.width() - 4; - } - _this.sendFunction({ "t": "cursor", "event": "move", "d": [currX, currY], "username": _this.settings.username }); - }) - this.textContainer.append(textBox); - textBox.draggable({ - handle: ".moveIcon", - stop: function () { - var textBoxPosition = textBox.position(); - _this.sendFunction({ "t": "setTextboxPosition", "d": [txId, textBoxPosition.top, textBoxPosition.left] }); - }, - drag: function () { - var textBoxPosition = textBox.position(); - _this.sendFunction({ "t": "setTextboxPosition", "d": [txId, textBoxPosition.top, textBoxPosition.left] }); - } - }); - textBox.find(".textContent").on("input", function () { - var text = btoa($(this).html()); //Get html and make encode base64 - _this.sendFunction({ "t": "setTextboxText", "d": [txId, text] }); - }); - textBox.find(".removeIcon").click(function (e) { - $("#" + txId).remove(); - _this.sendFunction({ "t": "removeTextbox", "d": [txId] }); - e.preventDefault(); - return false; - }); - if (newLocalBox) { - textBox.find(".textContent").focus(); - } - if (this.tool === "text") { - textBox.addClass("active"); - } - }, - setTextboxText(txId, text) { - $("#" + txId).find(".textContent").html(atob(text)); //Set decoded base64 as html - }, - removeTextbox(txId) { - $("#" + txId).remove(); - }, - setTextboxPosition(txId, top, left) { - $("#" + txId).css({ "top": top + "px", "left": left + "px" }); - }, - setTextboxFontSize(txId, fontSize) { - $("#" + txId).find(".textContent").css({ "font-size": fontSize + "em" }); - }, - setTextboxFontColor(txId, color) { - $("#" + txId).find(".textContent").css({ "color": color }); - }, - drawImgToCanvas(url, width, height, left, top, doneCallback) { - var _this = this; - var img = document.createElement('img'); - img.onload = function () { - _this.ctx.drawImage(img, left, top, width, height); - if (doneCallback) { - doneCallback(); - } - } - img.src = url; - }, - undoWhiteboard: function (username) { //Not call this directly because you will get out of sync whit others... - var _this = this; - if (!username) { - username = _this.settings.username; - } - for (var i = _this.drawBuffer.length - 1; i >= 0; i--) { - if (_this.drawBuffer[i]["username"] == username) { - var drawId = _this.drawBuffer[i]["drawId"]; - for (var i = _this.drawBuffer.length - 1; i >= 0; i--) { - if (_this.drawBuffer[i]["drawId"] == drawId && _this.drawBuffer[i]["username"] == username) { - _this.drawBuffer.splice(i, 1); - } - } - break; - } - } - _this.canvas.height = _this.canvas.height; - _this.imgContainer.empty(); - _this.loadDataInSteps(_this.drawBuffer, false, function (stepData) { - //Nothing to do - }); - }, - undoWhiteboardClick: function () { - this.sendFunction({ "t": "undo" }); - this.undoWhiteboard(); - }, - setTool: function (tool) { - this.tool = tool; - if (this.tool === "text") { - $(".textBox").addClass("active"); - this.textContainer.appendTo($(whiteboardContainer)); //Bring textContainer to the front - } else { - $(".textBox").removeClass("active"); - this.mouseOverlay.appendTo($(whiteboardContainer)); - } - this.refreshCursorAppearance(); - this.mouseOverlay.find(".xCanvasBtn").click(); - this.latestActiveTextBoxId = null; - }, - setDrawColor(color) { - var _this = this; - _this.drawcolor = color; - if (_this.tool == "text" && _this.latestActiveTextBoxId) { - _this.sendFunction({ "t": "setTextboxFontColor", "d": [_this.latestActiveTextBoxId, color] }); - _this.setTextboxFontColor(_this.latestActiveTextBoxId, color); - } - }, - updateSmallestScreenResolution(width, height) { - this.backgroundGrid.empty(); - if (width < $(window).width() || height < $(window).height()) { - this.backgroundGrid.append('
'); - this.backgroundGrid.append('
smallest screen participating
'); - } - }, - handleEventsAndData: function (content, isNewData, doneCallback) { - var _this = this; - var tool = content["t"]; - var data = content["d"]; - var color = content["c"]; - var username = content["username"]; - var thickness = content["th"]; - window.requestAnimationFrame(function () { - if (tool === "line" || tool === "pen") { - _this.drawPenLine(data[0], data[1], data[2], data[3], color, thickness); - } else if (tool === "rect") { - _this.drawRec(data[0], data[1], data[2], data[3], color, thickness); - } else if (tool === "circle") { - _this.drawCircle(data[0], data[1], data[2], color, thickness); - } else if (tool === "eraser") { - _this.drawEraserLine(data[0], data[1], data[2], data[3], thickness); - } else if (tool === "eraseRec") { - _this.eraseRec(data[0], data[1], data[2], data[3]); - } else if (tool === "recSelect") { - _this.dragCanvasRectContent(data[0], data[1], data[2], data[3], data[4], data[5]); - } else if (tool === "addImgBG") { - if (content["draw"] == "1") { - _this.drawImgToCanvas(content["url"], data[0], data[1], data[2], data[3], doneCallback) - } else { - _this.drawImgToBackground(content["url"], data[0], data[1], data[2], data[3]); - } - } else if (tool === "addTextBox") { - _this.addTextBox(data[0], data[1], data[2], data[3], data[4]); - } else if (tool === "setTextboxText") { - _this.setTextboxText(data[0], data[1]); - } else if (tool === "removeTextbox") { - _this.removeTextbox(data[0]); - } else if (tool === "setTextboxPosition") { - _this.setTextboxPosition(data[0], data[1], data[2]); - } else if (tool === "setTextboxFontSize") { - _this.setTextboxFontSize(data[0], data[1]); - } else if (tool === "setTextboxFontColor") { - _this.setTextboxFontColor(data[0], data[1]); - } else if (tool === "clear") { - _this.canvas.height = _this.canvas.height; - _this.imgContainer.empty(); - _this.textContainer.empty(); - _this.drawBuffer = []; - _this.drawId = 0; - } else if (tool === "cursor" && _this.settings) { - if (content["event"] === "move") { - if (_this.cursorContainer.find("." + content["username"]).length >= 1) { - _this.cursorContainer.find("." + content["username"]).css({ "left": data[0] + "px", "top": (data[1] - 15) + "px" }); - } else { - _this.cursorContainer.append('
' + - '
' + - content["username"] + '
'); - } - } else { - _this.cursorContainer.find("." + content["username"]).remove(); - } - } else if (tool === "undo") { - _this.undoWhiteboard(username); - } - }); + if (_this.tool == "text" && _this.latestActiveTextBoxId) { + _this.sendFunction({ "t": "setTextboxFontSize", "d": [_this.latestActiveTextBoxId, thickness] }); + _this.setTextboxFontSize(_this.latestActiveTextBoxId, thickness); + } + }, + addImgToCanvasByUrl: function (url) { + var _this = this; + var wasTextTool = false; + if (_this.tool === "text") { + wasTextTool = true; + _this.setTool("mouse"); //Set to mouse tool while dropping to prevent errors + } + _this.imgDragActive = true; + _this.mouseOverlay.css({ "cursor": "default" }); + var imgDiv = $('
' + + '' + + '
' + + ' ' + + ' ' + + '' + + '
' + + '' + + '
'); + imgDiv.find(".xCanvasBtn").click(function () { + _this.imgDragActive = false; + _this.refreshCursorAppearance(); + imgDiv.remove(); + if (wasTextTool) { + _this.setTool("text"); + } + }); + imgDiv.find(".addToCanvasBtn").click(function () { + var draw = $(this).attr("draw"); + _this.imgDragActive = false; + _this.refreshCursorAppearance(); + var width = imgDiv.width(); + var height = imgDiv.height(); + var p = imgDiv.position(); + var left = Math.round(p.left * 100) / 100; + var top = Math.round(p.top * 100) / 100; + if (draw == "1") { //draw image to canvas + _this.drawImgToCanvas(url, width, height, left, top); + } else { //Add image to background + _this.drawImgToBackground(url, width, height, left, top); + } + _this.sendFunction({ "t": "addImgBG", "draw": draw, "url": url, "d": [width, height, left, top] }); + _this.drawId++; + imgDiv.remove(); + if (wasTextTool) { + _this.setTool("text"); + } + }); + _this.mouseOverlay.append(imgDiv); + imgDiv.draggable(); + imgDiv.resizable(); + }, + drawImgToBackground(url, width, height, left, top) { + this.imgContainer.append('') + }, + addTextBox(textcolor, fontsize, left, top, txId, newLocalBox) { + var _this = this; + var textBox = $('
' + + '
' + + '
x
' + + '
' + + '
'); + _this.latestActiveTextBoxId = txId; + textBox.click(function (e) { + e.preventDefault(); + _this.latestActiveTextBoxId = txId; + return false; + }) + textBox.on("mousemove touchmove", function (e) { + e.preventDefault(); + if (_this.imgDragActive) { + return; + } + var textBoxPosition = textBox.position(); + var currX = (e.offsetX + textBoxPosition.left); + var currY = (e.offsetY + textBoxPosition.top); + if ($(e.target).hasClass("removeIcon")) { + currX += textBox.width() - 4; + } + _this.sendFunction({ "t": "cursor", "event": "move", "d": [currX, currY], "username": _this.settings.username }); + }) + this.textContainer.append(textBox); + textBox.draggable({ + handle: ".moveIcon", + stop: function () { + var textBoxPosition = textBox.position(); + _this.sendFunction({ "t": "setTextboxPosition", "d": [txId, textBoxPosition.top, textBoxPosition.left] }); + }, + drag: function () { + var textBoxPosition = textBox.position(); + _this.sendFunction({ "t": "setTextboxPosition", "d": [txId, textBoxPosition.top, textBoxPosition.left] }); + } + }); + textBox.find(".textContent").on("input", function () { + var text = btoa(unescape(encodeURIComponent($(this).html()))); //Get html and make encode base64 also take care of the charset + _this.sendFunction({ "t": "setTextboxText", "d": [txId, text] }); + }); + textBox.find(".removeIcon").click(function (e) { + $("#" + txId).remove(); + _this.sendFunction({ "t": "removeTextbox", "d": [txId] }); + e.preventDefault(); + return false; + }); + if (newLocalBox) { + textBox.find(".textContent").focus(); + } + if (this.tool === "text") { + textBox.addClass("active"); + } + }, + setTextboxText(txId, text) { + $("#" + txId).find(".textContent").html(decodeURIComponent(escape(atob(text)))); //Set decoded base64 as html + }, + removeTextbox(txId) { + $("#" + txId).remove(); + }, + setTextboxPosition(txId, top, left) { + $("#" + txId).css({ "top": top + "px", "left": left + "px" }); + }, + setTextboxFontSize(txId, fontSize) { + $("#" + txId).find(".textContent").css({ "font-size": fontSize + "em" }); + }, + setTextboxFontColor(txId, color) { + $("#" + txId).find(".textContent").css({ "color": color }); + }, + drawImgToCanvas(url, width, height, left, top, doneCallback) { + var _this = this; + var img = document.createElement('img'); + img.onload = function () { + _this.ctx.drawImage(img, left, top, width, height); + if (doneCallback) { + doneCallback(); + } + } + img.src = url; + }, + undoWhiteboard: function (username) { //Not call this directly because you will get out of sync whit others... + var _this = this; + if (!username) { + username = _this.settings.username; + } + for (var i = _this.drawBuffer.length - 1; i >= 0; i--) { + if (_this.drawBuffer[i]["username"] == username) { + var drawId = _this.drawBuffer[i]["drawId"]; + for (var i = _this.drawBuffer.length - 1; i >= 0; i--) { + if (_this.drawBuffer[i]["drawId"] == drawId && _this.drawBuffer[i]["username"] == username) { + _this.drawBuffer.splice(i, 1); + } + } + break; + } + } + _this.canvas.height = _this.canvas.height; + _this.imgContainer.empty(); + _this.loadDataInSteps(_this.drawBuffer, false, function (stepData) { + //Nothing to do + }); + }, + undoWhiteboardClick: function () { + this.sendFunction({ "t": "undo" }); + this.undoWhiteboard(); + }, + setTool: function (tool) { + this.tool = tool; + if (this.tool === "text") { + $(".textBox").addClass("active"); + this.textContainer.appendTo($(whiteboardContainer)); //Bring textContainer to the front + } else { + $(".textBox").removeClass("active"); + this.mouseOverlay.appendTo($(whiteboardContainer)); + } + this.refreshCursorAppearance(); + this.mouseOverlay.find(".xCanvasBtn").click(); + this.latestActiveTextBoxId = null; + }, + setDrawColor(color) { + var _this = this; + _this.drawcolor = color; + if (_this.tool == "text" && _this.latestActiveTextBoxId) { + _this.sendFunction({ "t": "setTextboxFontColor", "d": [_this.latestActiveTextBoxId, color] }); + _this.setTextboxFontColor(_this.latestActiveTextBoxId, color); + } + }, + updateSmallestScreenResolution(width, height) { + this.backgroundGrid.empty(); + if (width < $(window).width() || height < $(window).height()) { + this.backgroundGrid.append('
'); + this.backgroundGrid.append('
smallest screen participating
'); + } + }, + handleEventsAndData: function (content, isNewData, doneCallback) { + var _this = this; + var tool = content["t"]; + var data = content["d"]; + var color = content["c"]; + var username = content["username"]; + var thickness = content["th"]; + window.requestAnimationFrame(function () { + if (tool === "line" || tool === "pen") { + _this.drawPenLine(data[0], data[1], data[2], data[3], color, thickness); + } else if (tool === "rect") { + _this.drawRec(data[0], data[1], data[2], data[3], color, thickness); + } else if (tool === "circle") { + _this.drawCircle(data[0], data[1], data[2], color, thickness); + } else if (tool === "eraser") { + _this.drawEraserLine(data[0], data[1], data[2], data[3], thickness); + } else if (tool === "eraseRec") { + _this.eraseRec(data[0], data[1], data[2], data[3]); + } else if (tool === "recSelect") { + _this.dragCanvasRectContent(data[0], data[1], data[2], data[3], data[4], data[5]); + } else if (tool === "addImgBG") { + if (content["draw"] == "1") { + _this.drawImgToCanvas(content["url"], data[0], data[1], data[2], data[3], doneCallback) + } else { + _this.drawImgToBackground(content["url"], data[0], data[1], data[2], data[3]); + } + } else if (tool === "addTextBox") { + _this.addTextBox(data[0], data[1], data[2], data[3], data[4]); + } else if (tool === "setTextboxText") { + _this.setTextboxText(data[0], data[1]); + } else if (tool === "removeTextbox") { + _this.removeTextbox(data[0]); + } else if (tool === "setTextboxPosition") { + _this.setTextboxPosition(data[0], data[1], data[2]); + } else if (tool === "setTextboxFontSize") { + _this.setTextboxFontSize(data[0], data[1]); + } else if (tool === "setTextboxFontColor") { + _this.setTextboxFontColor(data[0], data[1]); + } else if (tool === "clear") { + _this.canvas.height = _this.canvas.height; + _this.imgContainer.empty(); + _this.textContainer.empty(); + _this.drawBuffer = []; + _this.drawId = 0; + } else if (tool === "cursor" && _this.settings) { + if (content["event"] === "move") { + if (_this.cursorContainer.find("." + content["username"]).length >= 1) { + _this.cursorContainer.find("." + content["username"]).css({ "left": data[0] + "px", "top": (data[1] - 15) + "px" }); + } else { + _this.cursorContainer.append('
' + + '
' + + decodeURIComponent(atob(content["username"])) + '
'); + } + } else { + _this.cursorContainer.find("." + content["username"]).remove(); + } + } else if (tool === "undo") { + _this.undoWhiteboard(username); + } + }); - if (isNewData && ["line", "pen", "rect", "circle", "eraser", "addImgBG", "recSelect", "eraseRec", "addTextBox", "setTextboxText", "removeTextbox", "setTextboxPosition", "setTextboxFontSize", "setTextboxFontColor"].includes(tool)) { - content["drawId"] = content["drawId"] ? content["drawId"] : _this.drawId; - content["username"] = content["username"] ? content["username"] : _this.settings.username; - _this.drawBuffer.push(content); - } - }, - userLeftWhiteboard(username) { - this.cursorContainer.find("." + username).remove(); - }, - refreshUserBadges() { - this.cursorContainer.find(".userbadge").remove(); - }, - getImageDataBase64() { - _this = this; - var width = this.mouseOverlay.width(); - var height = this.mouseOverlay.height(); - var copyCanvas = document.createElement('canvas'); - copyCanvas.width = width; - copyCanvas.height = height; - var ctx = copyCanvas.getContext("2d"); + if (isNewData && ["line", "pen", "rect", "circle", "eraser", "addImgBG", "recSelect", "eraseRec", "addTextBox", "setTextboxText", "removeTextbox", "setTextboxPosition", "setTextboxFontSize", "setTextboxFontColor"].includes(tool)) { + content["drawId"] = content["drawId"] ? content["drawId"] : _this.drawId; + content["username"] = content["username"] ? content["username"] : _this.settings.username; + _this.drawBuffer.push(content); + } + }, + userLeftWhiteboard(username) { + this.cursorContainer.find("." + username).remove(); + }, + refreshUserBadges() { + this.cursorContainer.find(".userbadge").remove(); + }, + getImageDataBase64() { + _this = this; + var width = this.mouseOverlay.width(); + var height = this.mouseOverlay.height(); + var copyCanvas = document.createElement('canvas'); + copyCanvas.width = width; + copyCanvas.height = height; + var ctx = copyCanvas.getContext("2d"); - $.each(_this.imgContainer.find("img"), function () { //Draw Backgroundimages to the export canvas - var width = $(this).width(); - var height = $(this).height(); - var p = $(this).position(); - var left = Math.round(p.left * 100) / 100; - var top = Math.round(p.top * 100) / 100; - ctx.drawImage(this, left, top, width, height); - }); + $.each(_this.imgContainer.find("img"), function () { //Draw Backgroundimages to the export canvas + var width = $(this).width(); + var height = $(this).height(); + var p = $(this).position(); + var left = Math.round(p.left * 100) / 100; + var top = Math.round(p.top * 100) / 100; + ctx.drawImage(this, left, top, width, height); + }); - var destCtx = copyCanvas.getContext('2d'); //Draw the maincanvas to the exportcanvas - destCtx.drawImage(this.canvas, 0, 0); + var destCtx = copyCanvas.getContext('2d'); //Draw the maincanvas to the exportcanvas + destCtx.drawImage(this.canvas, 0, 0); - $.each($(".textBox"), function () { //Draw the text on top - var textContainer = $(this) - var textEl = $(this).find(".textContent"); - var text = textEl.text(); - var fontSize = textEl.css('font-size'); - var fontColor = textEl.css('color'); - var p = textContainer.position(); - var left = Math.round(p.left * 100) / 100; - var top = Math.round(p.top * 100) / 100; - top += 25; //Fix top position - ctx.font = fontSize + " monospace"; - ctx.fillStyle = fontColor; - ctx.fillText(text, left, top); - }); + $.each($(".textBox"), function () { //Draw the text on top + var textContainer = $(this) + var textEl = $(this).find(".textContent"); + var text = textEl.text(); + var fontSize = textEl.css('font-size'); + var fontColor = textEl.css('color'); + var p = textContainer.position(); + var left = Math.round(p.left * 100) / 100; + var top = Math.round(p.top * 100) / 100; + top += 25; //Fix top position + ctx.font = fontSize + " Monospace"; + ctx.fillStyle = fontColor; + ctx.fillText(text, left, top); + }); - var url = copyCanvas.toDataURL(); - return url; - }, - getImageDataJson() { - var sendObj = []; - for (var i = 0; i < this.drawBuffer.length; i++) { - sendObj.push(JSON.parse(JSON.stringify(this.drawBuffer[i]))); - delete sendObj[i]["username"]; - delete sendObj[i]["wid"]; - delete sendObj[i]["drawId"]; - } - return JSON.stringify(sendObj); - }, - loadData: function (content) { - var _this = this; - _this.loadDataInSteps(content, true, function (stepData) { - if (stepData["username"] == _this.settings.username && _this.drawId < stepData["drawId"]) { - _this.drawId = stepData["drawId"] + 1; - } - }); - }, - loadDataInSteps(content, isNewData, callAfterEveryStep) { - var _this = this; - function lData(index) { - for (var i = index; i < content.length; i++) { - if (content[i]["t"] === "addImgBG" && content[i]["draw"] == "1") { - _this.handleEventsAndData(content[i], isNewData, function () { - callAfterEveryStep(content[i], i); - lData(i + 1); - }); - break; - } else { - _this.handleEventsAndData(content[i], isNewData); - callAfterEveryStep(content[i], i); - } - } - } - lData(0); - }, - loadJsonData(content, doneCallback) { - var _this = this; - _this.loadDataInSteps(content, false, function (stepData, index) { - _this.sendFunction(stepData); - if (index >= content.length - 1) { //Done with all data - _this.drawId++; - if (doneCallback) { - doneCallback(); - } - } - }); - }, - sendFunction: function (content) { //Sends every draw to server - var _this = this; - content["wid"] = _this.settings.whiteboardId; - content["username"] = _this.settings.username; - content["drawId"] = _this.drawId; + var url = copyCanvas.toDataURL(); + return url; + }, + getImageDataJson() { + var sendObj = []; + for (var i = 0; i < this.drawBuffer.length; i++) { + sendObj.push(JSON.parse(JSON.stringify(this.drawBuffer[i]))); + delete sendObj[i]["username"]; + delete sendObj[i]["wid"]; + delete sendObj[i]["drawId"]; + } + return JSON.stringify(sendObj); + }, + loadData: function (content) { + var _this = this; + _this.loadDataInSteps(content, true, function (stepData) { + if (stepData["username"] == _this.settings.username && _this.drawId < stepData["drawId"]) { + _this.drawId = stepData["drawId"] + 1; + } + }); + }, + loadDataInSteps(content, isNewData, callAfterEveryStep) { + var _this = this; - var tool = content["t"]; - if (_this.settings.sendFunction) { - _this.settings.sendFunction(content); - } - if (["line", "pen", "rect", "circle", "eraser", "addImgBG", "recSelect", "eraseRec", "addTextBox", "setTextboxText", "removeTextbox", "setTextboxPosition", "setTextboxFontSize", "setTextboxFontColor"].includes(tool)) { - _this.drawBuffer.push(content); - } - }, - refreshCursorAppearance() { //Set cursor depending on current active tool - var _this = this; - if (_this.tool === "pen" || _this.tool === "eraser") { - _this.mouseOverlay.css({ "cursor": "none" }); - } else if (_this.tool === "mouse") { - this.mouseOverlay.css({ "cursor": "default" }); - } else { //Line, Rec, Circle, Cutting - _this.mouseOverlay.css({ "cursor": "crosshair" }); - } - } + function lData(index) { + for (var i = index; i < content.length; i++) { + if (content[i]["t"] === "addImgBG" && content[i]["draw"] == "1") { + _this.handleEventsAndData(content[i], isNewData, function () { + callAfterEveryStep(content[i], i); + lData(i + 1); + }); + break; + } else { + _this.handleEventsAndData(content[i], isNewData); + callAfterEveryStep(content[i], i); + } + } + } + lData(0); + }, + loadJsonData(content, doneCallback) { + var _this = this; + _this.loadDataInSteps(content, false, function (stepData, index) { + _this.sendFunction(stepData); + if (index >= content.length - 1) { //Done with all data + _this.drawId++; + if (doneCallback) { + doneCallback(); + } + } + }); + }, + sendFunction: function (content) { //Sends every draw to server + var _this = this; + content["wid"] = _this.settings.whiteboardId; + content["username"] = _this.settings.username; + content["drawId"] = _this.drawId; + + var tool = content["t"]; + if (_this.settings.sendFunction) { + _this.settings.sendFunction(content); + } + if (["line", "pen", "rect", "circle", "eraser", "addImgBG", "recSelect", "eraseRec", "addTextBox", "setTextboxText", "removeTextbox", "setTextboxPosition", "setTextboxFontSize", "setTextboxFontColor"].includes(tool)) { + _this.drawBuffer.push(content); + } + }, + refreshCursorAppearance() { //Set cursor depending on current active tool + var _this = this; + if (_this.tool === "pen" || _this.tool === "eraser") { + _this.mouseOverlay.css({ "cursor": "none" }); + } else if (_this.tool === "mouse") { + this.mouseOverlay.css({ "cursor": "default" }); + } else { //Line, Rec, Circle, Cutting + _this.mouseOverlay.css({ "cursor": "crosshair" }); + } + } } \ No newline at end of file diff --git a/s_whiteboard.js b/s_whiteboard.js index 980d3f5..a0b09aa 100644 --- a/s_whiteboard.js +++ b/s_whiteboard.js @@ -2,42 +2,43 @@ var savedBoards = {}; module.exports = { - handleEventsAndData : function(content) { - var tool = content["t"]; //Tool witch is used - var wid = content["wid"]; //whiteboard ID - var username = content["username"]; - if(tool==="clear") { //Clear the whiteboard - delete savedBoards[wid]; - } else if(tool==="undo") { //Undo an action - if(savedBoards[wid]) { - for(var i=savedBoards[wid].length-1;i>=0;i--){ - if(savedBoards[wid][i]["username"]==username) { - var drawId = savedBoards[wid][i]["drawId"]; - for(var i=savedBoards[wid].length-1;i>=0;i--){ - if(savedBoards[wid][i]["drawId"]==drawId && savedBoards[wid][i]["username"]==username) { - savedBoards[wid].splice(i, 1); - } - } - break; - } - } - } - } else if(["line", "pen", "rect", "circle", "eraser", "addImgBG", "recSelect", "eraseRec", "addTextBox", "setTextboxText", "removeTextbox", "setTextboxPosition", "setTextboxFontSize", "setTextboxFontColor"].includes(tool)) { //Save all this actions - if(!savedBoards[wid]) { - savedBoards[wid] = []; - } - delete content["wid"]; //Delete id from content so we don't store it twice - if(tool==="setTextboxText") { - for(var i=savedBoards[wid].length-1;i>=0;i--){ //Remove old textbox tex -> dont store it twice - if(savedBoards[wid][i]["t"]==="setTextboxText" && savedBoards[wid][i]["d"][0]===content["d"][0]) { - savedBoards[wid].splice(i,1); - } - } - } - savedBoards[wid].push(content); - } - }, - loadStoredData : function(wid) { //Load saved whiteboard - return savedBoards[wid] ? savedBoards[wid] : []; - } + handleEventsAndData: function (content) { + var tool = content["t"]; //Tool witch is used + var wid = content["wid"]; //whiteboard ID + var username = content["username"]; + if (tool === "clear") { //Clear the whiteboard + delete savedBoards[wid]; + } else if (tool === "undo") { //Undo an action + if (savedBoards[wid]) { + for (var i = savedBoards[wid].length - 1; i >= 0; i--) { + if (savedBoards[wid][i]["username"] == username) { + var drawId = savedBoards[wid][i]["drawId"]; + for (var i = savedBoards[wid].length - 1; i >= 0; i--) { + if (savedBoards[wid][i]["drawId"] == drawId && savedBoards[wid][i]["username"] == username) { + savedBoards[wid].splice(i, 1); + } + } + break; + } + } + } + } else if (["line", "pen", "rect", "circle", "eraser", "addImgBG", "recSelect", "eraseRec", "addTextBox", "setTextboxText", "removeTextbox", "setTextboxPosition", "setTextboxFontSize", "setTextboxFontColor"].includes(tool)) { //Save all this actions + if (!savedBoards[wid]) { + savedBoards[wid] = []; + } + delete content["wid"]; //Delete id from content so we don't store it twice + if (tool === "setTextboxText") { + for (var i = savedBoards[wid].length - 1; i >= 0; i--) { //Remove old textbox tex -> dont store it twice + if (savedBoards[wid][i]["t"] === "setTextboxText" && savedBoards[wid][i]["d"][0] === content["d"][0]) { + savedBoards[wid].splice(i, 1); + } + } + } + console.log(content) + savedBoards[wid].push(content); + } + }, + loadStoredData: function (wid) { //Load saved whiteboard + return savedBoards[wid] ? savedBoards[wid] : []; + } } \ No newline at end of file
Server URL:
Path:path always have to start & end with "/"
Username:
Password: