From 40a8406427c8fc1f5df91a436c09c873ad0c937d Mon Sep 17 00:00:00 2001 From: teddy Date: Mon, 19 Aug 2024 08:58:38 +0100 Subject: [PATCH] Initial commit. \n 1. Screen capture plugin. \n 2. PNG annotation plugin --- DEPRECATED/jQuery_pluggable_annotate_png.html | 126 ++++ .../plugin_capture_screen_with_modals.js | 121 ++++ DEPRECATED/plugin_display_png_v1a.js | 183 ++++++ DEPRECATED/plugin_display_png_v2a.js | 268 ++++++++ DEPRECATED/plugin_tooltip.js | 72 +++ .../test_plugin_capture_screen_Mocha_async.js | 573 +++++++++++++++++ DEPRECATED/test_plugin_display_png_Jest.js | 174 ++++++ DEPRECATED/test_view_capture_screen.html | 47 ++ DEPRECATED/view_capture_screen_v2a.html | 110 ++++ DEPRECATED/view_capture_screen_v2b.html | 60 ++ DEPRECATED/view_display_png_v1a.html | 63 ++ DEPRECATED/view_display_png_v2a.html | 36 ++ DEPRECATED/view_modals.html | 98 +++ DEPRECATED/view_modals2.html | 89 +++ DEPRECATED/view_tooltip.html | 13 + NOTES.txt | 15 + submission - backup/README | 72 +++ submission - backup/capture-screen.css | 101 +++ submission - backup/display-png.css | 15 + submission - backup/plugin_capture_screen.js | 152 +++++ submission - backup/plugin_display_png,js | 274 +++++++++ submission - backup/screenshot (16).png | Bin 0 -> 53504 bytes submission - backup/shared.js | 13 + submission - backup/symbols/Orange Arrow.png | Bin 0 -> 10526 bytes .../test_plugin_capture_screen_Mocha.js | 527 ++++++++++++++++ .../test_plugin_display_png_Mocha.js | 376 +++++++++++ submission - backup/view_capture_screen.html | 113 ++++ submission - backup/view_display_png.html | 84 +++ submission/README | 70 +++ submission/annotate-PNG.css | 15 + submission/capture-screen.css | 101 +++ submission/plugin_annotate_PNG,js | 274 +++++++++ submission/plugin_capture_screen.js | 98 +++ submission/screenshot (16).png | Bin 0 -> 53504 bytes submission/shared.js | 13 + submission/symbols/Orange Arrow.png | Bin 0 -> 10526 bytes submission/test_plugin_annotate_PNG.js | 496 +++++++++++++++ submission/test_plugin_capture_screen.js | 582 ++++++++++++++++++ submission/view_annotate_PNG.html | 84 +++ submission/view_capture_screen.html | 114 ++++ 40 files changed, 5622 insertions(+) create mode 100644 DEPRECATED/jQuery_pluggable_annotate_png.html create mode 100644 DEPRECATED/plugin_capture_screen_with_modals.js create mode 100644 DEPRECATED/plugin_display_png_v1a.js create mode 100644 DEPRECATED/plugin_display_png_v2a.js create mode 100644 DEPRECATED/plugin_tooltip.js create mode 100644 DEPRECATED/test_plugin_capture_screen_Mocha_async.js create mode 100644 DEPRECATED/test_plugin_display_png_Jest.js create mode 100644 DEPRECATED/test_view_capture_screen.html create mode 100644 DEPRECATED/view_capture_screen_v2a.html create mode 100644 DEPRECATED/view_capture_screen_v2b.html create mode 100644 DEPRECATED/view_display_png_v1a.html create mode 100644 DEPRECATED/view_display_png_v2a.html create mode 100644 DEPRECATED/view_modals.html create mode 100644 DEPRECATED/view_modals2.html create mode 100644 DEPRECATED/view_tooltip.html create mode 100644 NOTES.txt create mode 100644 submission - backup/README create mode 100644 submission - backup/capture-screen.css create mode 100644 submission - backup/display-png.css create mode 100644 submission - backup/plugin_capture_screen.js create mode 100644 submission - backup/plugin_display_png,js create mode 100644 submission - backup/screenshot (16).png create mode 100644 submission - backup/shared.js create mode 100644 submission - backup/symbols/Orange Arrow.png create mode 100644 submission - backup/test_plugin_capture_screen_Mocha.js create mode 100644 submission - backup/test_plugin_display_png_Mocha.js create mode 100644 submission - backup/view_capture_screen.html create mode 100644 submission - backup/view_display_png.html create mode 100644 submission/README create mode 100644 submission/annotate-PNG.css create mode 100644 submission/capture-screen.css create mode 100644 submission/plugin_annotate_PNG,js create mode 100644 submission/plugin_capture_screen.js create mode 100644 submission/screenshot (16).png create mode 100644 submission/shared.js create mode 100644 submission/symbols/Orange Arrow.png create mode 100644 submission/test_plugin_annotate_PNG.js create mode 100644 submission/test_plugin_capture_screen.js create mode 100644 submission/view_annotate_PNG.html create mode 100644 submission/view_capture_screen.html diff --git a/DEPRECATED/jQuery_pluggable_annotate_png.html b/DEPRECATED/jQuery_pluggable_annotate_png.html new file mode 100644 index 0000000..8efe9a5 --- /dev/null +++ b/DEPRECATED/jQuery_pluggable_annotate_png.html @@ -0,0 +1,126 @@ + + + + + + Image Annotation Control + + + +
+ +
+ +
+
+ + + +
+ +
+ + + + + + \ No newline at end of file diff --git a/DEPRECATED/plugin_capture_screen_with_modals.js b/DEPRECATED/plugin_capture_screen_with_modals.js new file mode 100644 index 0000000..587af21 --- /dev/null +++ b/DEPRECATED/plugin_capture_screen_with_modals.js @@ -0,0 +1,121 @@ +(function($) { + $.fn.screenshotExporter = function(options) { + var settings = $.extend({ + filename: 'screenshot.png', + excludeSelector: null + }, options); + + return this.each(function() { + var $button = $(this); + + $button.on('click', function() { + takeScreenshot(); + }); + + function takeScreenshot() { + // Hide the button temporarily + $button.hide(); + + // Find the maximum z-index in the document + var maxZIndex = Math.max( + ...Array.from(document.querySelectorAll('body *')) + .map(a => parseFloat(window.getComputedStyle(a).zIndex)) + .filter(a => !isNaN(a)) + ); + + // Create a wrapper div + var $wrapper = $('
') + .css({ + position: 'absolute', + left: 0, + top: 0, + width: '100%', + height: '100%', + zIndex: maxZIndex + 1, + pointerEvents: 'none' + }) + .appendTo('body'); + + // Move all fixed and absolute positioned elements into the wrapper + $('body *').each(function() { + var $el = $(this); + var position = $el.css('position'); + if (position === 'fixed' || position === 'absolute') { + var offset = $el.offset(); + $el.data('original-position', { + parent: $el.parent(), + nextSibling: $el.next(), + position: position, + top: $el.css('top'), + left: $el.css('left'), + zIndex: $el.css('z-index') + }); + $el.appendTo($wrapper) + .css({ + position: 'absolute', + top: offset.top, + left: offset.left, + zIndex: position === 'fixed' ? (parseFloat($el.css('z-index')) || 0) + maxZIndex : $el.css('z-index') + }); + } + }); + + // Use html2canvas to capture the screenshot + html2canvas(document.body, { + ignoreElements: function(element) { + // Exclude the button and any elements matching the excludeSelector + return element === $button[0] || + (settings.excludeSelector && $(element).is(settings.excludeSelector)); + }, + windowWidth: document.documentElement.scrollWidth, + windowHeight: document.documentElement.scrollHeight + }).then(function(canvas) { + // Convert canvas to blob + canvas.toBlob(function(blob) { + // Create a temporary URL for the blob + var url = URL.createObjectURL(blob); + + // Create a temporary anchor element + var a = document.createElement('a'); + a.style.display = 'none'; + a.href = url; + a.download = settings.filename; + + // Append the anchor to the body, click it, and remove it + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + + // Revoke the blob URL + URL.revokeObjectURL(url); + + // Restore the original positions of moved elements + $wrapper.children().each(function() { + var $el = $(this); + var originalPosition = $el.data('original-position'); + if (originalPosition) { + if (originalPosition.nextSibling.length) { + $el.insertBefore(originalPosition.nextSibling); + } else { + $el.appendTo(originalPosition.parent); + } + $el.css({ + position: originalPosition.position, + top: originalPosition.top, + left: originalPosition.left, + zIndex: originalPosition.zIndex + }); + } + }); + + // Remove the wrapper + $wrapper.remove(); + + // Show the button again + $button.show(); + }); + }); + } + }); + }; +}(jQuery)); \ No newline at end of file diff --git a/DEPRECATED/plugin_display_png_v1a.js b/DEPRECATED/plugin_display_png_v1a.js new file mode 100644 index 0000000..eba2522 --- /dev/null +++ b/DEPRECATED/plugin_display_png_v1a.js @@ -0,0 +1,183 @@ + + + +var isEraseMode = false; +var activeSelection = null; + +function hookupPageDisplayPng() { + const canvas = new fabric.Canvas('canvas'); + const symbolSelect = document.getElementById('symbolSelect'); + const colorPicker = document.getElementById('colorPicker'); + const symbols = ['Orange Arrow.png']; + + // Populate symbol select + symbols.forEach(symbol => { + const option = document.createElement('option'); + option.value = symbol; + option.textContent = symbol.replace('.png', ''); + symbolSelect.appendChild(option); + }); + + // Image upload + document.getElementById('imageUpload').addEventListener('change', function(e) { + const file = e.target.files[0]; + const reader = new FileReader(); + reader.onload = function(f) { + fabric.Image.fromURL(f.target.result, function(img) { + canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), { + scaleX: canvas.width / img.width, + scaleY: canvas.height / img.height + }); + }); + }; + reader.readAsDataURL(file); + }); + + // Add arrow + document.getElementById('addArrow').addEventListener('click', function() { + const arrow = new fabric.Path('M 0 0 L 200 100', { + fill: colorPicker.value, + stroke: colorPicker.value, + strokeWidth: 2, + left: 100, + top: 100 + }); + canvas.add(arrow); + }); + + // Add textbox + document.getElementById('addTextbox').addEventListener('click', function() { + const textbox = new fabric.Textbox('Type here', { + left: 100, + top: 100, + width: 150, + fontSize: 20, + fill: colorPicker.value + }); + canvas.add(textbox); + }); + + // Add symbol + symbolSelect.addEventListener('change', function() { + if (this.value) { + fabric.Image.fromURL(`symbols/${this.value}`, function(img) { + img.set({ + left: 100, + top: 100, + scaleX: 0.5, + scaleY: 0.5 + }); + canvas.add(img); + }); + this.value = ''; // Reset select + } + }); + + // Color change for selected object + colorPicker.addEventListener('change', function() { + const activeObject = canvas.getActiveObject(); + if (activeObject) { + if (activeObject.type === 'textbox') { + activeObject.set('fill', this.value); + } else { + activeObject.set('fill', this.value); + activeObject.set('stroke', this.value); + } + canvas.renderAll(); + } + }); + + // Erase mode + document.getElementById('eraseMode').addEventListener('click', function() { + isEraseMode = !isEraseMode; + this.textContent = isEraseMode ? 'Exit Erase Mode' : 'Erase Mode'; + + if (isEraseMode) { + // Delete any pre-selected elements when entering erase mode + deleteSelectedObjects(canvas); + + // Disable selection and drawing + canvas.selection = false; + canvas.isDrawingMode = false; + + // Change cursor to indicate erase mode + canvas.defaultCursor = 'crosshair'; + canvas.hoverCursor = 'crosshair'; + } else { + // Re-enable selection when exiting erase mode + canvas.selection = true; + + // Reset cursors + canvas.defaultCursor = 'default'; + canvas.hoverCursor = 'move'; + } + }); + + // Object selection in erase mode + canvas.on('selection:created', function(options) { + if (isEraseMode) { + deleteSelectedObjects(canvas); + } + }); + + canvas.on('mouse:down', function(options) { + if (isEraseMode && options.target) { + canvas.remove(options.target); + canvas.requestRenderAll(); + } + }); + + // Prevent dragging in erase mode + canvas.on('object:moving', function(options) { + if (isEraseMode) { + options.target.setCoords(); + canvas.remove(options.target); + canvas.requestRenderAll(); + } + }); + + // Save image + document.getElementById('saveImage').addEventListener('click', function() { + if (confirm("Please ensure there is no sensitive information or PII in your annotations. Do you want to proceed with saving?")) { + const dataURL = canvas.toDataURL({ + format: 'png', + quality: 1 + }); + console.log("Base64 string:", dataURL); + // Here you would typically send this dataURL to your server or database + alert("Image saved as Base64 string. Check the console for the output."); + } + }); + /* + // Object selection + canvas.on('selection:created', function(options) { + if (isEraseMode && options.target) { + canvas.remove(options.target); + } else if (options.target) { + if (options.target.type === 'textbox') { + colorPicker.value = options.target.fill; + } else { + colorPicker.value = options.target.stroke || options.target.fill; + } + } + }); + */ +} + +function deleteSelectedObjects(canvas) { + // const canvas = new fabric.Canvas('canvas'); + const activeObject = canvas.getActiveObject(); + if (activeObject) { + if (activeObject.type === 'activeSelection') { + // If it's a multi-selection, remove all selected objects + activeObject.forEachObject(function(obj) { + canvas.remove(obj); + }); + canvas.discardActiveObject(); + } else { + // If it's a single object, just remove it + canvas.remove(activeObject); + } + canvas.requestRenderAll(); + } +} diff --git a/DEPRECATED/plugin_display_png_v2a.js b/DEPRECATED/plugin_display_png_v2a.js new file mode 100644 index 0000000..fc26cb6 --- /dev/null +++ b/DEPRECATED/plugin_display_png_v2a.js @@ -0,0 +1,268 @@ + +(function($) { + $.fn.annotatorPNG = function(options) { + var settings = $.extend({ + heightCanvas: "600px", + widthCanvas: "800px", + }, options); + + var flagToolbox = "annotator-png-toolbox"; + var flagContainer = "annotator-png-container"; + var flagContainerAnnotation = "annotator-png-container-annotation"; + var flagUploadImage = "annotator-png-upload-image"; + var flagAddArrow = "annotator-png-add-arrow"; + var flagAddTextbox = "annotator-png-add-textbox"; + var flagAddSymbol = "annotator-png-add-symbol"; + var flagColourPicker = "annotator-png-colour-picker"; + var flagEraseMode = "annotator-png-erase-mode"; + var flagSaveImage = "annotator-png-save-image"; + var flagCanvasAnnotation = "annotator-png-canvas-annotation"; + var keyFabric = "fabric"; + var keyIsEraseMode = "isEraseMode"; + + function getCanvas() { + let $annotatorPNG = $(document).find("." + flagAnnotatorPNG); + let $canvasAnnotation = $annotatorPNG.find("canvas." + flagCanvasAnnotation); + let canvas = $canvasAnnotation.data(keyFabric); + console.log("canvas: ", canvas); + return canvas; + } + + function deleteSelectedObjects() { + let canvas = getCanvas(); + const activeObject = canvas.getActiveObject(); + if (activeObject) { + console.log("active object type:", activeObject.type); + if (activeObject.type === 'activeSelection') { + // If it's a multi-selection, remove all selected objects + activeObject.forEachObject(function(obj) { + canvas.remove(obj); + }); + canvas.discardActiveObject(); + } else { + // If it's a single object, just remove it + canvas.remove(activeObject); + } + canvas.requestRenderAll(); + } + } + + return this.each(function() { + var $annotatorPNG = $(this); + $annotatorPNG.data(keyIsEraseMode, false); + + const symbols = ['Orange Arrow.png']; + + // Make elements + var $toolbox = $('
'); + + var $inputUploadImage = $(''); + $toolbox.append($inputUploadImage); + + var $buttonAddArrow = $(''); + $toolbox.append($buttonAddArrow); + + var $buttonAddTextbox = $(''); + $toolbox.append($buttonAddTextbox); + + var $selectAddSymbol = $(''); + $selectAddSymbol.append($("