Skip to content

Instantly share code, notes, and snippets.

@hdk5
Last active November 6, 2023 18:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hdk5/b6261471096dc0c45a3563dc9af58949 to your computer and use it in GitHub Desktop.
Save hdk5/b6261471096dc0c45a3563dc9af58949 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Danbooru - Panzoom
// @namespace danbooru.hdk5
// @match *://*.donmai.us/*
// @grant none
// @version 20231103232546
// @author hdk5
// @downloadURL https://github.com/hdk5/danbooru.user.js/raw/master/dist/mediaasset-panzoom.user.js
// @updateURL https://github.com/hdk5/danbooru.user.js/raw/master/dist/mediaasset-panzoom.user.js
// @require https://unpkg.com/panzoom@9.4.3/dist/panzoom.min.js
// ==/UserScript==
// Moved to a new repo
// This script won't be updated here anymore
// https://github.com/hdk5/danbooru.user.js
/* global $ panzoom */
class MediaAssetComponent {
static initialize() {
$(".media-asset-component").each((i, el) => {
if (el.hasAttribute("ex-panzoom")) return;
el.setAttribute("ex-panzoom", "");
new MediaAssetComponent(el);
});
}
constructor(element) {
this.$component = $(element);
this.$component.css("top", "1rem");
this.$component.css("position", "sticky");
this.$component.css("--height", "calc(max(var(--min-asset-height), 100vh - max(1rem, var(--header-visible-height))))");
this.$component.css("max-height", "var(--height)");
this.$component.css("min-height", "var(--height)");
this.$component.css("overflow", "hidden");
this.$container = this.$component.find(".media-asset-container");
this.$container.css("width", "100%");
this.$container.css("height", "100%");
this.$zoomLevel = this.$component.find(".media-asset-zoom-level");
this.$zoomLevel.css("z-index", "1");
this.$zoomLevel.css("cursor", "pointer");
this.$zoomLevel.css("pointer-events", "all");
this.$panzoom = $('<div class="media-asset-panzoom"></div>');
this.$panzoom.css("width", "100%");
this.$panzoom.css("height", "100%");
this.$panzoom.css("flex", "1");
this.$panzoom.css("display", "flex");
this.$panzoom.css("align-items", "center");
this.$panzoom.css("justify-content", "center");
this.$image = this.$component.find(".media-asset-image");
if (this.$image.length) {
this.$panzoom.insertBefore(this.$image);
this.$image.detach().appendTo(this.$panzoom);
this.$image.off();
this.$image.css("cursor", "default");
this.$image.css("max-height", "100%");
this.$image.css("max-width", "100%");
this.panzoom = panzoom(this.$panzoom.get(0));
this.fit();
this.$zoomLevel.on("click", () => this.fit());
this.updateZoom();
this.panzoom.on("zoom", () => this.updateZoom());
new ResizeObserver(() => this.updateZoom()).observe(this.$image.get(0));
}
}
fit() {
this.panzoom.zoomAbs(0, 0, 1);
this.panzoom.moveTo(0, 0);
}
updateZoom() {
this.$zoomLevel.removeClass("hidden").text(`${Math.round(100 * this.zoomLevel)}%`);
// Rendering without smoothing makes checking for artifacts easier
this.$container.css("image-rendering", this.zoomLevel > 1 ? "pixelated" : "auto");
}
get zoomLevel() {
return (this.$image.width() * this.panzoom.getTransform().scale) / Number(this.$image.attr("width"));
}
}
$(MediaAssetComponent.initialize);
new MutationObserver((mutationList, observer) => {
$(MediaAssetComponent.initialize);
}).observe(document.body, { childList: true, subtree: true });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment