您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
1/8/2024, 9:16:09 PM
// ==UserScript== // @name Sheezy Image Viewer // @namespace Violentmonkey Scripts // @match https://sheezy.dev/*/gallery/* // @match https://sheezy.art/*/gallery/* // @homepageURL https://github.com/Exodus-Drake/Redeviated-Advanced-Image-Viewer-Sheezy // @version 2024.01.12.0 // @author Edael // @description 1/8/2024, 9:16:09 PM // ==/UserScript== (function() { setTimeout(() => { console.clear(); //DOM path to image const _config = { ImgDOM: '#artwork', }; if (document.querySelector(`${_config.ImgDOM} canvas`) || document.querySelector(`${_config.ImgDOM} img`)) { const css = ` #content > section:first-child > div:first-child > div:nth-child(2) > div > div > div > div{ cursor:zoom-in } #my-img-modal{ min-height: 100%; min-width: 100%; margin: 0; padding: 0; background: none; border: 0 transparent; overflow-x: hidden; overflow-y: scroll; transition: 0.25s ease; opacity: 1; background-color: rgba(55, 63, 61, .75); scrollbar-width: thin; scrollbar-color: white transparent; color: white; } #my-img-modal::backdrop{background-color: transparent;} #my-img-modal > div:first-child{ top: 12px; right: 12px; } #my-img-modal > div:nth-child(3){ top: 12px; left: 12px; } #my-img-modal > div:nth-child(4){ bottom: 12px; right: 12px; } #my-img-modal > div:last-child{ position: fixed; display: block; width: 50%; left: 150vw; top: 50%; translate: -50% -50%; box-shadow: rgba(0, 0, 0, 0.5) 0px 1px 4px, rgb(255, 255, 255) 0px 1px 1px inset; border-radius: 2rem; background-color: #A2B8C6; transition: 0.45s ease-in-out; font-size: 16px; overflow: hidden; } #my-img-modal > div:last-child > div{ position: relative; } #my-img-modal > div:last-child > div:first-child{ padding: 15px 20px; font-size: 1.6rem; font-weight: 600; border-radius: 1.6rem 1.6rem 0 0; box-shadow: rgba(0, 0, 0, 0.6) 0px 1px 1px, rgb(255, 255, 255) 0px 1px 1px inset; background-image: linear-gradient(to top, #526B83, #5B7690); z-index: 1; } #my-img-modal > div:last-child > div:last-child{ padding: 12px 16px; display: grid; row-gap: 16px; overflow-y: auto; height: 50vh; overflow-x: hidden; scrollbar-color: white transparent; scrollbar-width: thin; } #my-img-modal > div:last-child > div:last-child > div:last-child{ display: grid; row-gap: 12px; } .mdl-btns{ padding: 8px 16px; position: fixed; display: grid; justify-content: space-evenly; transition: 0.25s ease; row-gap: 8px; z-index: 1; opacity: 0.5; } .mdl-btns:hover{ opacity: 1.0; } .mdl-btns-help{ display: grid; transition: 0.25s ease; column-gap: 10px; row-gap: 8px; grid-template-rows: auto auto; grid-template-columns: repeat(7, auto); justify-content: center; } .mdl-btns-help::after{ content:"" width: 100%; } .mdl-btns > span, .mdl-btns-help > span{ display: flex; padding: 6px; width: 100%; cursor: pointer; border-radius: .6em; transition: 0.1s ease !important; --tw-shadow: 0 .1em .3em rgba(0, 0, 0, .2), inset 0 1px rgba(255, 255, 255, .2), inset 0 -1px rgba(0, 0, 0, .05); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); text-shadow: 0 1px rgba(0, 0, 0, .15), 0 -1px rgba(255, 255, 255, .15); background-color: var(--button-background, #7c9db1); height: 38px; width: 52px; max-width: unset; user-select: none; } .mdl-btns > span:hover{ transform: scale(1.3); box-shadow: rgba(0, 0, 0, 0.5) 0px 1px 4px, rgba(255, 255, 255, 1.0) 0px 1px 2px inset; background-color: var(--button-background-hover, #88a7ba); color: var(--button-text-hover, #fff) !important; } .mdl-btns > span:active:hover{ transform: scale(0.9); background-color: rgb(236 242 246 / var(--tw-bg-opacity)); } .mdl-btns-help > span:hover{ translate: 0 -4px; box-shadow: rgba(0, 0, 0, 0.5) 0px 1px 4px, rgba(255, 255, 255, 1.0) 0px 1px 2px inset; background-color: var(--button-background-hover, #88a7ba); color: var(--button-text-hover, #fff) !important; } .mdl-btns-help > span:active:hover{ background-color: rgb(236 242 246 / var(--tw-bg-opacity)); translate: 0 2px; } .mdl-btns > span > img, .mdl-btns-help > span > img{ filter: invert(26%) sepia(30%) saturate(665%) hue-rotate(169deg) brightness(91%) contrast(83%); margin: auto; } .btn-img-viw{ padding: 6px; margin-inline: 2px; width: 36px; height: 36px; border: 0; background-color: rgba(165, 255, 123, 0.0); box-shadow: rgba(0, 0, 0, 0.0) 0px 1px 4px, rgba(255, 255, 255, 0.0) 0px 1px 1px inset; border-radius: 5px; bottom: 0; transition: 0.25s ease !important; } .btn-img-viw:hover{ translate: 0 -4px; background-color: rgba(165, 255, 123, 0.5); box-shadow: rgba(0, 0, 0, 0.5) 0px 1px 4px, rgba(255, 255, 255, 1.0) 0px 1px 2px inset; } .btn-img-viw:active:hover{ background-color: #82fc49cc; translate: 0 2px; transition: 0.1s ease; } /*.btn-img-viw:focus{ outline: none; }*/ .btn-img-viw > img, .btn-example > img{ width: 100%; filter: invert(1); cursor: pointer; filter: invert(99%) sepia(1%) saturate(1265%) hue-rotate(10deg) brightness(116%) drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.8)) drop-shadow(0px 0px 2px rgba(0, 0, 0, 0.8)) drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.4)) contrast(100%); } .btn-example{ display: inline-block; padding: 4px; width: 24px; height: 24px; background-color: rgba(0, 0, 0, 0.5); box-shadow: rgba(0, 0, 0, 0.5) 0px 1px 4px, rgba(255, 255, 255, 1.0) 0px 1px 1px inset; border-radius: 5px; } .darkbox-cont{ padding: 6px; background-color: #c0d0da; border-radius: 5px; color: #4a647d; } .spread-align{ text-align: right; padding: 0 12px; } .spread-align > span:first-child{ float:left; } .spread-align > :not(:first-child){ margin: 0; } #arrow-exit{ position: absolute; right: 22px; top: 12px; width: 32px; height: 32px; cursor: pointer; filter: invert(99%) sepia(1%) saturate(1265%) hue-rotate(10deg) brightness(116%) drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.8)) drop-shadow(0px 0px 2px rgba(0, 0, 0, 0.8)) drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.4)) contrast(100%); } #my-img-modal input:active{cursor: grabbing;} #my-img-modal > div:nth-child(2){ position: absolute; width: fit-content; height: fit-content; line-height: 0; } #my-img-modal > div:nth-child(2) > img{ position: relative; max-width: 66vw; max-height: 90vh; image-rendering: auto; transition: 0.1s ease; filter: drop-shadow(0px 0px 6px rgba(0, 0, 0, 0.7)); rotate: 0deg; } #my-img-modal > div:nth-child(2):hover{cursor: all-scroll} #my-img-modal > div:nth-child(2):active{cursor: none} .janky-workaround{cursor:zoom-in !important} @media (max-width: 900px){ .mdl-btns-help { grid-template-rows: repeat(4, auto); grid-template-columns: repeat(4, auto); } } `; let styleNode = document.createElement("style"); styleNode.innerHTML = css; document.head.appendChild(styleNode); function getContainerType() { if (document.querySelector(`${_config.ImgDOM} canvas`)) { return document.querySelector(`${_config.ImgDOM} canvas`).getAttribute('style').match(/--src:url\('(.*?)'\)/)[1]; } else { return document.querySelector(`${_config.ImgDOM} img`).src; }; }; const modalBtn = ` <div onclick="openImage(getContainerType());" class="absolute translate-center bottom-0 flex h-2x w-2x cursor-pointer items-center justify-center rounded-50 bg-black/75 text-20 font-normal text-white opacity-0 transition-opacity group-hover:opacity-100" style="right: 48px;"> <i class="not-prose material-symbols-outlined Icon-module__icon__Ykfh8"> expand_content </i> </div> `; //TODO //document.querySelector(_config.ImgDOM).insertAdjacentHTML("afterbegin", modalBtn); document.querySelector(_config.ImgDOM).addEventListener('click', () => { openImage(getContainerType()); }); var _dom = {} var _eStop = [] var _iConf = { Width: '28', Height: '28' }; function buildModal() { const btnsModal = ` <span> <img title="Reset" draggable="false" src="https://www.svgrepo.com/show/510837/arrows-reload-01.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Zoom-In" draggable="false" src="https://www.svgrepo.com/show/511061/magnifying-glass-plus.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Zoom-Out" draggable="false" src="https://www.svgrepo.com/show/511056/magnifying-glass-minus.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Rotate Left" draggable="false" src="https://www.svgrepo.com/show/511181/undo.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Rotate Right" draggable="false" src="https://www.svgrepo.com/show/511181/undo.svg" width="${_iConf.Width}" height="${_iConf.Height}" style="scale: -1;"> </span> <span> <img Title="Real Size" draggable="false" src="https://www.svgrepo.com/show/510968/expand.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Fit Width to Screen" draggable="false" src="https://www.svgrepo.com/show/511082/move-horizontal.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Fit Height to Screen" draggable="false" src="https://www.svgrepo.com/show/511081/move-vertical.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="To-Top" draggable="false" src="https://www.svgrepo.com/show/510911/chevron-up.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="To-Bottom" draggable="false" src="https://www.svgrepo.com/show/510905/chevron-down.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Flip Horizontally" draggable="false" src="https://www.svgrepo.com/show/510812/arrow-left-right.svg" data-toggle="true" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Flip Vertically" draggable="false" src="https://www.svgrepo.com/show/510808/arrow-down-up.svg" data-toggle="true" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Background Transparency" draggable="false" src="https://www.svgrepo.com/show/510903/checkbox-fill.svg" data-toggle="true" width="${_iConf.Width}" height="${_iConf.Height}"> </span> <span> <img Title="Toggle Rendering" draggable="false" src="https://www.svgrepo.com/show/510899/check-big.svg" data-toggle="true" width="${_iConf.Width}" height="${_iConf.Height}"> </span> `; const helpModal = ` <div> <div> <h3><b>Button Controls</b></h3> <img id="arrow-exit" src="https://www.svgrepo.com/show/533605/arrow-narrow-right.svg"> </div> <div> <div class="mdl-btns-help"> ${btnsModal} </div> <div class="darkbox-cont"> <b>Reset</b> <p>Resets image position and scale, toggle settings remain active.</p> </div> <div> <h3><b>Hot Keys</b></h3> <p class="spread-align"> <span>Hide / Show Interface</span><span class="darkbox-cont">H</span> </p> <hr class="divider line-white"> <p class="spread-align"> <span>Reset</span><span class="darkbox-cont">Double Click</span> </p> <hr class="divider line-white"> <p class="spread-align"> <span>Zooming In / Out</span><span class="darkbox-cont">=</span> <span class="darkbox-cont">-</span> or <span class="darkbox-cont">Shift + Mousewheel</span> </p> <hr class="divider line-white"> <p class="spread-align"> <span>Toggle Background</span><span class="darkbox-cont">C</span> </p> <hr class="divider line-white"> <p class="spread-align"> <span>Toggle Rendering</span><span class="darkbox-cont">V</span> </p> <hr class="divider line-white"> </div> </div> </div> `; const createModal = ` <dialog id="my-img-modal"> <div class="mdl-btns"> <span><img title="Exit" draggable="false" src="https://www.svgrepo.com/show/510924/close-md.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> </div> <div> <img ondragstart="return false" id="drag-img" loading="lazy" src=""> </div> <div class="mdl-btns" data-toggle="true"> ${btnsModal} </div> <div class="mdl-btns" data-toggle="true"> <span> <img Title="Controls and Hotkeys" draggable="false" src="https://www.svgrepo.com/show/511031/info.svg" width="${_iConf.Width}" height="${_iConf.Height}"> </span> </div> ${helpModal} </dialog> `; if (document.getElementById('my-img-modal')) { document.getElementById('my-img-modal').remove() }; document.body.insertAdjacentHTML("beforeend", createModal); _dom = { ImgModal: document.getElementById('my-img-modal'), ModalCloseBtn: document.getElementById('my-img-modal').children[0], ModalImage: document.getElementById('my-img-modal').children[1], ModalDock: document.getElementById('my-img-modal').children[2], ModalInfoBtn: document.getElementById('my-img-modal').children[3], ModalInfoField: document.getElementById('my-img-modal').children[4], ModalHelpBtns: document.getElementById('my-img-modal').children[4].children[1].children[0], }; _eStop = [ _dom.ModalImage, _dom.ModalDock, _dom.ModalInfoBtn, _dom.ModalInfoField ]; _eStop.forEach((ele) => ele.addEventListener("click", (e) => e.stopPropagation()) ); }; buildModal(); const toggleElement = (num) => { return _dom.ModalDock.children[num].children[0] }; function openImage(img) { _dom.ModalImage.children[0].src = img; _dom.ImgModal.showModal(); _dom.ImgModal.style.opacity = '1'; _dom.ImgModal.style.backgroundColor = 'rgba(55, 63, 61, .75)'; document.body.style = ` overflow: hidden; position: fixed; width: 100%; `; document.querySelector('main').style.marginRight = '17px'; callModalFunc(); }; function reset() { _dom.ImgModal.style.backgroundColor = 'rgba(55, 63, 61, .75)'; _dom.ModalImage.children[0].style = null; document.body.style = null; document.querySelector('main').style.marginRight = null; toggleElement(12).setAttribute('data-toggle', 'true'); toggleElement(12).src = `https://www.svgrepo.com/show/510903/checkbox-fill.svg`; toggleElement(13).setAttribute('data-toggle', 'true'); toggleElement(13).src = `https://www.svgrepo.com/show/510899/check-big.svg`; toggleElement(10).setAttribute('data-toggle', 'true'); toggleElement(10).style.scale = '1 1'; toggleElement(11).setAttribute('data-toggle', 'true'); toggleElement(11).style.scale = '1 1'; showHelp("reset"); }; function showHelp(att) { if (att === "reset"){ _dom.ModalInfoField.style.left = '150vw'; _dom.ModalInfoBtn.setAttribute('data-toggle', 'true'); } else { let getAttr = _dom.ModalInfoBtn.getAttribute('data-toggle'); move = getAttr == 'true' ? '50%' : '150vw'; toggle = getAttr == 'true' ? 'false' : 'true'; _dom.ModalInfoField.style.left = move; _dom.ModalInfoBtn.setAttribute('data-toggle', toggle); } }; function callModalFunc() { var contRect = _dom.ImgModal.getBoundingClientRect() var imgRect = _dom.ModalImage.getBoundingClientRect(); var centerX = (contRect.width * 0.5) - (imgRect.width * 0.5); var centerY = (contRect.height * 0.5) - (imgRect.height * 0.5); console.log(contRect) //Heavily modified and adapted from https://stackoverflow.com/a/60235061/22552292 const view = (() => { const matrix = [1, 0, 0, 1, 0, 0]; // current view transform var m = matrix; // alias var scale = 1; // current scale var pos = { x: centerX, y: centerY }; // current position of origin var flipX = '1'; var flipY = '1'; var dirty = true; const API = { applyTo(el) { if (dirty) { this.update() } el.style.transform = `matrix(${m[0]},${m[1]},${m[2]},${m[3]},${m[4]},${m[5]})`; }, update() { dirty = false; m[3] = m[0] = scale; m[2] = m[1] = 0; m[4] = pos.x; m[5] = pos.y; }, updateVariables() { if (dirty) { this.update() } contRect = _dom.ImgModal.getBoundingClientRect(); imgRect = _dom.ModalImage.getBoundingClientRect(); centerX = (contRect.width * 0.5) - (imgRect.width * 0.5); centerY = (contRect.height * 0.5) - (imgRect.height * 0.5); pos.x = centerX; pos.y = centerY; console.log(centerX, centerY); dirty = true; }, pan(amount) { if (dirty) { this.update() } if (_dom.ModalImage.style.transition != 'unset') _dom.ModalImage.style.transition = 'unset' pos.x += amount.x; pos.y += amount.y; dirty = true; }, scaleAt(at, amount) { // at in screen coords if (dirty) { this.update() } if (_dom.ModalImage.style.transition != '0.15s ease') _dom.ModalImage.style.transition = '0.15s ease' scale *= amount; pos.x = at.x - (at.x - pos.x) * amount; pos.y = at.y - (at.y - pos.y) * amount; dirty = true; }, reset() { if (dirty) { this.update() } if (_dom.ModalImage.style.transition != '0.25s ease') _dom.ModalImage.style.transition = '0.25s ease'; if (_dom.ModalImage.children[0].style.transition != 'unset') _dom.ModalImage.children[0].style.transition = 'unset'; _dom.ModalImage.children[0].style.maxWidth = null; _dom.ModalImage.children[0].style.maxHeight = null; _dom.ModalImage.children[0].style.rotate = null; scale = 1; pos.x = centerX; pos.y = centerY; //realSize = true dirty = true; }, realSize() { if (dirty) { this.update() } if (_dom.ModalImage.style.transition != '0.25s ease') _dom.ModalImage.style.transition = '0.25s ease'; this.reset; amount = _dom.ModalImage.children[0].naturalWidth / _dom.ModalImage.children[0].width; scale = amount; console.log(centerX, centerY); dirty = true; }, rotateLeft() { if (dirty) { this.update() } if (_dom.ModalImage.children[0].style.transition != '0.1s ease') _dom.ModalImage.children[0].style.transition = '0.1s ease'; var getDeg = parseInt(window.getComputedStyle(_dom.ModalImage.children[0], null).getPropertyValue("rotate").replace('deg', '')); let setDeg = getDeg - 45; _dom.ModalImage.children[0].style.rotate = `${setDeg}deg`; dirty = true; }, rotateRight() { if (dirty) { this.update() } if (_dom.ModalImage.children[0].style.transition != '0.1s ease') _dom.ModalImage.children[0].style.transition = '0.1s ease'; var getDeg = parseInt(window.getComputedStyle(_dom.ModalImage.children[0], null).getPropertyValue("rotate").replace('deg', '')); let setDeg = getDeg + 45; _dom.ModalImage.children[0].style.rotate = `${setDeg}deg`; dirty = true; }, zoomIn() { if (dirty) { this.update(); } if (_dom.ModalImage.style.transition != '0.15s ease') _dom.ModalImage.style.transition = '0.15s ease' amount = 1.2; scale *= amount; dirty = true; }, zoomOut() { if (dirty) { this.update() } if (_dom.ModalImage.style.transition != '0.15s ease') _dom.ModalImage.style.transition = '0.15s ease'; amount = 1 / 1.2; scale *= amount; dirty = true; }, imgTop() { if (dirty) { this.update() } if (_dom.ModalImage.style.transition != 'unset') _dom.ModalImage.style.transition = 'unset'; if (_dom.ModalImage.children[0].style.rotate != '0deg') _dom.ModalImage.children[0].style.rotate = '0deg'; //oldY = centerY; contRect = _dom.ImgModal.getBoundingClientRect(); imgRect = _dom.ModalImage.getBoundingClientRect(); newY = ((contRect.height * 0.5) - (imgRect.height * 0.5)); pos.x = centerX; pos.y = centerY - newY; dirty = true; }, imgBottom() { if (dirty) { this.update() } if (_dom.ModalImage.style.transition != 'unset') _dom.ModalImage.style.transition = 'unset'; if (_dom.ModalImage.children[0].style.rotate != '0deg') _dom.ModalImage.children[0].style.rotate = '0deg'; contRect = _dom.ImgModal.getBoundingClientRect(); imgRect = _dom.ModalImage.getBoundingClientRect(); newY = ((contRect.height * 0.5) - (imgRect.height * 0.5)); pos.x = centerX; pos.y = centerY + newY; dirty = true; }, toggleBG() { let getAttr = toggleElement(12).getAttribute('data-toggle'); let buttonBG = getAttr == 'true' ? '1' : '0.75'; let imgSrc = getAttr == 'true' ? `https://www.svgrepo.com/show/510902/checkbox-unchecked.svg` : `https://www.svgrepo.com/show/510903/checkbox-fill.svg`; let buttonValue = getAttr == 'true' ? 'false' : 'true'; _dom.ImgModal.style.backgroundColor = `rgba(55, 63, 61, ${buttonBG})`; toggleElement(12).src = imgSrc; toggleElement(12).setAttribute('data-toggle', buttonValue); }, toggleRender() { let getAttr = toggleElement(13).getAttribute('data-toggle'); let buttonRender = getAttr == 'true' ? 'crisp-edges' : 'auto'; let imgSrc = getAttr == 'true' ? `https://www.svgrepo.com/show/377238/check.svg` : `https://www.svgrepo.com/show/510899/check-big.svg`; let buttonValue = getAttr == 'true' ? 'false' : 'true'; _dom.ModalImage.children[0].style.imageRendering = buttonRender; toggleElement(13).src = imgSrc; toggleElement(13).setAttribute('data-toggle', buttonValue); }, hFlip() { let getAttr = toggleElement(10).getAttribute('data-toggle'); if (_dom.ModalImage.children[0].style.transition != 'unset') _dom.ModalImage.children[0].style.transition = 'unset'; flipX = getAttr == 'true' ? '-1' : '1'; buttonValue = getAttr == 'true' ? 'false' : 'true'; toggleElement(10).style.scale = `${flipX} ${flipY}`; _dom.ModalImage.children[0].style.scale = `${flipX} ${flipY}`; toggleElement(10).setAttribute('data-toggle', buttonValue); }, vFlip() { let getAttr = toggleElement(11).getAttribute('data-toggle'); if (_dom.ModalImage.children[0].style.transition != 'unset') _dom.ModalImage.children[0].style.transition = 'unset'; flipY = getAttr == 'true' ? '-1' : '1'; buttonValue = getAttr == 'true' ? 'false' : 'true'; toggleElement(11).style.scale = `${flipX} ${flipY}`; _dom.ModalImage.children[0].style.scale = `${flipX} ${flipY}`; toggleElement(11).setAttribute('data-toggle', buttonValue); }, hFitScreen() { if (dirty) { this.update() }; if (_dom.ModalImage.style.transition != '0.25s ease') _dom.ModalImage.style.transition = '0.25s ease'; this.reset; amount = window.innerWidth / _dom.ModalImage.children[0].width; scale = amount; console.log(centerX, centerY); dirty = true; }, vFitScreen() { if (dirty) { this.update() }; if (_dom.ModalImage.style.transition != '0.25s ease') _dom.ModalImage.style.transition = '0.25s ease'; this.reset; amount = window.innerHeight / _dom.ModalImage.children[0].height; scale = amount; console.log(centerX, centerY); dirty = true; } }; return API; })(); _dom.ModalImage.style.transform = `matrix(1,0,0,1,${centerX},${centerY}`; const Apply = () => { view.applyTo(_dom.ModalImage); }; const proceedTo = { UpdateVars: () => { view.updateVariables(); Apply() }, Reset: () => { view.reset(); Apply() }, RealSize: () => { view.realSize(); Apply() }, RotateLeft: () => { view.rotateLeft(); Apply() }, RotateRight: () => { view.rotateRight(); Apply() }, ZoomIn: () => { view.zoomIn(); Apply() }, ZoomOut: () => { view.zoomOut(); Apply() }, TopOfImg: () => { view.imgTop(); Apply() }, BottomOfImg: () => { view.imgBottom(); Apply() }, toggleBG: () => { view.toggleBG(); Apply() }, toggleRender: () => { view.toggleRender(); Apply() }, hFlip: () => { view.hFlip(); Apply() }, vFlip: () => { view.vFlip(); Apply() }, vFitScreen: () => { view.vFitScreen(); Apply() }, hFitScreen: () => { view.hFitScreen(); Apply() } }; var _iFuncs = [ proceedTo.Reset, proceedTo.ZoomIn, proceedTo.ZoomOut, proceedTo.RotateLeft, proceedTo.RotateRight, proceedTo.RealSize, proceedTo.hFitScreen, proceedTo.vFitScreen, proceedTo.TopOfImg, proceedTo.BottomOfImg, proceedTo.hFlip, proceedTo.vFlip, proceedTo.toggleBG, proceedTo.toggleRender, ]; function setEvents() { ["cancel", "click"].forEach((types) => // Since you also want to be a chocolate starfish, fine have it your way you knob jocky. _dom.ImgModal.addEventListener(types, proceedTo.Reset) ); ["cancel", "click"].forEach((types) => // Twotty knob goblins... _dom.ImgModal.addEventListener(types, modalClose) ); ["mousemove", "mousedown", "mouseup", "mouseout"].forEach((types) => _dom.ModalImage.addEventListener(types, mouseEvent, { passive: false }) ); _dom.ModalImage.addEventListener("wheel", mouseWheelEvent, { passive: false }); _dom.ModalImage.addEventListener("dblclick", proceedTo.Reset, { passive: false }); _iFuncs.forEach((events) => _dom.ModalDock.children[_iFuncs.indexOf(events)].addEventListener("click", events, false) ); document.addEventListener("keydown", keyPressEvent); window.addEventListener("resize", proceedTo.UpdateVars); _dom.ModalInfoBtn.addEventListener("click", showHelp); _dom.ModalInfoField.children[0].children[1].addEventListener("click", showHelp); //addEvent(infoArrow, "click", showHelp, {once: true}); }; setEvents() function removeEvents() { //Since you want to be a piece of #$%@, fine, @#$% you... ["cancel", "click"].forEach((types) => _dom.ImgModal.removeEventListener(types, proceedTo.Reset) ); ["cancel", "click"].forEach((types) => _dom.ImgModal.removeEventListener(types, modalClose) ); ["mousemove", "mousedown", "mouseup", "mouseout"].forEach((types) => _dom.ModalImage.removeEventListener(types, mouseEvent, { passive: false }) ); _dom.ModalImage.removeEventListener("wheel", mouseWheelEvent, { passive: false }); _dom.ModalImage.removeEventListener("dblclick", proceedTo.Reset, { passive: false }); _iFuncs.forEach((events) => _dom.ModalDock.children[_iFuncs.indexOf(events)].removeEventListener("click", events, false) ); document.removeEventListener("keydown", keyPressEvent); window.removeEventListener("resize", proceedTo.UpdateVars); _dom.ModalInfoBtn.removeEventListener("click", showHelp); _dom.ModalInfoField.children[1].removeEventListener("click", showHelp); //addEvent(infoArrow, "click", showHelp, {once: true}); }; const mouse = { x: 0, y: 0, oldX: 0, oldY: 0, button: false }; function mouseEvent(e) { if (e.type === "mousedown") { mouse.button = true }; if (e.type === "mouseup" || e.type === "mouseout") { mouse.button = false }; mouse.oldX = mouse.x; mouse.oldY = mouse.y; mouse.x = e.pageX; mouse.y = e.pageY; if (mouse.oldX != 0 || mouse.oldY != 0) { if (mouse.button) { // pan view.pan({ x: mouse.x - mouse.oldX, y: mouse.y - mouse.oldY }); view.applyTo(_dom.ModalImage); }; }; e.preventDefault(); }; function mouseWheelEvent(e) { if (e.shiftKey) { const x = e.pageX - (_dom.ModalImage.children[0].width / 2); const y = e.pageY - (_dom.ModalImage.children[0].height / 2); if (e.deltaY < 0) { view.scaleAt({ x, y }, 1.1); view.applyTo(_dom.ModalImage); } else { view.scaleAt({ x, y }, 1 / 1.1); view.applyTo(_dom.ModalImage); }; e.preventDefault(); }; }; function toggleInterfaceEvent() { let getAttr = _dom.ModalDock.getAttribute('data-toggle'); let result = getAttr == 'true' ? 'opacity: 0.0' : null; let toggle = getAttr == 'true' ? 'false' : 'true'; _dom.ModalDock.style = _dom.ModalInfoBtn.style = _dom.ModalCloseBtn.style = result; _dom.ModalDock.setAttribute('data-toggle', toggle); }; var isOnDiv = false; _dom.ModalImage.addEventListener("mouseenter", () => { isOnDiv = true }); _dom.ModalImage.addEventListener("mouseleave", () => { isOnDiv = false }); _dom.ImgModal.addEventListener("mousedown", cursorHold, { passive: true }); _dom.ImgModal.addEventListener("mouseup", cursorReset); document.addEventListener("keyup", cursorReset); function cursorReset(e) { if (e.repeat) return; _dom.ModalImage.style.cursor = 'all-scroll'; }; function cursorHold(e) { if (e.repeat) return; _dom.ModalImage.style.cursor = 'none'; }; function cursorMagnify() { if (_dom.ModalImage.style.cursor == 'zoom-in') return; _dom.ModalImage.style.cursor = 'zoom-in'; }; const KEY_HANDLERS = { F1: () => console.log('You pressed F1.'), ArrowUp: () => console.log('You pressed ↑.'), Escape: () => modalClose(), KeyH: () => toggleInterfaceEvent(), KeyC: () => proceedTo.toggleBG(), KeyV: () => proceedTo.toggleRender(), ShiftLeft: () => cursorMagnify(), ShiftRight: () => cursorMagnify(), Minus: () => proceedTo.ZoomOut(), Equal: () => proceedTo.ZoomIn(), KeyK: () => proceedTo.hFlip(), }; function keyPressEvent(e) { e.preventDefault(); const handler = KEY_HANDLERS[e.code]; if (e.repeat) return; if (handler) { handler(); return; }; console.log('Pressed a key without a handler.'); }; infoKeys = [{ "Reset": "Resets image position and scale, toggle settings remain active." }, { "Zoom-In": "Increases image size by set amount. Zooms from Center." }, { "Zoom-Out": "Decreases image size by set amount. Zooms from Center." }, { "Rotate Left": "Rotates image left." }, { "Rotate Right": "Rotates image Right." }, { "Real Size": "Shows image at true size, removing page scaling." }, { "Fit Height to Screen": "Expands Image Height to the edges of the screen." }, { "Fit Width to Screen": "Expands Image width to the edges of the screen." }, { "To-Top": "Goes to the top of an image, Zoom remains intitial size." }, { "To-Bottom": "Goes to the bottom of an image, Zoom remains intitial size." }, { "Flip Horizontally": "Flips the Image Horizontally." }, { "Flip Vertically": "Flips the Image Vertically." }, { "Toggle Background": "Toggles between image view background being a solid color to transparent." }, { "Toggle Rendering": "Toggles between image rendering smooth and pixelated." }, ]; for (var key in infoKeys) { let mTitle = Object.keys(infoKeys[key]); let mDesc = Object.values(infoKeys[key]); _dom.ModalHelpBtns.children[key].addEventListener("click", () => { if (_dom.ModalInfoField.children[1].children[1].querySelector('b').innerText != mTitle) { _dom.ModalInfoField.children[1].children[1].querySelector('b').innerText = mTitle; _dom.ModalInfoField.children[1].children[1].querySelector('p').innerText = mDesc; }; }); }; function modalClose() { if (_dom.ModalImage.style.transition != 'unset') _dom.ModalImage.style.transition = 'unset'; _dom.ImgModal.style.opacity = '0'; _dom.ImgModal.style.backgroundColor = 'rgba(55, 63, 61, 0)'; removeEvents(); setTimeout(() => { reset(); _dom.ImgModal.close(); }, "300"); }; }; buildModal(); }; }, 2500); })();