您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
View images in local directories. Can navigate, zoom, rotate.
当前为
// ==UserScript== // @name Local Image Viewer // @description View images in local directories. Can navigate, zoom, rotate. // @namespace localimgviewer // @include file:///* // @version 15 // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // ==/UserScript== var fullAddress = window.location.href; // full address var folderAddress = window.location.href; var img = null; var imgWidth = null, imgHeight = null; var imageList = []; var settingsObj = { 'imagedisplay': 0, 'imagezoom': 100, 'imagerotation': 0, 'imageopacity': 1, 'panelsopacity': 1, }; var imageName = ''; var curPos = null, nextPos = null, prevPos = null; if(isAnImage(fullAddress)) { folderAddress = fullAddress.substring(0, fullAddress.lastIndexOf('/')) + '/'; img = document.getElementsByTagName('img')[0]; img.removeAttribute('width'); img.removeAttribute('height'); img.removeAttribute('class'); if(GM_getValue('settings') !== undefined) settingsObj = JSON.parse(GM_getValue('settings')); handleImage(); hookKeys(); createPanels(); applySettings(); } else { if(fullAddress[fullAddress.length - 1] != '/') window.location.assign(fullAddress + '/'); populateImageArray(); document.addEventListener('click', function() { populateImageArray(); }); } function populateImageArray() { imageList = []; let links = document.getElementsByTagName('a'); for(let i = 0, j = ''; i < links.length; i++) { j = links[i].getAttribute('href'); j = j.indexOf('/') != -1 ? j.substring(j.lastIndexOf('/') + 1) : j; // if the href contains full addr, just get the string after last slash if(isAnImage(j)) imageList.push(j); } if(imageList.length) { curPos = 0; nextPos = 0; prevPos = imageList.length - 1; hookKeys(); } GM_setValue('imagelist_' + folderAddress, JSON.stringify(imageList)); } function handleImage() { img.style.position = 'absolute'; img.style.textAlign = 'center'; img.style.margin = 'auto'; img.style.top = '0'; img.style.right = '0'; img.style.bottom = '0'; img.style.left = '0'; document.body.style.background = '#222'; imageName = fullAddress.substring(fullAddress.lastIndexOf('/') + 1); imageList = JSON.parse(GM_getValue('imagelist_' + folderAddress)); curPos = imageList.indexOf(imageName); nextPos = curPos == imageList.length - 1 ? 0 : curPos + 1; prevPos = curPos == 0 ? imageList.length - 1 : curPos - 1; imgWidth = img.naturalWidth; imgHeight = img.naturalHeight; } function isAnImage(x) { var ext = x.split('.').pop(); if(ext == 'jpg' || ext == 'jpeg' || ext == 'bmp' || ext == 'png' || ext == 'gif' || ext == 'tga') return true; return false; } function hookKeys() { document.addEventListener('keydown', function(e) { let key = e.keyCode || e.which; let spKeys = e.ctrlKey || e.shiftKey || e.altKey; // console.log('keydown key: ' + key + ' spkeys: ' + spKeys); // if(e.ctrlKey && key == 46) { deletesettings(); console.log('deleting settings'); } if(spKeys) return; if(document.activeElement.tagName == 'INPUT') { if(key == 27) document.getElementById('imgViewer-prefs').lastChild.click(); // key ESC return; } if(key == 39) window.location.assign(imageList[nextPos]); // right arrow key else if(key == 37) window.location.assign(imageList[prevPos]); // left arrow key else if(key == 220) { if(fullAddress != folderAddress) window.location.assign(folderAddress); } // \ key else if(key == 188 || key == 190 || key == 191) { let curRotation = parseInt(document.getElementById('imgViewer-settings').getElementsByTagName('input')[4].value); if(key == 188) document.getElementById('imgViewer-settings').getElementsByTagName('input')[4].value = curRotation - 10; // , key else if(key == 190) document.getElementById('imgViewer-settings').getElementsByTagName('input')[4].value = curRotation + 10; // . key else if(key == 191) document.getElementById('imgViewer-settings').getElementsByTagName('input')[4].value = 0; // / key if(document.getElementById('imgViewer-settings').getElementsByTagName('input')[4].value < 0) document.getElementById('imgViewer-settings').getElementsByTagName('input')[4].value = 350; document.getElementById('imgViewer-settings').getElementsByTagName('input')[4].onchange(); } }); document.addEventListener('keypress', function(e) { let key = e.keyCode || e.which; let spKeys = e.ctrlKey || e.shiftKey || e.altKey; // console.log('keypress key: ' + key + ' spkeys: ' + spKeys); if(spKeys) return; if(document.activeElement.tagName == 'INPUT') return; if(key == 48) { let nextDisplay = settingsObj['imagedisplay'] == 2 ? 0 : settingsObj['imagedisplay'] + 1; document.getElementById('imgViewer-settings').getElementsByTagName('input')[nextDisplay].click(); } else if(key == 45 || key == 61) { let curZoom = parseInt(document.getElementById('imgViewer-settings').getElementsByTagName('input')[3].value); document.getElementById('imgViewer-settings').getElementsByTagName('input')[2].click(); if(key == 45) document.getElementById('imgViewer-settings').getElementsByTagName('input')[3].value = curZoom - 5; // - key else if(key == 61) document.getElementById('imgViewer-settings').getElementsByTagName('input')[3].value = curZoom + 5; // = key document.getElementById('imgViewer-settings').getElementsByTagName('input')[3].onchange(); } else if(key == 103) document.getElementById('imgViewer-prefs').lastChild.click(); // G key }); } function createPanels() { let mainDiv = document.createElement('div'); mainDiv.id = 'imgViewer'; mainDiv.style = 'color: #BBB; font-family: Tahoma, sans-serif; font-size: 13px; position: fixed; z-index: 5; top: 5px; left: 5px;'; mainDiv.innerHTML = '<div id="imgViewer-prefs"></div><div id="imgViewer-imageinfo"></div><div id="imgViewer-settings"></div><div id="imgViewer-filelist"></div><div id="imgViewer-jump"></div>'; document.body.appendChild(mainDiv); let prefsDiv = document.getElementById('imgViewer-prefs'); let infoDiv = document.getElementById('imgViewer-imageinfo'); let settingsDiv = document.getElementById('imgViewer-settings'); let listDiv = document.getElementById('imgViewer-filelist'); let jumpDiv = document.getElementById('imgViewer-jump'); prefsDiv.innerHTML = '<a href="#" title="Image info"><b><i>i</i></b></a><a href="#" title="Settings">⚙</a><a href="#" title="Image list">☰</a><a href="#" title="Jump to image">↳</a>'; infoDiv.innerHTML += '<span class="panel-title">Image ' + (curPos + 1) + '/' + imageList.length + '</span>'; infoDiv.innerHTML += '<span style="color: #AF3; font-size: 16px; display: block;">' + decodeURIComponent(imageName) + '</span>'; infoDiv.innerHTML += '<span style="font-family: sans-serif; font-size: 85%; display: block; margin-bottom: 16px;" id="zoomInfo"></span>'; infoDiv.innerHTML += '<span style="font-size: 85%; display: block;"><a href="' + imageList[prevPos] + '">Prev</a> ' + decodeURIComponent(imageList[prevPos]) + '</span>'; infoDiv.innerHTML += '<span style="font-size: 85%; display: block;"><a href="' + imageList[nextPos] + '">Next</a> ' + decodeURIComponent(imageList[nextPos]) + '</span>'; settingsDiv.innerHTML += '<span class="panel-title">Settings</span>'; settingsDiv.innerHTML += '<span>Image size: <label style="width: 100%;"><input type="radio" name="imgsize" value="0">Original</label> <label><input type="radio" name="imgsize" value="1">Fit to screen</label> <label><input type="radio" name="imgsize" value="2">Zoom (%) <input type="number" min="5" max="5000" default="100" style="width: 70px;"> <a href="#"></a></label></span>'; settingsDiv.innerHTML += '<label>Image rotation (°): <input type="number" min="0" max="360" default="0" style="width: 50px;"> <a href="#"></a></label>'; settingsDiv.innerHTML += '<label>Image opacity: <input type="range" min="5" max="100" default="100" style="font-size: 1px; width: 90px; height: 6px;"> <span></span>% <a href="#"></a></label>'; settingsDiv.innerHTML += '<label>Panels opacity: <input type="range" min="5" max="100" default="100" style="font-size: 1px; width: 90px; height: 6px;"> <span></span>% <a href="#"></a></label>'; listDiv.innerHTML += '<span class="panel-title">Image list</span><select size="15"></select>'; jumpDiv.innerHTML += '<form name="jumpToImage"><input type="number" style="width: 50px; height: 100%; font-size: 10px;"> <input type="submit" value="Jump" style="width: 50px; height: 100%; font-size: 10px;"></form>'; let panels = mainDiv.getElementsByTagName('div'); for(let i=0; i<panels.length; i++) { panels[i].style = 'background-color: #111; margin-bottom: 8px; padding: 8px 14px 14px 12px; border-radius: 6px; border: 1px solid #3A3A3A; display: table;'; if(i == 0) { panels[i].style.fontSize = '16px'; panels[i].style.textAlign = 'center'; panels[i].style.backgroundColor = 'rgba(0,0,0,0.8)'; panels[i].style.borderRadius = '30px'; panels[i].style.padding = '0px 11px 2px'; } else if(i == 4) panels[i].style = 'position: absolute; top: 0; left: 116px; background-color: #18F; padding: 2px; border-radius: 6px; width: 110px; height: 20px; font-size: 10px; text-align: center;'; } let links = document.getElementsByTagName('a'); for(let i=0; i<links.length; i++) links[i].style = 'color: #FFF; text-decoration: none'; let panelTitle = mainDiv.getElementsByClassName('panel-title'); let prefs = prefsDiv.getElementsByTagName('a'); for(let i=0; i<panelTitle.length; i++) { panelTitle[i].style = 'position: relative; color: #3AF; font-family: Georgia; font-size: 16px; margin-left: -4px; display: block; margin-bottom: 8px; padding-right: 20px;'; panelTitle[i].innerHTML += '<a href="#" style="color: #FFF; text-decoration: none; position: absolute; top: -7; right: -8;">✖</a>'; panelTitle[i].children[0].onclick = function() { prefs[i].click(); return false; }; } let resets = settingsDiv.getElementsByTagName('a'); for(let i=1; i<resets.length; i++) { resets[i].innerHTML = '∅'; resets[i].style.color = '#F22'; resets[i].onclick = function() { if(this.previousElementSibling.tagName == 'INPUT') { this.previousElementSibling.value = this.previousElementSibling.getAttribute('default'); this.previousElementSibling.onchange(); } else { this.previousElementSibling.previousElementSibling.value = this.previousElementSibling.previousElementSibling.getAttribute('default'); this.previousElementSibling.previousElementSibling.onchange(); } return false; }; } for(let i=0; i<prefs.length; i++) { prefs[i].style.display = 'inline-block'; prefs[i].style.width = '21px'; prefs[i].style.height = '21px'; prefs[i].onclick = function() { let j = mainDiv.children[i+1]; if(i == 3) { j.style.display = j.style.display == 'none' ? 'block' : 'none'; j.children[0].children[0].focus(); } else j.style.display = j.style.display == 'none' ? 'table' : 'none'; settingsObj['showpanels' + (i+1)] = j.style.display; GM_setValue('settings', JSON.stringify(settingsObj)); return false; }; } let fileList = listDiv.getElementsByTagName('select')[0]; for(let i=0; i<imageList.length; i++) { fileList.innerHTML += '<option value="' + i + '" ' + (i==curPos ? 'selected' : '') + '>' + '(' + (i + 1) + ') ' + decodeURIComponent(imageList[i]) + '</option>'; } fileList.onchange = function() { window.location.assign(imageList[this.value]); }; let inputs = settingsDiv.getElementsByTagName('input'); for(let i=0; i<inputs.length; i++) { if(i == 0) { inputs[i].parentElement.style = 'display: inline-block;'; inputs[i].parentElement.parentElement.style = 'display: block; margin-bottom: 8px;'; } else if(i == 1 || i == 2) inputs[i].parentElement.style = 'display: block; margin-left: 71px'; else if(i >= 4) inputs[i].parentElement.style = 'display: block; margin-bottom: 8px;'; inputs[i].onchange = function() { if(i == 0 || i == 1 || i == 2) { img_doDisplay(this.value); if(i == 2) img_doZoom(this.nextElementSibling.value); } else if(i == 3) { this.previousElementSibling.click(); this.value = this.value == '' ? settingsObj['imagezoom'] : this.value >= 5000 ? 5000 : this.value < 5 ? 5 : this.value; img_doZoom(this.value); } else if(i == 4) { // rotate this.value = this.value == '' ? 0 : this.value >= 360 ? 0 : this.value < 0 ? 0 : this.value; img_doRotation(this.value); } else if(i == 5 || i == 6) { // opacity this.value = this.value > 100 ? 100 : this.value < 5 ? 5 : this.value ? this.value : 5; this.nextElementSibling.innerHTML = this.value; if(i == 5) { img.style.opacity = this.value / 100; settingsObj['imageopacity'] = this.value / 100; } else { mainDiv.style.opacity = this.value / 100; settingsObj['panelsopacity'] = this.value / 100; } GM_setValue('settings', JSON.stringify(settingsObj)); } zoomInfo(); }; } img.addEventListener('click', function() { if(imgWidth > window.innerWidth || imgHeight > window.innerHeight) { if(img.width == imgWidth && img.height == imgHeight) document.getElementById('imgViewer-settings').getElementsByTagName('input')[0].click(); else document.getElementById('imgViewer-settings').getElementsByTagName('input')[1].click(); } }); document.forms["jumpToImage"].onsubmit = function() { let page = this.children[0].value; if(page == '') { alert('Type the image number and press Jump'); return false; } page = parseInt(page); if(page <= 0 || page > imageList.length) alert('Image #' + page + ' doesn\'t exist'); else window.location.href = folderAddress + imageList[page - 1]; return false; }; } function img_doDisplay(fit) { if(fit == 0) { img.removeAttribute('width'); img.removeAttribute('height'); } else { img.removeAttribute('width'); img.removeAttribute('height'); if(imgWidth > window.innerWidth) { img.width = window.innerWidth; if(imgHeight > window.innerHeight) { img.height = window.innerHeight; img.removeAttribute('width'); } } else if(imgHeight > window.innerHeight) { img.height = window.innerHeight; if(imgWidth > window.innerWidth) { img.width = window.innerWidth; img.removeAttribute('height'); } } else { img.width = imgWidth; img.height = imgHeight; } } settingsObj['imagedisplay'] = parseInt(fit); GM_setValue('settings', JSON.stringify(settingsObj)); } function img_doZoom(percent) { if(percent == 100) { img.removeAttribute('width'); img.removeAttribute('height'); } else { img.width = percent / 100 * imgWidth; img.height = percent / 100 * imgHeight; } settingsObj['imagezoom'] = parseInt(percent); GM_setValue('settings', JSON.stringify(settingsObj)); } function img_doRotation(angle) { if(angle == 0) img.style.transform = ''; else img.style.transform = 'rotate(' + angle + 'deg)'; settingsObj['imagerotation'] = parseInt(angle); GM_setValue('settings', JSON.stringify(settingsObj)); } function zoomInfo() { let text = ''; if(settingsObj['imagedisplay'] == 0) text = 'Original'; else if(settingsObj['imagedisplay'] == 1) text = 'Fit to screen'; else if(settingsObj['imagedisplay'] == 2) text = settingsObj['imagezoom'] + '% zoom'; document.getElementById('zoomInfo').innerHTML = text + ' (' + img.width + 'x' + img.height + ')'; GM_setValue('settings', JSON.stringify(settingsObj)); } function applySettings() { console.log(settingsObj); if(settingsObj['imagezoom'] !== undefined) document.getElementById('imgViewer-settings').children[1].children[2].children[1].value = settingsObj['imagezoom']; if(settingsObj['imagedisplay'] !== undefined) { document.getElementById('imgViewer-settings').children[1].children[settingsObj['imagedisplay']].children[0].click(); if(document.getElementById('imgViewer-settings').children[1].children[2].children[0].checked == true) img_doZoom(settingsObj['imagezoom']); } if(settingsObj['imagerotation'] !== undefined) { document.getElementById('imgViewer-settings').children[2].children[0].value = settingsObj['imagerotation']; img_doRotation(settingsObj['imagerotation']); } if(settingsObj['imageopacity'] !== undefined) { img.style.opacity = settingsObj['imageopacity']; document.getElementById('imgViewer-settings').children[3].children[0].value = settingsObj['imageopacity'] * 100; document.getElementById('imgViewer-settings').children[3].children[1].innerHTML = settingsObj['imageopacity'] * 100; } if(settingsObj['panelsopacity'] !== undefined) { document.getElementById('imgViewer').style.opacity = settingsObj['panelsopacity']; document.getElementById('imgViewer-settings').children[4].children[0].value = settingsObj['panelsopacity'] * 100; document.getElementById('imgViewer-settings').children[4].children[1].innerHTML = settingsObj['panelsopacity'] * 100; } let j = document.getElementById('imgViewer'); for(let i=1; i<j.children.length; i++) { if(settingsObj['showpanels' + i] !== undefined) j.children[i].style.display = settingsObj['showpanels' + i]; } zoomInfo(); } /* function deletesettings() { var keys = GM_listValues(); for (var i=0, key=null; key=keys[i]; i++) GM_deleteValue(key); alert('all settings deleted'); }; */
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址