add option to draw grid to image on download

This commit is contained in:
raphael 2020-05-22 15:24:11 +02:00
parent 22126840e9
commit 4134c4130a
5 changed files with 113 additions and 71 deletions

View File

@ -28,6 +28,9 @@ frontend:
# Image download format, can be "png", "jpeg" (or "webp" -> only working on chrome) -- string # Image download format, can be "png", "jpeg" (or "webp" -> only working on chrome) -- string
imageDownloadFormat: "png" imageDownloadFormat: "png"
# draw the background grid to images on download ? (If True, even PNGs are also not transparent anymore) -- boolean
drawBackgroundGrid: false
# Frontend performance tweaks # Frontend performance tweaks
performance: performance:
# Refresh frequency of the debug / info div (in Hz i.e. /s) -- number # Refresh frequency of the debug / info div (in Hz i.e. /s) -- number

View File

@ -51,6 +51,9 @@
"imageDownloadFormat": { "imageDownloadFormat": {
"type": "string" "type": "string"
}, },
"drawBackgroundGrid": {
"type": "boolean"
},
"performance": { "performance": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,

View File

@ -285,21 +285,27 @@ function initWhiteboard() {
// save image as imgae // save image as imgae
$("#saveAsImageBtn").click(function () { $("#saveAsImageBtn").click(function () {
whiteboard.getImageDataBase64(ConfigService.imageDownloadFormat, function (imgData) { whiteboard.getImageDataBase64(
var w = window.open("about:blank"); //Firefox will not allow downloads without extra window {
setTimeout(function () { imageFormat: ConfigService.imageDownloadFormat,
//FireFox seems to require a setTimeout for this to work. drawBackgroundGrid: ConfigService.drawBackgroundGrid,
var a = document.createElement("a"); },
a.href = imgData; function (imgData) {
a.download = "whiteboard." + ConfigService.imageDownloadFormat; var w = window.open("about:blank"); //Firefox will not allow downloads without extra window
w.document.body.appendChild(a);
a.click();
w.document.body.removeChild(a);
setTimeout(function () { setTimeout(function () {
w.close(); //FireFox seems to require a setTimeout for this to work.
}, 100); var a = document.createElement("a");
}, 0); a.href = imgData;
}); a.download = "whiteboard." + ConfigService.imageDownloadFormat;
w.document.body.appendChild(a);
a.click();
w.document.body.removeChild(a);
setTimeout(function () {
w.close();
}, 100);
}, 0);
}
);
}); });
// save image to json containing steps // save image to json containing steps
@ -380,26 +386,30 @@ function initWhiteboard() {
localStorage.setItem("webdavusername", webdavusername); localStorage.setItem("webdavusername", webdavusername);
var webdavpassword = webDavHtml.find(".webdavpassword").val(); var webdavpassword = webDavHtml.find(".webdavpassword").val();
localStorage.setItem("webdavpassword", webdavpassword); localStorage.setItem("webdavpassword", webdavpassword);
whiteboard.getImageDataBase64(ConfigService.imageDownloadFormat, function ( whiteboard.getImageDataBase64(
base64data {
) { imageFormat: ConfigService.imageDownloadFormat,
var webdavaccess = { drawBackgroundGrid: ConfigService.drawBackgroundGrid,
webdavserver: webdavserver, },
webdavpath: webdavpath, function (base64data) {
webdavusername: webdavusername, var webdavaccess = {
webdavpassword: webdavpassword, webdavserver: webdavserver,
}; webdavpath: webdavpath,
webDavHtml.find(".loadingWebdavText").show(); webdavusername: webdavusername,
webDavHtml.find(".webdavUploadBtn").hide(); webdavpassword: webdavpassword,
saveWhiteboardToWebdav(base64data, webdavaccess, function (err) { };
if (err) { webDavHtml.find(".loadingWebdavText").show();
webDavHtml.find(".loadingWebdavText").hide(); webDavHtml.find(".webdavUploadBtn").hide();
webDavHtml.find(".webdavUploadBtn").show(); saveWhiteboardToWebdav(base64data, webdavaccess, function (err) {
} else { if (err) {
webDavHtml.parents(".basicalert").remove(); webDavHtml.find(".loadingWebdavText").hide();
} webDavHtml.find(".webdavUploadBtn").show();
}); } else {
}); webDavHtml.parents(".basicalert").remove();
}
});
}
);
}); });
showBasicAlert(webDavHtml, { showBasicAlert(webDavHtml, {
header: "Save to Webdav", header: "Save to Webdav",

View File

@ -40,6 +40,14 @@ class ConfigService {
return this.#imageDownloadFormat; return this.#imageDownloadFormat;
} }
/**
* @type {boolean}
*/
#drawBackgroundGrid = false;
get drawBackgroundGrid() {
return this.#drawBackgroundGrid;
}
/** /**
* @type {{minDistDelta: number, minTimeDelta: number}} * @type {{minDistDelta: number, minTimeDelta: number}}
*/ */
@ -69,12 +77,14 @@ class ConfigService {
onWhiteboardLoad, onWhiteboardLoad,
showSmallestScreenIndicator, showSmallestScreenIndicator,
imageDownloadFormat, imageDownloadFormat,
drawBackgroundGrid,
performance, performance,
} = common; } = common;
this.#onWhiteboardLoad = onWhiteboardLoad; this.#onWhiteboardLoad = onWhiteboardLoad;
this.#showSmallestScreenIndicator = showSmallestScreenIndicator; this.#showSmallestScreenIndicator = showSmallestScreenIndicator;
this.#imageDownloadFormat = imageDownloadFormat; this.#imageDownloadFormat = imageDownloadFormat;
this.#drawBackgroundGrid = drawBackgroundGrid;
this.#refreshInfoInterval = 1000 / performance.refreshInfoFreq; this.#refreshInfoInterval = 1000 / performance.refreshInfoFreq;
console.log("Whiteboard config from server:", configFromServer, "parsed:", this); console.log("Whiteboard config from server:", configFromServer, "parsed:", this);

View File

@ -1173,62 +1173,78 @@ const whiteboard = {
refreshUserBadges() { refreshUserBadges() {
this.cursorContainer.find(".userbadge").remove(); this.cursorContainer.find(".userbadge").remove();
}, },
getImageDataBase64(format, callback) { getImageDataBase64(options, callback) {
var _this = this; var _this = this;
var width = this.mouseOverlay.width(); var width = this.mouseOverlay.width();
var height = this.mouseOverlay.height(); var height = this.mouseOverlay.height();
var copyCanvas = document.createElement("canvas"); var copyCanvas = document.createElement("canvas");
copyCanvas.width = width; copyCanvas.width = width;
copyCanvas.height = height; copyCanvas.height = height;
var ctx = copyCanvas.getContext("2d"); var imageFormat = options.imageFormat || "png";
var drawBackgroundGrid = options.drawBackgroundGrid || false;
$.each(_this.imgContainer.find("img"), function () { var brackGroundImg = new Image();
//Draw Backgroundimages to the export canvas brackGroundImg.src = _this.settings.backgroundGridUrl;
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 brackGroundImg.onload = function () {
if (format === "jpeg") { var destCtx = copyCanvas.getContext("2d"); //Draw the maincanvas to the exportcanvas
//Set white background for jpeg images
destCtx.fillStyle = "#FFFFFF";
destCtx.fillRect(0, 0, width, height);
}
destCtx.drawImage(this.canvas, 0, 0);
var textBoxCnt = 0; if (imageFormat === "jpeg") {
$.each($(".textBox"), function () { //Set white background for jpeg images
//Draw the text on top destCtx.fillStyle = "#FFFFFF";
textBoxCnt++; destCtx.fillRect(0, 0, width, height);
}
var textContainer = $(this); if (drawBackgroundGrid) {
var p = textContainer.position(); var ptrn = destCtx.createPattern(brackGroundImg, "repeat"); // Create a pattern with this image, and set it to "repeat".
destCtx.fillStyle = ptrn;
destCtx.fillRect(0, 0, copyCanvas.width, copyCanvas.height); // context.fillRect(x, y, width, height);
}
var left = Math.round(p.left * 100) / 100; $.each(_this.imgContainer.find("img"), function () {
var top = Math.round(p.top * 100) / 100; //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;
destCtx.drawImage(this, left, top, width, height);
});
html2canvas(this, { backgroundColor: "rgba(0, 0, 0, 0)", removeContainer: true }).then( //Copy drawings
function (canvas) { destCtx.drawImage(_this.canvas, 0, 0);
var textBoxCnt = 0;
$.each($(".textBox"), function () {
//Draw the text on top
textBoxCnt++;
var textContainer = $(this);
var p = textContainer.position();
var left = Math.round(p.left * 100) / 100;
var top = Math.round(p.top * 100) / 100;
html2canvas(this, {
backgroundColor: "rgba(0, 0, 0, 0)",
removeContainer: true,
}).then(function (canvas) {
console.log("canvas", canvas); console.log("canvas", canvas);
destCtx.drawImage(canvas, left, top); destCtx.drawImage(canvas, left, top);
textBoxCnt--; textBoxCnt--;
checkForReturn(); checkForReturn();
} });
); });
});
function checkForReturn() { function checkForReturn() {
if (textBoxCnt == 0) { if (textBoxCnt == 0) {
var url = copyCanvas.toDataURL("image/" + format); var url = copyCanvas.toDataURL("image/" + imageFormat);
callback(url); callback(url);
}
} }
} checkForReturn();
checkForReturn(); };
}, },
getImageDataJson() { getImageDataJson() {
var sendObj = []; var sendObj = [];