diff --git a/Web Annotation Extension/annotation-old.js b/Web Annotation Extension/annotation-old.js new file mode 100644 index 00000000..cedf12fe --- /dev/null +++ b/Web Annotation Extension/annotation-old.js @@ -0,0 +1,376 @@ +(function() { + if (document.getElementById('annotationSidebar')) return; + + // Add Sidebar + const sidebar = document.createElement('div'); + sidebar.id = 'annotationSidebar'; + sidebar.style.position = 'fixed'; + sidebar.style.top = '10px'; + sidebar.style.left = '10px'; + sidebar.style.width = '200px'; + sidebar.style.backgroundColor = 'white'; + sidebar.style.border = '1px solid #ccc'; + sidebar.style.zIndex = '10000'; + sidebar.style.padding = '10px'; + sidebar.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)'; + sidebar.style.display = 'flex'; + sidebar.style.flexDirection = 'column'; + sidebar.style.display = 'none'; + document.body.appendChild(sidebar); + + sidebar.innerHTML = ` + <div style="display: flex; justify-content: space-between; align-items: center;"> + <span>Tools</span> + <button id="closeSidebar" style="background: transparent; border: none; font-size: 16px; cursor: pointer;">✖</button> + </div> + <button id="startAnnotation" style="border-radius: 8px">Start Annotation</button> + <button id="stopAnnotation" style="display: none;border-radius: 8px">Stop Annotation</button> + <button id="screenshotButton" style="border-radius: 8px">Annotation Screenshot</button> + <button id="clearButton" style="border-radius: 8px">Clear Annotations</button> + `; + + const startAnnotationButton = document.getElementById('startAnnotation'); + const stopAnnotationButton = document.getElementById('stopAnnotation'); + const screenshotButton = document.getElementById('screenshotButton'); + const clearButton = document.getElementById('clearButton'); + const closeSidebarButton = document.getElementById('closeSidebar'); + + // Annotation Canvas + const canvas = document.createElement('canvas'); + canvas.id = 'annotationCanvas'; + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + canvas.style.position = 'fixed'; + canvas.style.top = '0'; + canvas.style.left = '0'; + canvas.style.zIndex = '9999'; + canvas.style.display = 'none'; + document.body.appendChild(canvas); + + const ctx = canvas.getContext('2d'); + let drawing = false; + let penColor = '#000000'; + let penWidth = 2; + const paths = []; + let currentPath = []; + + const penWidthInput = document.createElement('input'); + penWidthInput.type = 'range'; + penWidthInput.min = 1; + penWidthInput.max = 20; + penWidthInput.value = 2; + penWidthInput.style.display = 'none'; + sidebar.appendChild(penWidthInput); + + const colorPickerInput = document.createElement('input'); + colorPickerInput.type = 'color'; + colorPickerInput.value = '#000000'; + colorPickerInput.style.display = 'none'; + sidebar.appendChild(colorPickerInput); + + const undoButton = document.createElement('button'); + undoButton.textContent = 'Undo'; + undoButton.style.display = 'none'; + sidebar.appendChild(undoButton); + + penWidthInput.addEventListener('input', (e) => { + penWidth = e.target.value; + }); + + colorPickerInput.addEventListener('input', (e) => { + penColor = e.target.value; + }); + + startAnnotationButton.addEventListener('click', () => { + canvas.style.display = 'block'; + canvas.style.cursor = 'crosshair'; + startAnnotationButton.style.display = 'none'; + stopAnnotationButton.style.display = 'inline'; + penWidthInput.style.display = 'block'; + colorPickerInput.style.display = 'block'; + undoButton.style.display = 'block'; + clearButton.style.display = 'block'; + }); + + stopAnnotationButton.addEventListener('click', () => { + canvas.style.display = 'none'; + canvas.style.cursor = 'default'; + startAnnotationButton.style.display = 'inline'; + stopAnnotationButton.style.display = 'none'; + penWidthInput.style.display = 'none'; + colorPickerInput.style.display = 'none'; + undoButton.style.display = 'none'; + clearButton.style.display = 'none'; + }); + + undoButton.addEventListener('click', () => { + paths.pop(); + redraw(); + }); + + closeSidebarButton.addEventListener('click', () => { + sidebar.style.display = 'none'; + }); + + clearButton.addEventListener('click', () => { + paths.length = 0; + redraw(); + }); + + canvas.addEventListener('mousedown', (e) => { + if (e.target.id === 'annotationCanvas') { + drawing = true; + currentPath = [{ x: e.clientX, y: e.clientY, color: penColor, width: penWidth }]; + ctx.beginPath(); + ctx.moveTo(e.clientX, e.clientY); + } + }); + + canvas.addEventListener('mousemove', (e) => { + if (drawing) { + currentPath.push({ x: e.clientX, y: e.clientY, color: penColor, width: penWidth }); + ctx.lineTo(e.clientX, e.clientY); + ctx.strokeStyle = penColor; + ctx.lineWidth = penWidth; + ctx.stroke(); + } + }); + + canvas.addEventListener('mouseup', () => { + if (drawing) { + paths.push(currentPath); + drawing = false; + ctx.closePath(); + } + }); + + canvas.addEventListener('mouseleave', () => { + if (drawing) { + paths.push(currentPath); + drawing = false; + ctx.closePath(); + } + }); + + function redraw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + paths.forEach(path => { + ctx.beginPath(); + path.forEach((point, index) => { + ctx.strokeStyle = point.color; + ctx.lineWidth = point.width; + if (index === 0) { + ctx.moveTo(point.x, point.y); + } else { + ctx.lineTo(point.x, point.y); + } + ctx.stroke(); + }); + ctx.closePath(); + }); + } + + screenshotButton.addEventListener('click', () => { + const link = document.createElement('a'); + link.href = canvas.toDataURL(); + link.download = 'screenshot.png'; + link.click(); + }); + + chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + if (request.action === 'toggleSidebar') { + sidebar.style.display = (sidebar.style.display === 'none' || sidebar.style.display === '') ? 'flex' : 'none'; + } + }); + +})(); + + + +/* (function() { + if (document.getElementById('annotationSidebar')) return; + + // Add Sidebar + const sidebar = document.createElement('div'); + sidebar.id = 'annotationSidebar'; + sidebar.classList.add('collapsed'); + sidebar.style.position = 'fixed'; + sidebar.style.top = '10px'; + sidebar.style.left = '10px'; + sidebar.style.width = '150px'; + sidebar.style.backgroundColor = 'white'; + sidebar.style.border = '1px solid #ccc'; + sidebar.style.zIndex = '10000'; + sidebar.style.padding = '10px'; + sidebar.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)'; + document.body.appendChild(sidebar); + + sidebar.innerHTML = ` + <div id="dragHandle" style="cursor: grab; padding: 5px; background: #007bff; color: white; border-radius: 50%; width: 100%; text-align: center;">☰</div> + <div id="tools" style="display: none;"> + <label for="penWidth">Pen Width:</label> + <input type="range" id="penWidth" min="1" max="20" value="2"><br><br> + <label for="colorPicker">Color:</label> + <input type="color" id="colorPicker" value="#000000"><br><br> + <button id="undoButton">Undo</button> + <button id="startAnnotation">Start Annotation</button> + <button id="stopAnnotation" style="display: none;">Stop Annotation</button> + </div> + `; + + const dragHandle = document.getElementById('dragHandle'); + const toolsDiv = document.getElementById('tools'); + const startAnnotationButton = document.getElementById('startAnnotation'); + const stopAnnotationButton = document.getElementById('stopAnnotation'); + let isDragging = false; + let offsetX, offsetY; + + dragHandle.addEventListener('mousedown', (e) => { + isDragging = true; + dragHandle.style.cursor = 'grabbing'; + offsetX = e.clientX - sidebar.getBoundingClientRect().left; + offsetY = e.clientY - sidebar.getBoundingClientRect().top; + document.addEventListener('mousemove', onDrag); + document.addEventListener('mouseup', onStopDrag); + }); + + function onDrag(e) { + if (isDragging) { + sidebar.style.left = `${e.clientX - offsetX}px`; + sidebar.style.top = `${e.clientY - offsetY}px`; + } + } + + function onStopDrag() { + isDragging = false; + dragHandle.style.cursor = 'grab'; + document.removeEventListener('mousemove', onDrag); + document.removeEventListener('mouseup', onStopDrag); + } + + sidebar.addEventListener('click', (e) => { + e.stopPropagation(); + sidebar.classList.toggle('expanded'); + sidebar.classList.toggle('collapsed'); + if (sidebar.classList.contains('expanded')) { + toolsDiv.style.display = 'block'; + } else { + toolsDiv.style.display = 'none'; + } + }); + + document.addEventListener('click', (e) => { + if (sidebar.classList.contains('expanded') && !e.target.closest('#annotationSidebar')) { + sidebar.classList.remove('expanded'); + sidebar.classList.add('collapsed'); + toolsDiv.style.display = 'none'; + } + }); + + // Prevent annotation on the sidebar + sidebar.addEventListener('mousedown', (e) => e.stopPropagation()); + sidebar.addEventListener('mousemove', (e) => e.stopPropagation()); + sidebar.addEventListener('mouseup', (e) => e.stopPropagation()); + + // Annotation Canvas + const canvas = document.createElement('canvas'); + canvas.id = 'annotationCanvas'; + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + canvas.style.position = 'fixed'; + canvas.style.top = '0'; + canvas.style.left = '0'; + canvas.style.zIndex = '9999'; + canvas.style.display = 'none'; + document.body.appendChild(canvas); + + const ctx = canvas.getContext('2d'); + let drawing = false; + let penColor = '#000000'; + let penWidth = 2; + const paths = []; + let currentPath = []; + + const penWidthInput = document.getElementById('penWidth'); + const colorPickerInput = document.getElementById('colorPicker'); + const undoButton = document.getElementById('undoButton'); + + penWidthInput.addEventListener('input', (e) => { + penWidth = e.target.value; + }); + + colorPickerInput.addEventListener('input', (e) => { + penColor = e.target.value; + }); + + startAnnotationButton.addEventListener('click', () => { + canvas.style.display = 'block'; + startAnnotationButton.style.display = 'none'; + stopAnnotationButton.style.display = 'inline'; + }); + + stopAnnotationButton.addEventListener('click', () => { + canvas.style.display = 'none'; + startAnnotationButton.style.display = 'inline'; + stopAnnotationButton.style.display = 'none'; + }); + + undoButton.addEventListener('click', () => { + paths.pop(); + redraw(); + }); + + canvas.addEventListener('mousedown', (e) => { + if (e.target.id === 'annotationCanvas') { + drawing = true; + currentPath = [{ x: e.clientX, y: e.clientY, color: penColor, width: penWidth }]; + ctx.beginPath(); + ctx.moveTo(e.clientX, e.clientY); + } + }); + + canvas.addEventListener('mousemove', (e) => { + if (drawing) { + currentPath.push({ x: e.clientX, y: e.clientY, color: penColor, width: penWidth }); + ctx.lineTo(e.clientX, e.clientY); + ctx.strokeStyle = penColor; + ctx.lineWidth = penWidth; + ctx.stroke(); + } + }); + + canvas.addEventListener('mouseup', () => { + if (drawing) { + paths.push(currentPath); + drawing = false; + ctx.closePath(); + } + }); + + canvas.addEventListener('mouseleave', () => { + if (drawing) { + paths.push(currentPath); + drawing = false; + ctx.closePath(); + } + }); + + function redraw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + paths.forEach(path => { + ctx.beginPath(); + path.forEach((point, index) => { + ctx.strokeStyle = point.color; + ctx.lineWidth = point.width; + if (index === 0) { + ctx.moveTo(point.x, point.y); + } else { + ctx.lineTo(point.x, point.y); + } + ctx.stroke(); + }); + ctx.closePath(); + }); + } +})(); + */ \ No newline at end of file diff --git a/Web Annotation Extension/annotation.js b/Web Annotation Extension/annotation.js new file mode 100644 index 00000000..e12dee1d --- /dev/null +++ b/Web Annotation Extension/annotation.js @@ -0,0 +1,426 @@ +(function() { + if (document.getElementById('annotationSidebar')) return; + + // Add Sidebar + const sidebar = document.createElement('div'); + sidebar.id = 'annotationSidebar'; + sidebar.style.position = 'fixed'; + sidebar.style.top = '10px'; + sidebar.style.left = '10px'; + sidebar.style.width = '220px'; + sidebar.style.backgroundColor = 'white'; + sidebar.style.border = '1px solid #ccc'; + sidebar.style.zIndex = '10000'; + sidebar.style.padding = '10px'; + sidebar.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)'; + sidebar.style.display = 'flex'; + sidebar.style.flexDirection = 'column'; + sidebar.style.display = 'none'; + sidebar.style.borderRadius = '8px'; + document.body.appendChild(sidebar); + + sidebar.innerHTML = ` + <div id="dragHandle" style="padding: 5px 10px; cursor: move; height:30px; background: #007bff; color: white; display: flex; align-items: center; border-top-left-radius: 8px; border-top-right-radius: 8px;"> + <span style="flex-grow: 1; text-align: center;">☰ Drag</span> + <button id="closeSidebar" style="background: transparent; border: none; font-size: 16px; color: white; cursor: pointer; color: red">✖</button> + </div> + <button id="startAnnotation" style="border-radius: 8px; margin: 10px 0; padding: 10px; background: #28a745; color: white; border: none; cursor: pointer;" title="Start Annotation">Start Annotation</button> + <button id="stopAnnotation" style="display: none; border-radius: 8px; margin: 10px 0; padding: 10px; background: #dc3545; color: white; border: none; cursor: pointer;" title="Stop Annotation">Stop Annotation</button> + <button id="screenshotButton" style="border-radius: 8px; margin: 10px 0; padding: 10px; background: #17a2b8; color: white; border: none; cursor: pointer;" title="Take only Annotation Screenshot">Annotation Screenshot</button> + <button id="clearButton" style="border-radius: 8px; margin: 10px 0; padding: 10px; background: #ffc107; color: black; border: none; cursor: pointer;" title="Clear Annotations">Clear Annotations</button> + <label for="penWidthInput" id="penInputText" style="display: none; margin: 7px 0; font-size: 14px;">Pen Size:</label> + <input id="penWidthInput" type="range" min="1" max="20" value="2" style="margin: 10px 0; display: none;"> + <label for="colorPickerInput" id="colorInputText" style="display: none; margin: 7px 0; font-size: 14px;">Choose Color:</label> + <input id="colorPickerInput" type="color" value="#000000" style="margin: 10px 0; display: none; width: 80px"> + <button id="undoButton" style="display: none; border-radius: 8px; margin: 10px 0; padding: 10px; background: #6c757d; color: white; border: none; cursor: pointer;" title="Undo Last Annotation">Undo</button> + `; + + const startAnnotationButton = document.getElementById('startAnnotation'); + const stopAnnotationButton = document.getElementById('stopAnnotation'); + const screenshotButton = document.getElementById('screenshotButton'); + const clearButton = document.getElementById('clearButton'); + const closeSidebarButton = document.getElementById('closeSidebar'); + const dragHandle = document.getElementById('dragHandle'); + const penWidthInput = document.getElementById('penWidthInput'); + const colorPickerInput = document.getElementById('colorPickerInput'); + const undoButton = document.getElementById('undoButton'); + const penInputText = document.getElementById('penInputText'); + const colorInputText = document.getElementById('colorInputText'); + + + // Annotation Canvas + const canvas = document.createElement('canvas'); + canvas.id = 'annotationCanvas'; + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + canvas.style.position = 'fixed'; + canvas.style.top = '0'; + canvas.style.left = '0'; + canvas.style.zIndex = '9999'; + canvas.style.display = 'none'; + document.body.appendChild(canvas); + + const ctx = canvas.getContext('2d'); + let drawing = false; + let penColor = '#000000'; + let penWidth = 2; + const paths = []; + let currentPath = []; + +/* const penWidthInput = document.createElement('input'); + penWidthInput.type = 'range'; + penWidthInput.min = 1; + penWidthInput.max = 20; + penWidthInput.value = 2; + penWidthInput.style.display = 'none'; + penWidthInput.style.margin = '10px 0'; + sidebar.appendChild(penWidthInput); + + const colorPickerInput = document.createElement('input'); + colorPickerInput.type = 'color'; + colorPickerInput.value = '#000000'; + colorPickerInput.style.display = 'none'; + colorPickerInput.style.margin = '10px 0'; + sidebar.appendChild(colorPickerInput); */ + + /* const undoButton = document.createElement('button'); + undoButton.textContent = 'Undo'; + undoButton.style.display = 'none'; + undoButton.style.borderRadius = '8px'; + undoButton.style.margin = '10px 0'; + undoButton.style.padding = '10px'; + undoButton.style.background = '#6c757d'; + undoButton.style.color = 'white'; + undoButton.style.border = 'none'; + undoButton.style.cursor = 'pointer'; + sidebar.appendChild(undoButton); */ + + penWidthInput.addEventListener('input', (e) => { + penWidth = e.target.value; + }); + + colorPickerInput.addEventListener('input', (e) => { + penColor = e.target.value; + }); + + startAnnotationButton.addEventListener('click', () => { + canvas.style.display = 'block'; + canvas.style.cursor = 'crosshair'; + startAnnotationButton.style.display = 'none'; + stopAnnotationButton.style.display = 'inline'; + penWidthInput.style.display = 'block'; + colorPickerInput.style.display = 'block'; + undoButton.style.display = 'block'; + clearButton.style.display = 'block'; + penInputText.style.display = 'block'; + colorInputText.style.display = 'block'; + }); + + stopAnnotationButton.addEventListener('click', () => { + canvas.style.display = 'none'; + canvas.style.cursor = 'default'; + startAnnotationButton.style.display = 'inline'; + stopAnnotationButton.style.display = 'none'; + penWidthInput.style.display = 'none'; + colorPickerInput.style.display = 'none'; + undoButton.style.display = 'none'; + clearButton.style.display = 'none'; + penInputText.style.display = 'none'; + colorInputText.style.display = 'none'; + }); + + undoButton.addEventListener('click', () => { + paths.pop(); + redraw(); + }); + + closeSidebarButton.addEventListener('click', () => { + sidebar.style.display = 'none'; + }); + + clearButton.addEventListener('click', () => { + paths.length = 0; + redraw(); + }); + + let isDragging = false; + let offsetX, offsetY; + + dragHandle.addEventListener('mousedown', (e) => { + isDragging = true; + offsetX = e.clientX - sidebar.getBoundingClientRect().left; + offsetY = e.clientY - sidebar.getBoundingClientRect().top; + document.addEventListener('mousemove', onDrag); + document.addEventListener('mouseup', stopDrag); + }); + + function onDrag(e) { + if (isDragging) { + sidebar.style.left = `${e.clientX - offsetX}px`; + sidebar.style.top = `${e.clientY - offsetY}px`; + } + } + + function stopDrag() { + isDragging = false; + document.removeEventListener('mousemove', onDrag); + document.removeEventListener('mouseup', stopDrag); + } + + canvas.addEventListener('mousedown', (e) => { + if (e.target.id === 'annotationCanvas') { + drawing = true; + currentPath = [{ x: e.clientX, y: e.clientY, color: penColor, width: penWidth }]; + ctx.beginPath(); + ctx.moveTo(e.clientX, e.clientY); + } + }); + + canvas.addEventListener('mousemove', (e) => { + if (drawing) { + currentPath.push({ x: e.clientX, y: e.clientY, color: penColor, width: penWidth }); + ctx.lineTo(e.clientX, e.clientY); + ctx.strokeStyle = penColor; + ctx.lineWidth = penWidth; + ctx.stroke(); + } + }); + + canvas.addEventListener('mouseup', () => { + if (drawing) { + paths.push(currentPath); + drawing = false; + ctx.closePath(); + } + }); + + canvas.addEventListener('mouseleave', () => { + if (drawing) { + paths.push(currentPath); + drawing = false; + ctx.closePath(); + } + }); + + function redraw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + paths.forEach(path => { + ctx.beginPath(); + path.forEach((point, index) => { + ctx.strokeStyle = point.color; + ctx.lineWidth = point.width; + if (index === 0) { + ctx.moveTo(point.x, point.y); + } else { + ctx.lineTo(point.x, point.y); + } + ctx.stroke(); + }); + ctx.closePath(); + }); + } + + screenshotButton.addEventListener('click', () => { + const link = document.createElement('a'); + link.href = canvas.toDataURL(); + link.download = 'screenshot.png'; + link.click(); + }); + + chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + if (request.action === 'toggleSidebar') { + sidebar.style.display = (sidebar.style.display === 'none' || sidebar.style.display === '') ? 'flex' : 'none'; + } + }); + +})(); + + + +/* (function() { + if (document.getElementById('annotationSidebar')) return; + + // Add Sidebar + const sidebar = document.createElement('div'); + sidebar.id = 'annotationSidebar'; + sidebar.classList.add('collapsed'); + sidebar.style.position = 'fixed'; + sidebar.style.top = '10px'; + sidebar.style.left = '10px'; + sidebar.style.width = '150px'; + sidebar.style.backgroundColor = 'white'; + sidebar.style.border = '1px solid #ccc'; + sidebar.style.zIndex = '10000'; + sidebar.style.padding = '10px'; + sidebar.style.boxShadow = '0 0 10px rgba(0,0,0,0.5)'; + document.body.appendChild(sidebar); + + sidebar.innerHTML = ` + <div id="dragHandle" style="cursor: grab; padding: 5px; background: #007bff; color: white; border-radius: 50%; width: 100%; text-align: center;">☰</div> + <div id="tools" style="display: none;"> + <label for="penWidth">Pen Width:</label> + <input type="range" id="penWidth" min="1" max="20" value="2"><br><br> + <label for="colorPicker">Color:</label> + <input type="color" id="colorPicker" value="#000000"><br><br> + <button id="undoButton">Undo</button> + <button id="startAnnotation">Start Annotation</button> + <button id="stopAnnotation" style="display: none;">Stop Annotation</button> + </div> + `; + + const dragHandle = document.getElementById('dragHandle'); + const toolsDiv = document.getElementById('tools'); + const startAnnotationButton = document.getElementById('startAnnotation'); + const stopAnnotationButton = document.getElementById('stopAnnotation'); + let isDragging = false; + let offsetX, offsetY; + + dragHandle.addEventListener('mousedown', (e) => { + isDragging = true; + dragHandle.style.cursor = 'grabbing'; + offsetX = e.clientX - sidebar.getBoundingClientRect().left; + offsetY = e.clientY - sidebar.getBoundingClientRect().top; + document.addEventListener('mousemove', onDrag); + document.addEventListener('mouseup', onStopDrag); + }); + + function onDrag(e) { + if (isDragging) { + sidebar.style.left = `${e.clientX - offsetX}px`; + sidebar.style.top = `${e.clientY - offsetY}px`; + } + } + + function onStopDrag() { + isDragging = false; + dragHandle.style.cursor = 'grab'; + document.removeEventListener('mousemove', onDrag); + document.removeEventListener('mouseup', onStopDrag); + } + + sidebar.addEventListener('click', (e) => { + e.stopPropagation(); + sidebar.classList.toggle('expanded'); + sidebar.classList.toggle('collapsed'); + if (sidebar.classList.contains('expanded')) { + toolsDiv.style.display = 'block'; + } else { + toolsDiv.style.display = 'none'; + } + }); + + document.addEventListener('click', (e) => { + if (sidebar.classList.contains('expanded') && !e.target.closest('#annotationSidebar')) { + sidebar.classList.remove('expanded'); + sidebar.classList.add('collapsed'); + toolsDiv.style.display = 'none'; + } + }); + + // Prevent annotation on the sidebar + sidebar.addEventListener('mousedown', (e) => e.stopPropagation()); + sidebar.addEventListener('mousemove', (e) => e.stopPropagation()); + sidebar.addEventListener('mouseup', (e) => e.stopPropagation()); + + // Annotation Canvas + const canvas = document.createElement('canvas'); + canvas.id = 'annotationCanvas'; + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + canvas.style.position = 'fixed'; + canvas.style.top = '0'; + canvas.style.left = '0'; + canvas.style.zIndex = '9999'; + canvas.style.display = 'none'; + document.body.appendChild(canvas); + + const ctx = canvas.getContext('2d'); + let drawing = false; + let penColor = '#000000'; + let penWidth = 2; + const paths = []; + let currentPath = []; + + const penWidthInput = document.getElementById('penWidth'); + const colorPickerInput = document.getElementById('colorPicker'); + const undoButton = document.getElementById('undoButton'); + + penWidthInput.addEventListener('input', (e) => { + penWidth = e.target.value; + }); + + colorPickerInput.addEventListener('input', (e) => { + penColor = e.target.value; + }); + + startAnnotationButton.addEventListener('click', () => { + canvas.style.display = 'block'; + startAnnotationButton.style.display = 'none'; + stopAnnotationButton.style.display = 'inline'; + }); + + stopAnnotationButton.addEventListener('click', () => { + canvas.style.display = 'none'; + startAnnotationButton.style.display = 'inline'; + stopAnnotationButton.style.display = 'none'; + }); + + undoButton.addEventListener('click', () => { + paths.pop(); + redraw(); + }); + + canvas.addEventListener('mousedown', (e) => { + if (e.target.id === 'annotationCanvas') { + drawing = true; + currentPath = [{ x: e.clientX, y: e.clientY, color: penColor, width: penWidth }]; + ctx.beginPath(); + ctx.moveTo(e.clientX, e.clientY); + } + }); + + canvas.addEventListener('mousemove', (e) => { + if (drawing) { + currentPath.push({ x: e.clientX, y: e.clientY, color: penColor, width: penWidth }); + ctx.lineTo(e.clientX, e.clientY); + ctx.strokeStyle = penColor; + ctx.lineWidth = penWidth; + ctx.stroke(); + } + }); + + canvas.addEventListener('mouseup', () => { + if (drawing) { + paths.push(currentPath); + drawing = false; + ctx.closePath(); + } + }); + + canvas.addEventListener('mouseleave', () => { + if (drawing) { + paths.push(currentPath); + drawing = false; + ctx.closePath(); + } + }); + + function redraw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + paths.forEach(path => { + ctx.beginPath(); + path.forEach((point, index) => { + ctx.strokeStyle = point.color; + ctx.lineWidth = point.width; + if (index === 0) { + ctx.moveTo(point.x, point.y); + } else { + ctx.lineTo(point.x, point.y); + } + ctx.stroke(); + }); + ctx.closePath(); + }); + } +})(); + */ \ No newline at end of file diff --git a/Web Annotation Extension/background.js b/Web Annotation Extension/background.js new file mode 100644 index 00000000..886ed0f5 --- /dev/null +++ b/Web Annotation Extension/background.js @@ -0,0 +1,29 @@ +chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { + if (request.action === 'captureScreenshot') { + chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { + chrome.tabs.captureVisibleTab(null, { format: 'png' }, (dataUrl) => { + sendResponse({ screenshotUrl: dataUrl }); + }); + }); + return true; // Required to use sendResponse asynchronously. + } +}); + +chrome.runtime.onInstalled.addListener(() => { + chrome.contextMenus.create({ + id: "startAnnotation", + title: "Start Annotation", + contexts: ["all"] + }); +}); + +chrome.contextMenus.onClicked.addListener((info, tab) => { + if (info.menuItemId === "startAnnotation") { + chrome.scripting.executeScript({ + target: { tabId: tab.id }, + files: ['annotation.js'] + }, () => { + chrome.tabs.sendMessage(tab.id, { action: "toggleSidebar" }); + }); + } +}); diff --git a/Web Annotation Extension/icons/icon128.png b/Web Annotation Extension/icons/icon128.png new file mode 100644 index 00000000..7555650c Binary files /dev/null and b/Web Annotation Extension/icons/icon128.png differ diff --git a/Web Annotation Extension/icons/icon16.png b/Web Annotation Extension/icons/icon16.png new file mode 100644 index 00000000..48acfb7c Binary files /dev/null and b/Web Annotation Extension/icons/icon16.png differ diff --git a/Web Annotation Extension/icons/icon32.png b/Web Annotation Extension/icons/icon32.png new file mode 100644 index 00000000..97b4b11e Binary files /dev/null and b/Web Annotation Extension/icons/icon32.png differ diff --git a/Web Annotation Extension/icons/icon48.png b/Web Annotation Extension/icons/icon48.png new file mode 100644 index 00000000..f065117e Binary files /dev/null and b/Web Annotation Extension/icons/icon48.png differ diff --git a/Web Annotation Extension/manifest.json b/Web Annotation Extension/manifest.json new file mode 100644 index 00000000..05f00c48 --- /dev/null +++ b/Web Annotation Extension/manifest.json @@ -0,0 +1,36 @@ +{ + "manifest_version": 3, + "name": "Web Annotation Tool", + "version": "1.0", + "description": "Annotate webpages and save them as screenshots", + "permissions": [ + "activeTab", + "storage", + "scripting", + "tabs", + "contextMenus" + ], + "background": { + "service_worker": "background.js" + }, + "action": { + "default_popup": "popup.html", + "default_icon": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } + }, + "content_scripts": [ + { + "matches": ["http://*/*", "https://*/*"], + "js": ["annotation.js"], + "run_at": "document_idle" + } + ], + "icons": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + } +} \ No newline at end of file diff --git a/Web Annotation Extension/popup.css b/Web Annotation Extension/popup.css new file mode 100644 index 00000000..090a842c --- /dev/null +++ b/Web Annotation Extension/popup.css @@ -0,0 +1,42 @@ +body { + font-family: Arial, sans-serif; + width: 200px; + margin: 0; +} + +.container { + text-align: center; + padding: 20px; +} + +button { + width: 100%; + padding: 10px; + margin: 10px 0; + cursor: pointer; + border: none; + background-color: #007bff; + color: white; + border-radius: 5px; + outline: none; + transition: background-color 0.3s ease; +} + +button:hover { + background-color: #0056b3; +} + +#penWidth, #colorPicker, #undoButton { + margin: 5px 0; +} + +#undoButton:hover, #clearButton:hover { + background-color: #c82333; +} + +canvas { + position: fixed; + top: 0; + left: 0; + z-index: 9999; +} diff --git a/Web Annotation Extension/popup.html b/Web Annotation Extension/popup.html new file mode 100644 index 00000000..7105a534 --- /dev/null +++ b/Web Annotation Extension/popup.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title>Web Annotation Tool</title> + <link rel="stylesheet" type="text/css" href="popup.css"> + <script src="popup.js"></script> +</head> +<body> + <div class="container"> + <h1>Annotation Tool</h1> + <button id="enableAnnotation">Enable Annotation</button> + <button id="saveScreenshot">Save Web Screenshot</button> + </div> +</body> +</html> \ No newline at end of file diff --git a/Web Annotation Extension/popup.js b/Web Annotation Extension/popup.js new file mode 100644 index 00000000..16cb7c7d --- /dev/null +++ b/Web Annotation Extension/popup.js @@ -0,0 +1,38 @@ +document.addEventListener("DOMContentLoaded", function(){ + document.getElementById('enableAnnotation').addEventListener('click', () => { + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + const tab = tabs[0]; + if ((tab.url.startsWith('http://') || tab.url.startsWith('https://')) && (tab && tab.id)) { + chrome.scripting.executeScript({ + target: { tabId: tab.id }, + files: ['annotation.js'] + }).then(() => { + console.log("Annotation script executed."); + chrome.tabs.sendMessage(tab.id, {action: "toggleSidebar"}); + }).catch((err) => { + console.error("Script execution failed: ", err); + }); + } else { + console.error("Cannot run script on this URL."); + alert("Cannot run script on this URL."); + } + }); + }); + + document.getElementById('saveScreenshot').addEventListener('click', () => { + chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { + const tab = tabs[0]; + if (tab.url.startsWith('http://') || tab.url.startsWith('https://')) { + chrome.tabs.captureVisibleTab(tabs[0].windowId, {}, function(image) { + const link = document.createElement('a'); + link.href = image; + link.download = 'screenshot.png'; + link.click(); + }); + } else { + console.error("Cannot capture screenshot on this URL."); + alert("Cannot capture screenshot on this URL."); + } + }); + }); +}); \ No newline at end of file