Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Jigsaw Explorer - qualité d'image (haute résolution)
- // @namespace local
- // @version 0.2
- // @description Fait travailler le jeu avec plus de pixels que ta fenêtre n'en affiche (×1,5 ou ×2) : image du puzzle et pièces plus détaillées, loupe plus nette. Bouton « HD » dans la barre pour changer (la page se recharge).
- // @match https://www.jigsawexplorer.com/*
- // @run-at document-start
- // @grant none
- // ==/UserScript==
- (function () {
- 'use strict';
- var FACTORS = [1, 1.5, 2]; // 1 = comportement normal du site
- var DEFAULT = 1.5;
- var STORE = 'jigex-quality-factor';
- var MAX_SIDE = 8192; // au-delà, certains navigateurs/cartes graphiques refusent le canvas
- function load() {
- try { var v = parseFloat(localStorage.getItem(STORE)); return FACTORS.indexOf(v) !== -1 ? v : DEFAULT; }
- catch (e) { return DEFAULT; }
- }
- function save(v) { try { localStorage.setItem(STORE, String(v)); } catch (e) {} }
- var factor = load();
- var desc = Object.getOwnPropertyDescriptor(window, 'devicePixelRatio');
- var realGet = desc && desc.get ? desc.get : function () { return 1; };
- var applied = 1;
- // Le jeu lit window.devicePixelRatio au démarrage pour fixer la taille de son canvas : on lui annonce un ratio plus grand.
- try {
- Object.defineProperty(window, 'devicePixelRatio', {
- configurable: true,
- get: function () {
- var real = realGet.call(window);
- var side = Math.max(window.innerWidth, window.innerHeight) || 1000;
- var f = Math.min(factor, MAX_SIDE / (side * real)); // limite de sécurité
- f = Math.max(1, f);
- applied = f;
- return real * f;
- }
- });
- } catch (e) { return; }
- function label() {
- var real = realGet.call(window);
- return 'Qualité : ×' + factor + (applied < factor - 0.01 ? ' (limitée à ×' + applied.toFixed(2) + ')' : '') + ' · écran ×' + real;
- }
- // ---- Bouton dans la barre du site + petit panneau ----
- var btn = null, panel = null, sel = null, info = null, note = null;
- function mk(tag, css, txt) { var e = document.createElement(tag); if (css) e.style.cssText = css; if (txt) e.textContent = txt; return e; }
- function refresh() {
- var tip = 'Qualité d\'image ×' + factor + (applied < factor - 0.01 ? ' (limitée à ×' + applied.toFixed(2) + ')' : '');
- if (btn) { btn.setAttribute('data-tooltip', tip); btn.title = tip; var l = btn.querySelector('.jq-lvl'); if (l) l.textContent = '×' + factor; }
- if (info) info.textContent = 'Écran : ×' + realGet.call(window).toFixed(2) + ' · appliqué : ×' + (realGet.call(window) * applied).toFixed(2);
- }
- function buildPanel() {
- panel = mk('div', 'position:fixed;z-index:2147483000;width:270px;padding:12px 14px;border-radius:10px;background:rgb(36,38,42);color:#eee;' +
- 'font:13px Arial,sans-serif;box-shadow:0 6px 24px rgba(0,0,0,.45);display:none;');
- panel.appendChild(mk('div', 'font-weight:bold;font-size:14px;margin-bottom:6px;', 'Qualité d\'image'));
- var r = mk('label', 'display:flex;align-items:center;justify-content:space-between;gap:8px;margin:7px 0;');
- r.appendChild(mk('span', '', 'Résolution'));
- sel = mk('select', ''); FACTORS.forEach(function (v) { var o = mk('option', '', v === 1 ? '×1 (normal)' : '×' + v); o.value = v; sel.appendChild(o); });
- sel.value = String(factor); r.appendChild(sel); panel.appendChild(r);
- info = mk('div', 'opacity:.75;font-size:12px;margin:4px 0;'); panel.appendChild(info);
- note = mk('div', 'opacity:.6;font-size:11px;margin-top:6px;', 'Un changement recharge la page. Plus haut = pièces et image plus détaillées, mais plus de mémoire.');
- panel.appendChild(note);
- sel.addEventListener('change', function () {
- factor = parseFloat(sel.value); save(factor); note.textContent = 'Rechargement…';
- setTimeout(function () { location.reload(); }, 500);
- });
- ['pointerdown', 'mousedown', 'click', 'wheel', 'keydown', 'contextmenu'].forEach(function (t) { panel.addEventListener(t, function (e) { e.stopPropagation(); }); });
- document.body.appendChild(panel);
- }
- // Reprend l'apparence des panneaux du site (menu du programme) pour que nos panneaux aient le même style
- function applyTheme(el) {
- try {
- var src = document.getElementById('jigex-prog-menu-tb') || document.getElementById('jigex-prog-menu');
- if (!src) return;
- var cs = getComputedStyle(src), bg = cs.backgroundColor;
- if (!bg || /rgba\(.*,\s*0\)$/.test(bg) || bg === 'transparent') { var tb = document.getElementById('jigex-prog-menu-tb'); if (tb) bg = getComputedStyle(tb).backgroundColor; }
- if (bg && !/rgba\(.*,\s*0\)$/.test(bg) && bg !== 'transparent') {
- var m = bg.match(/[\d.]+/g); // fond toujours opaque, même si celui du site est translucide
- el.style.background = m && m.length >= 3 ? 'rgb(' + m[0] + ',' + m[1] + ',' + m[2] + ')' : bg;
- }
- if (cs.color) el.style.color = cs.color;
- if (cs.fontFamily) el.style.fontFamily = cs.fontFamily;
- if (cs.borderRadius && cs.borderRadius !== '0px') el.style.borderRadius = cs.borderRadius;
- if (cs.boxShadow && cs.boxShadow !== 'none') el.style.boxShadow = cs.boxShadow;
- } catch (e) {}
- }
- function toggle(force) {
- if (!panel) buildPanel();
- var show = force === undefined ? panel.style.display === 'none' : force;
- if (show) {
- var br = btn.getBoundingClientRect();
- panel.style.top = Math.round(br.bottom + 6) + 'px';
- panel.style.left = Math.max(8, Math.min(window.innerWidth - 280, Math.round(br.right - 270))) + 'px';
- applyTheme(panel); refresh();
- }
- panel.style.display = show ? 'block' : 'none';
- }
- function buildBtn() {
- var clock = document.getElementById('jigex-clock'), bar = clock && clock.parentElement;
- btn = document.createElement('div');
- btn.id = 'jigex-quality-btn'; btn.className = 'niftybar-icon-button main-tb-btn'; btn.style.cssText = 'display:block;position:relative;cursor:pointer;';
- btn.innerHTML = '<svg class="niftybar-icon" width="24" height="24" viewBox="0 0 24 24" style="color:rgb(232,230,227)"><g style="fill:none;stroke:currentColor;stroke-width:2;stroke-linejoin:round">' +
- '<rect x="3" y="6" width="18" height="12" rx="2"/></g><text x="12" y="15" text-anchor="middle" style="fill:currentColor;font:bold 7px Arial,sans-serif">HD</text></svg>' +
- '<span class="jq-lvl" style="position:absolute;right:1px;bottom:1px;font:bold 9px Arial,sans-serif;color:rgb(232,230,227);pointer-events:none;"></span>';
- btn.addEventListener('click', function (e) { e.stopPropagation(); toggle(); });
- if (bar) bar.insertBefore(btn, clock);
- else { btn.style.cssText = 'position:fixed;left:8px;bottom:34px;z-index:100000;width:36px;height:36px;color:#fff;background:rgba(0,0,0,.55);border-radius:18px;'; document.body.appendChild(btn); }
- document.addEventListener('mousedown', function (e) { if (panel && panel.style.display !== 'none' && !panel.contains(e.target) && !btn.contains(e.target)) toggle(false); }, true);
- refresh();
- }
- function start() {
- var tries = 0;
- (function wait() {
- if (document.getElementById('jigex-clock') || ++tries > 60) { if (!document.getElementById('jigex-quality-btn')) buildBtn(); }
- else setTimeout(wait, 500);
- })();
- }
- if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();
- setInterval(function () { var c = document.getElementById('jigex-clock'); if (btn && c && !btn.isConnected && c.parentElement) c.parentElement.insertBefore(btn, c); }, 2000);
- })();
Advertisement
Add Comment
Please, Sign In to add comment