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 13
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
var fullAddress = window.location.href; // full address
var folderAddress = window.location.href;
var img = null;
var imageName = '';
var imageList = [];
var curPos = null, nextPos = null, prevPos = null;
var imgWidth = null, imgHeight = null;
var zoomAmount = 100;
var fitToScreen = false;
var imgRotation = 0;
if(isAnImage(fullAddress)) {
folderAddress = fullAddress.substring(0, fullAddress.lastIndexOf('/')) + '/';
img = document.getElementsByTagName('img')[0];
img.removeAttribute('width'); img.removeAttribute('height'); img.removeAttribute('class');
handleImage();
hookKeys();
createBox();
}
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.width;
imgHeight = img.height;
if(GM_getValue('zoomamount') != undefined) zoomAmount = parseInt(GM_getValue('zoomamount'));
if(GM_getValue('fittoscreen') != undefined) fitToScreen = JSON.parse(GM_getValue('fittoscreen'));
if(fitToScreen) { img.click(); img.click(); }
else { img.width = imgWidth * zoomAmount / 100; img.height = imgHeight * zoomAmount / 100; }
img.addEventListener('click', function() {
if(img.width <= window.innerWidth && img.height <= window.innerHeight && img.width != imgWidth && img.height != imgHeight) fitToScreen = true;
else if(img.width <= window.innerWidth && img.height <= window.innerHeight) return;
else fitToScreen = false;
zoomInfo();
});
}
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(spKeys) return;
if(document.activeElement.tagName == 'INPUT') {
if(key == 27) toggleJumpForm(); // 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) {
if(key == 188) imgRotation -= 10; // , key
else if(key == 190) imgRotation += 10; // . key
else if(key == 191) imgRotation = 0; // / key
imgRotation %= 360;
img.style.transform = 'rotate(' + imgRotation + 'deg)';
}
});
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 || key == 45 || key == 61) {
if(key == 48) { fitToScreen = fitToScreen ? false : true; zoomAmount = 100; } // 0 key
else if(key == 45) { zoomAmount -= zoomAmount <= 5 ? 0 : 5; fitToScreen = false; } // - key
else if(key == 61) { zoomAmount += zoomAmount >= 1000 ? 0 : 5; fitToScreen = false; }// = key
img.width = imgWidth * zoomAmount / 100;
img.height = imgHeight * zoomAmount / 100;
zoomInfo();
}
else if(key == 103) toggleJumpForm(); // G key
});
}
function zoomInfo() {
let text = '';
if(fitToScreen) { img.click(); img.click(); text = 'Fit to Screen'; zoomAmount = Math.ceil(img.width/imgWidth * 100); }
else {
if(img.width == imgWidth && img.height == imgHeight) zoomAmount = 100;
if(zoomAmount == 100) text = 'Original';
else text = zoomAmount + '%' + ' Zoom';
}
document.getElementById('zoomInfo').innerHTML = 'Size: ' + text + ' (' + img.width + 'x' + img.height + ')';
GM_setValue('zoomamount', zoomAmount);
GM_setValue('fittoscreen', fitToScreen);
}
function createBox() {
let div = document.createElement('div');
div.id = 'imgViewer';
div.style = 'z-index: 5; margin: 10px; padding: 10px 20px; border: 1px solid #555; border-radius: 10px; top: 0; left: 0; position: fixed; display: inline-block; opacity: 0.8; background-color: #111; color: #AAA; font-family: Georgia';
div.innerHTML += '<span style="font-weight: bold; color: #FFF;">Image ' + (curPos + 1) + '/' + imageList.length + '</span> ';
div.innerHTML += '<br><span style="color: #AF3;">' + decodeURIComponent(imageName) + '</span>';
div.innerHTML += '<br><span style="font-family: sans-serif; font-size: 70%;" id="zoomInfo"></span>';
div.innerHTML += '<br><br><span style="font-size: 75%;">Prev: ' + decodeURIComponent(imageList[prevPos]) + '<br>Next: ' + decodeURIComponent(imageList[nextPos]) + '</span>';
document.body.appendChild(div);
let jump = document.createElement('div');
jump.id = 'jumpToImage';
jump.style = 'z-index: 10; top: 22px; left: 15px; position: fixed;';
jump.innerHTML += '<a href="#" style="color: #3AF; text-decoration: none;">▼</a>';
jump.innerHTML += '<form name="jumpToImage" method="post" style="display: none; background-color: #3AF; padding: 3px; border-radius: 3px; margin-left: 15px"><input name="page" type="number" style="width: 60px;"></input><input type="submit" value="Jump"></input></form>';
document.body.appendChild(jump);
zoomInfo();
if(GM_getValue('imgviewerboxopacity') != undefined) {
div.style.opacity = GM_getValue('imgviewerboxopacity');
jump.style.opacity = GM_getValue('imgviewerboxopacity');
}
div.addEventListener('click', function() {
let opac = parseFloat(this.style.opacity);
opac = opac >= 1.0 ? 0.0 : opac + 0.2;
this.style.opacity = opac;
jump.style.opacity = opac;
GM_setValue('imgviewerboxopacity', opac);
});
jump.getElementsByTagName('a')[0].onclick = function() {
toggleJumpForm();
return false;
};
document.forms["jumpToImage"].onsubmit = function() {
let page = this["page"].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 toggleJumpForm() {
let jumpForm = document.forms["jumpToImage"];
jumpForm.style.display = jumpForm.style.display == 'block' ? 'none' : 'block';
document.forms["jumpToImage"]["page"].focus();
};