(function() { //Keyboard shortcut to enable highlighter: Ctrl + Shift + f (you can change the character key below) var shortcutKey = "f"; //Enable with shortcut document.addEventListener("keydown", function(e) { if ( e.ctrlKey && e.shiftKey && (e.key === shortcutKey.toUpperCase() || e.key === shortcutKey.toLowerCase()) ) { activateHighlighter(); } }); // document.addEventListener("keydown", function(e) { if (e.key === "Escape" || e.key === "Esc") { if (document.getElementsByClassName("dh-block").length) { //Some section is currently highlighted. Just remove the highlighting. Dont deactivate yet clearHighlightings(); } else { deactivateHighlighter(); } } }); function addStyleString(str) { var node = document.createElement("style"); node.innerHTML = str; document.body.appendChild(node); } addStyleString( "#dhCanvas{position:fixed;left:0px;top:0px;right:0px;bottom:0px;width:100%;z-index: 1000000000; display: none; pointer-events: all; background: rgba(0,0,0,0.3)} " + "#dhCanvas.dh-highlighted {background: transparent; pointer-events: none;} " + "#dhCanvas > .dh-block{position:absolute;background:#000;opacity:.5; pointer-events: all;} " + ".dh-drag-highlighter{position:absolute;background:#fff;border:solid 1px #29ff5a;opacity:0.3;} " + ".dh-close-btn {display: none; z-index: 10000000000000; position: fixed;left: 0px;top: 0px;color: #fff;background: #000;height: 20px;width: 20px;line-height: 15px;text-align: center;cursor: pointer;} " + ".dh-close-btn::after{content: 'x'}" + "#dhCanvas.dh-dragging {pointer-events: all !important;}" ); var dhCanvas = document.createElement("div"); dhCanvas.setAttribute("id", "dhCanvas"); dhCanvas.addEventListener( "wheel", function(e) { e.preventDefault(); }, { passive: false } ); document.body.appendChild(dhCanvas); var dragTracker = { tracking: false, xStart: undefined, yStart: undefined, xStop: undefined, yStop: undefined, dragHighlighterElm: undefined, start: (x, y) => { dhCanvas.classList.add('dh-dragging') this.tracking = true; this.xStart = x; this.yStart = y; if (!this.dragHighlighterElm) { this.dragHighlighterElm = document.createElement("div"); this.dragHighlighterElm.setAttribute( "class", "dh-drag-highlighter" ); this.dragHighlighterElm.style.left = x + "px"; this.dragHighlighterElm.style.top = y + "px"; dhCanvas.appendChild(this.dragHighlighterElm); } }, stop: (x, y) => { dhCanvas.classList.remove('dh-dragging') this.tracking = false; this.xStop = x; this.yStop = y; this.dragHighlighterElm.remove(); this.dragHighlighterElm = undefined; }, hasMoved: () => { if (xStart == xStop && yStart == yStop) return false; return true; }, highlightDraggingPath: (x, y) => { var xtl = Math.min(x, this.xStart); var ytl = Math.min(y, this.yStart); this.dragHighlighterElm.style.left = xtl + "px"; this.dragHighlighterElm.style.top = ytl + "px"; this.dragHighlighterElm.style.width = Math.abs(x - this.xStart) + "px"; this.dragHighlighterElm.style.height = Math.abs(y - this.yStart) + "px"; }, setup: dhCanvas => { dhCanvas.addEventListener("mousedown", e => { dragTracker.start(e.clientX, e.clientY); }); dhCanvas.addEventListener("mouseup", e => { dragTracker.stop(e.clientX, e.clientY); if (dragTracker.hasMoved()) { console.log(xStart, yStart, xStop - xStart, yStop - yStart); highlight( Math.min(xStart, xStop), Math.min(yStart, yStop), Math.abs(xStop - xStart), Math.abs(yStop - yStart) ); } }); dhCanvas.addEventListener("mousemove", e => { //If mouse button not pressed, not dragging, skip! if (e.which != 1) return; dragTracker.highlightDraggingPath(e.clientX, e.clientY); }); clearCanvas() } }; function renderBlock(x, y, w, h) { var block = document.createElement("div"); block.setAttribute("class", "dh-block"); block.setAttribute( "style", "left: " + x + "px; top: " + y + "px; width: " + w + "px; height: " + h + "px;" ); dhCanvas.appendChild(block); } function findBlocksAround(x, y, w, h) { var heightMax = window.innerHeight; var widthMax = window.innerWidth; var blocks = []; blocks.push({ x: 0, y: 0, w: x, h: heightMax }); blocks.push({ x: x, y: 0, w: widthMax - x, h: y }); blocks.push({ x: x + w, y: y, w: widthMax - x - w, h: heightMax - y }); blocks.push({ x: x, y: y + h, w: w, h: heightMax - y - h }); return blocks; } function clearCanvas() { dhCanvas.innerHTML = ""; var dhCloseBtn = document.createElement("div"); dhCloseBtn.setAttribute('class', 'dh-close-btn'); dhCloseBtn.addEventListener('click', ()=>{deactivateHighlighter()}); dhCanvas.appendChild(dhCloseBtn); } function clearHighlightings() { clearCanvas(); dhCanvas.className = ""; } function highlight(x, y, w, h) { clearHighlightings(); dhCanvas.className = "dh-highlighted"; var blocksAround = findBlocksAround(x, y, w, h); for (var i in blocksAround) { let block = blocksAround[i]; renderBlock(block.x, block.y, block.w, block.h); } document.dispatchEvent(new Event("dh-highlighted")); } function activateHighlighter() { dhCanvas.style.display = "block"; document.dispatchEvent(new Event("dh-activated")); } function deactivateHighlighter() { dhCanvas.style.display = "none"; document.dispatchEvent(new Event("dh-deactivated")); } window.dhMan = { dhCanvas: dhCanvas, renderBlock: renderBlock, findBlocksAround: findBlocksAround, highlight: highlight, dragTracker: dragTracker, activate: activateHighlighter, deactivate: deactivateHighlighter }; dragTracker.setup(dhCanvas); })();