diff --git a/locales/de/translation.json b/locales/de/translation.json index 03d029c..19b2dad 100644 --- a/locales/de/translation.json +++ b/locales/de/translation.json @@ -17,7 +17,8 @@ "delete": "Löschen", "fill": "Füllen", "copy": "Kopieren", - "paste": "Einfügen", + "paste": "Einfügen", + "replaceImage": "Ausgewähltes Bild ersetzen", "edit": "Editieren", "set": "Anzeigen", "clear": "Entfernen", diff --git a/locales/en/translation.json b/locales/en/translation.json index 403ded0..e2d7107 100644 --- a/locales/en/translation.json +++ b/locales/en/translation.json @@ -18,6 +18,7 @@ "fill": "Fill", "copy": "Copy", "paste": "Paste", + "replaceImage": "Replace selected image", "edit": "Edit", "set": "Set", "clear": "Clear", diff --git a/locales/fi/translation.json b/locales/fi/translation.json index 295e82f..8a2c780 100644 --- a/locales/fi/translation.json +++ b/locales/fi/translation.json @@ -19,6 +19,7 @@ "fill": "Täytä", "copy": "Kopio", "paste": "Liitä", + "replaceImage": "Korvaa valittu kuva", "set": "Aseta", "clear": "Tyhjennä", "play": "Toista", diff --git a/public/js/edit.js b/public/js/edit.js index 746106c..284635e 100644 --- a/public/js/edit.js +++ b/public/js/edit.js @@ -735,6 +735,22 @@ function addImage(imageUrl, isFullSized) { $("#imageLayer").modal("hide"); +} +function replaceImage(imageUrl) { + const obj = canvas.getActiveObject(); + // make exact replacement by scaling new image to the old size + const oldWidth = obj.width; + const oldHeight = obj.height; + const oldScaleX = obj.scaleX; + const oldScaleY = obj.scaleY; + fabric.Image.fromURL(imageUrl, (newImg) => { + obj.setElement(newImg.getElement()); + obj.scaleX = (oldWidth * oldScaleX) / obj.width; + obj.scaleY = (oldHeight * oldScaleY) / obj.height; + canvas.requestRenderAll() + $("#imageLayer").modal("hide"); + }) + } function addHeader(content) { @@ -1070,7 +1086,15 @@ function closest(list, x) { } function openImageBrowser() { - $("#imageList").load("/admin/ajax/imagelist?bundle=" + bundle + "&nocache=" + uuidv4(), null, function () { + const baseUrl = "/admin/ajax/imagelist" + const bundlePart = "bundle=" + bundle + const noCachePart = "nocache=" + uuidv4() + // If currently selected item is an image, we also add a replace button + const obj = canvas.getActiveObject(); + const replaceModePart = "replacemode=" + (obj?.type === "image" ? "1" : "0") + const finalUrl = baseUrl+"?"+[bundlePart,noCachePart, replaceModePart].join("&") + + $("#imageList").load(finalUrl, null, function () { addImagesFromUploadQueue(); $('#imageLayer').modal('show'); }); diff --git a/routes/admin.js b/routes/admin.js index 2144b80..468816f 100644 --- a/routes/admin.js +++ b/routes/admin.js @@ -261,6 +261,7 @@ export default function (pluginManager, websocket, dispatcher) { router.get('/ajax/imagelist', function (req, res, next) { let bundle = req.query['bundle']; + let replaceMode = req.query['replacemode']; let bundleRoot = path.normalize("./data/bundles/" + bundle); let bundleImages = fs.readdirSync(bundleRoot + "/images", { dotfiles: false @@ -277,7 +278,8 @@ export default function (pluginManager, websocket, dispatcher) { } res.render('ajax/bundleImageList', { - bundleImages: output + bundleImages: output, + replaceMode: replaceMode }); }); diff --git a/views/ajax/bundleImageList.twig b/views/ajax/bundleImageList.twig index 4d1e1e5..ebfe89d 100644 --- a/views/ajax/bundleImageList.twig +++ b/views/ajax/bundleImageList.twig @@ -7,6 +7,12 @@