diff --git a/frontend/js/svg-draw.js b/frontend/js/svg-draw.js index 5e23533..9a9aeb2 100644 --- a/frontend/js/svg-draw.js +++ b/frontend/js/svg-draw.js @@ -153,6 +153,18 @@ const content = document.createElementNS(SVGNS, 'g'); // user drawing lives here content.setAttribute('class', 'svgd-content'); svg.appendChild(content); + // optional background image to draw over (annotation mode) + const bgUrl = opts.bgImage || null; + if (bgUrl) { + const im = document.createElementNS(SVGNS, 'image'); + im.setAttribute('href', bgUrl); + try { im.setAttributeNS('http://www.w3.org/1999/xlink', 'href', bgUrl); } catch (e) {} + im.setAttribute('x', '0'); im.setAttribute('y', '0'); + im.setAttribute('width', String(W)); im.setAttribute('height', String(H)); + im.setAttribute('preserveAspectRatio', 'xMidYMid meet'); + im.style.pointerEvents = 'none'; + svg.insertBefore(im, content); + } wrap.appendChild(svg); root.appendChild(toolbar); @@ -480,13 +492,41 @@ return '#' + [m[1], m[2], m[3]].map(function (x) { return ('0' + parseInt(x, 10).toString(16)).slice(-2); }).join(''); } + /* Rasterize to a flattened PNG: optional background image + the vector + drawing on top. Used to save an annotated image into «Мои материалы». */ + function exportFlatBlob(cb) { + const out = document.createElement('canvas'); + out.width = W; out.height = H; + const ctx = out.getContext('2d'); + function drawVector() { + const v = new Image(); + v.onload = function () { ctx.drawImage(v, 0, 0, W, H); out.toBlob(cb, 'image/png'); }; + v.onerror = function () { out.toBlob(cb, 'image/png'); }; + v.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(getSVG()); + } + ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, W, H); + if (bgUrl) { + const bg = new Image(); + bg.onload = function () { + const s = Math.min(W / bg.naturalWidth, H / bg.naturalHeight) || 1; + const dw = bg.naturalWidth * s, dh = bg.naturalHeight * s; + ctx.drawImage(bg, (W - dw) / 2, (H - dh) / 2, dw, dh); + drawVector(); + }; + bg.onerror = drawVector; + bg.src = bgUrl; + } else { + drawVector(); + } + } + function destroy() { document.removeEventListener('keydown', onKey); document.removeEventListener('pointerup', restoreAncestorDrag); if (root.parentNode) root.parentNode.removeChild(root); } - return { getSVG: getSVG, destroy: destroy, el: root }; + return { getSVG: getSVG, exportFlatBlob: exportFlatBlob, destroy: destroy, el: root }; } window.SvgDraw = { mount: mount }; diff --git a/frontend/my-materials.html b/frontend/my-materials.html index e408e7d..9be5232 100644 --- a/frontend/my-materials.html +++ b/frontend/my-materials.html @@ -53,6 +53,7 @@