CACHE BUST UPDATE: Add-on that allows the user to scroll images so they can view pixel art in browser
当前为
// ==UserScript==
// @name Pixel Art Zoom
// @namespace http://tampermonkey.net/
// @version 0.2
// @description CACHE BUST UPDATE: Add-on that allows the user to scroll images so they can view pixel art in browser
// @author You
// @match *://*/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
// Add-on that allows the user to scroll images so they can view pixel art in browser
var classes = {
Pixelated: "pixelated-25CVD21ZZ"
};
var mouseDown = false;
var target = undefined;
var imgContainer = undefined;
var originalWidth = 0;
var originalHeight = 0;
var originalX = 0;
var originalY = 0;
var zoom = 1;
addCSSClasses();
// Setup event handling for mouse+keyboard
document.addEventListener("mousedown", function (e) {
// Only active if the ctlr key ispressed while clicking an img
var targetElem = e.target.tagName;
if ((e.ctrlKey && e.shiftKey) && targetElem === "IMG") {
mouseDown = true;
e.preventDefault();
e.stopPropagation();
createImgContainer(e);
zoom += 1;
resizeImg();
}
});
document.addEventListener("mouseup", function (e) {
if (mouseDown) {
e.preventDefault();
e.stopPropagation();
mouseDown = false;
}
});
document.addEventListener("wheel", function (e) {
// check if user has scrolled the mouse wheel(while holding ctrl) over the zoomable image.
if (e.ctrlKey && imgContainer && e.target.hasAttribute("data-open")) {
e.preventDefault();
e.stopPropagation();
if (e.deltaY < 0) {
zoom = Math.max(1, zoom - 1);
}
else if (e.deltaY > 0) {
zoom = Math.min(10, zoom + 1);
}
resizeImg();
}
});
function addCSSClasses() {
var head = document.head;
var newCss = document.createElement("style");
newCss.type = "text/css";
newCss.innerHTML = "\n." + classes.Pixelated + "{\n image-rendering: -webkit-optimize-contrast; \n image-rendering: -webkit-crisp-edges; \n image-rendering: -moz-crisp-edges; \n image-rendering: -o-crisp-edges; \n image-rendering: pixelated; \n -ms-interpolation-mode: nearest-neighbor; \n position:absolute;\n z-index: 1000000;\n box-shadow: 0 19px 38px rgba(0, 0, 0, 0.6), 0 15px 12px rgba(0, 0, 0, 0.46);\n background: #BBBC94;\n}\n";
head.appendChild(newCss);
}
function resizeImg() {
if (target === undefined || imgContainer === undefined)
throw new Error("target or imageContainer were undefined");
// set new image dimensions based on zoom level;
var targetWidth = zoom * originalWidth;
var targetHeight = zoom * originalHeight;
target.style.width = targetWidth + "px";
target.style.height = targetHeight + "px";
// try to position the image nicely so it fits on screen without user needing to scroll.
// Tries to center, but if that isn't possible, then just position at top-left corner
if (originalX + targetWidth > window.scrollX + window.innerWidth) {
imgContainer.style.left = window.scrollX + Math.max(0, Math.floor((window.innerWidth - targetWidth) / 2)) + "px";
}
else {
imgContainer.style.left = Math.max(window.scrollX, originalX - (targetWidth - originalWidth) / 2) + "px";
}
if (originalY + targetHeight > window.scrollY + window.innerHeight) {
imgContainer.style.top = window.scrollY + Math.max(0, Math.floor((window.innerHeight - targetHeight) / 2)) + "px";
}
else {
imgContainer.style.top = Math.max(window.scrollY, originalY - (targetHeight - originalHeight) / 2) + "px";
}
}
function createImgContainer(e) {
if (imgContainer !== undefined)
return; // avoid creating duplicates
target = e.target;
// create container for image that is absolutely positioned
imgContainer = document.createElement("div");
var offset = cumulativeOffset();
imgContainer.style.top = offset.top + "px";
imgContainer.style.left = offset.left + "px";
imgContainer.className = classes.Pixelated; // sets rendering mode to crisp pixels.
// created a copy of the image we want to scroll since we need to modify its properties for zooming.
target = target.cloneNode(true);
target.removeAttribute("style"); // remove any cruft that modifies the size, padding, etc.
target.removeAttribute("class"); // same
target.removeAttribute("height"); // same
target.removeAttribute("width"); // same
// Add a custom attribute so we can differentiate between events on the zoomable image and others
target.setAttribute("data-open", "active");
/// save some of the original image's properties
originalWidth = target.width;
originalHeight = target.height;
originalX = offset.left;
originalY = offset.top;
// And now add the container and image to the DOM
imgContainer.appendChild(target);
// It doesn't matter that we insert it as the first element, but is easier for debugging.
document.body.insertBefore(imgContainer, document.body.firstElementChild);
// Focus the image and add event to clean up when user clicks away from image
target.setAttribute("tabindex", "0"); // Needed so the image can be focused.
target.addEventListener("blur", function () {
destroyImgContainer();
}, true);
target.focus(); // Can only be called AFTER the img is added to the DOM
/** Find the position of an element relative to the top-left corner of document */
function cumulativeOffset() {
var bbox = target.getBoundingClientRect();
// damn margin
var style = window.getComputedStyle(target);
var marginLeft = parseInt(style.marginLeft.replace(" px", ""), 10);
var marginTop = parseInt(style.marginTop.replace(" px", ""), 10);
return {
left: bbox.left + window.scrollX - marginLeft,
top: bbox.top + window.scrollY - marginTop
};
}
}
function destroyImgContainer() {
if (imgContainer === undefined)
return;
document.body.removeChild(imgContainer);
// reset to initial state
target = undefined;
imgContainer = undefined;
zoom = 1;
}
})();