Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Jigsaw Explorer - zoom molette
- // @namespace local
- // @version 0.16
- // @description Zoome dans le puzzle avec la molette, sans recharger ni redécouper les pièces (zoom d'affichage). Clic milieu + glisser = déplacer la vue. Touche Z = activer/couper. Bouton loupe dans la barre : réglages.
- // @match https://www.jigsawexplorer.com/*
- // @run-at document-start
- // @grant none
- // ==/UserScript==
- (function () {
- 'use strict';
- var MIN = 1, MAX = 6, edgeSize = 36, edgeSpeed = 14;
- var STORE = 'jigex-zoom-on';
- var on = true;
- try { on = localStorage.getItem(STORE) !== '0'; } catch (e) {}
- window.__jigexZoomOn = on;
- var z = 1, tx = 0, ty = 0; // zoom et décalage de l'affichage (px)
- var ctrlOnly = false, gripped = false, hoverPan = true, mX = -1, mY = -1, mOver = false, autoPan = false, held = false, lastX = 0, lastY = 0, baseW = 0, canvas = null, badge = null, panning = null, dragging = false, parentOverflow = null;
- // La transformation est portée par une feuille de style (et non par le style du canvas) : le site réécrit le style du canvas
- // à chaque prise/lâcher de pièce, ce qui effaçait le zoom.
- var styleEl = null;
- function ensureStyle() {
- if (styleEl && styleEl.isConnected) return;
- var host = document.head || document.documentElement; if (!host) return;
- styleEl = document.createElement('style');
- styleEl.textContent = 'html[data-jz] #jigex-canvas{transform-origin:0 0!important;transform:translate(var(--jzx),var(--jzy)) scale(var(--jzz))!important;}' +
- 'html[data-jz] :has(>#jigex-canvas){overflow:clip!important;}';
- host.appendChild(styleEl);
- }
- function getCanvas() { return canvas && canvas.isConnected ? canvas : (canvas = document.getElementById('jigex-canvas')); }
- function apply() {
- var c = getCanvas(); if (!c) return;
- var w = c.offsetWidth, h = c.offsetHeight;
- var mx = w * 0.4, my = h * 0.4; // marge libre autour du puzzle
- tx = Math.min(mx, Math.max(w * (1 - z) - mx, tx)); ty = Math.min(my, Math.max(h * (1 - z) - my, ty));
- var de = document.documentElement; ensureStyle();
- if (z > 1.0001) {
- de.style.setProperty('--jzx', tx + 'px'); de.style.setProperty('--jzy', ty + 'px'); de.style.setProperty('--jzz', z);
- de.setAttribute('data-jz', '1');
- } else {
- z = 1; tx = ty = 0; de.removeAttribute('data-jz');
- }
- refreshBadge();
- }
- function reset() { z = 1; tx = ty = 0; apply(); }
- function setOn(v) {
- on = v; window.__jigexZoomOn = on;
- try { localStorage.setItem(STORE, on ? '1' : '0'); } catch (e) {}
- if (!on) reset(); else refreshBadge();
- }
- window.addEventListener('pointerdown', function (e) { if (e.button === 0 && e.target === getCanvas()) gripped = true; }, true);
- ['pointerup', 'pointercancel', 'blur'].forEach(function (t) { window.addEventListener(t, function () { gripped = false; }, true); });
- try { ctrlOnly = localStorage.getItem('jigex-zoom-ctrl') === '1'; } catch (e) {}
- // ---- Molette : zoom autour du pointeur ----
- window.addEventListener('wheel', function (e) {
- var c = getCanvas();
- if (!on || !c || e.target !== c || e.metaKey || e.altKey || e.shiftKey) return;
- if (ctrlOnly ? !e.ctrlKey : (e.ctrlKey || gripped)) return; // sinon la molette sert à tourner les pièces du site
- e.preventDefault(); e.stopImmediatePropagation();
- var r = c.getBoundingClientRect();
- var px = (e.clientX - r.left) / z, py = (e.clientY - r.top) / z; // point visé, en coordonnées du canvas non zoomé
- var L = r.left - tx, T = r.top - ty; // position de base du canvas dans la page
- var nz = Math.min(MAX, Math.max(MIN, z * Math.pow(1.0022, -e.deltaY)));
- tx = e.clientX - L - px * nz; ty = e.clientY - T - py * nz; z = nz;
- apply();
- }, { capture: true, passive: false });
- // ---- Bouton de déplacement de la vue (touche P pour changer) ----
- var MODES = [
- { label: 'clic molette', btn: 1 }, { label: 'clic droit', btn: 2 }, { label: 'bouton précédent', btn: 3 },
- { label: 'bouton suivant', btn: 4 }, { label: 'clic gauche + Maj', btn: 0, mod: 'shift' }, { label: 'clic gauche + Espace', btn: 0, mod: 'space' }
- ];
- var modeI = 0, spaceDown = false;
- try { modeI = Math.max(0, Math.min(MODES.length - 1, parseInt(localStorage.getItem('jigex-zoom-panmode') || '0', 10) || 0)); } catch (e) {}
- var MASK = { 0: 1, 1: 4, 2: 2, 3: 8, 4: 16 };
- function isPanBtn(e) {
- var m = MODES[modeI];
- if (e.button !== m.btn) return false;
- if (m.mod === 'shift') return e.shiftKey;
- if (m.mod === 'space') return spaceDown;
- return true;
- }
- window.addEventListener('keydown', function (e) { if (e.code === 'Space') spaceDown = true; }, true);
- window.addEventListener('keyup', function (e) { if (e.code === 'Space') spaceDown = false; }, true);
- window.addEventListener('blur', function () { spaceDown = false; });
- window.addEventListener('keydown', function (e) {
- if ((e.key !== 'm' && e.key !== 'M') || e.ctrlKey || e.metaKey || e.altKey) return;
- var t = document.activeElement; if (t && /INPUT|TEXTAREA|SELECT/.test(t.tagName)) return;
- modeI = (modeI + 1) % MODES.length; panning = null;
- try { localStorage.setItem('jigex-zoom-panmode', String(modeI)); } catch (er) {}
- refreshBadge();
- }, true);
- // ---- Clic milieu : déplacer la vue (le jeu ne le voit pas) ----
- function isMid(e) { return e.button === 1 || (e.buttons & 4) === 4; }
- ['pointerdown', 'mousedown', 'pointerup', 'mouseup', 'auxclick'].forEach(function (t) {
- window.addEventListener(t, function (e) {
- if (!on || z <= 1) return;
- var down = t === 'pointerdown' || t === 'mousedown';
- if ((down && isPanBtn(e)) || (!down && panning) || (e.type === 'auxclick' && e.button === MODES[modeI].btn)) {
- e.preventDefault(); e.stopImmediatePropagation();
- if (down) panning = { x: e.clientX, y: e.clientY, tx: tx, ty: ty, mask: MASK[e.button] };
- if (t === 'pointerup' || t === 'mouseup') panning = null;
- }
- }, true);
- });
- window.addEventListener('contextmenu', function (e) { if (on && z > 1 && (MODES[modeI].btn === 2 || panning)) { e.preventDefault(); e.stopImmediatePropagation(); } }, true);
- function panMove(e) {
- if (!panning) return;
- if (!(e.buttons & panning.mask)) { panning = null; return; }
- tx = panning.tx + (e.clientX - panning.x); ty = panning.ty + (e.clientY - panning.y); apply();
- e.stopImmediatePropagation();
- }
- window.addEventListener('pointermove', function (e) {
- if (panning) panMove(e);
- }, true);
- window.addEventListener('mousemove', panMove, true);
- // ---- Les clics du jeu : on corrige les coordonnées pour qu'elles visent le bon endroit du canvas zoomé ----
- function down0(t) { return t === 'pointerdown' || t === 'mousedown'; }
- var REMAP = ['pointerdown', 'pointermove', 'pointerup', 'pointercancel', 'mousedown', 'mousemove', 'mouseup', 'click', 'dblclick', 'contextmenu'];
- REMAP.forEach(function (t) {
- window.addEventListener(t, function (e) {
- var c = getCanvas();
- if (!c || z <= 1.0001 || panning || (down0(t) && isPanBtn(e))) return;
- var down = t === 'pointerdown' || t === 'mousedown', up = t === 'pointerup' || t === 'mouseup' || t === 'pointercancel';
- if (down && e.target === c) { dragging = true; held = true; }
- if (t === 'pointerup' && held && e.__ox === undefined && e.target) {
- // le jeu reçoit un dernier mouvement exactement à l'endroit du lâcher, juste avant le relâchement
- try {
- var o = { clientX: e.clientX, clientY: e.clientY, buttons: 1, pointerId: e.pointerId || 1, pointerType: e.pointerType || 'mouse', isPrimary: true, bubbles: true, cancelable: true, view: window };
- c.dispatchEvent(new PointerEvent('pointermove', o));
- c.dispatchEvent(new MouseEvent('mousemove', o));
- } catch (err) {}
- }
- if (up) held = false;
- var apply1 = e.target === c || dragging;
- if (up) setTimeout(function () { dragging = false; }, 150);
- if (!apply1 || e.__ox !== undefined) return;
- lastX = e.clientX; lastY = e.clientY;
- var r = c.getBoundingClientRect();
- var nx = r.left + (e.clientX - r.left) / z, ny = r.top + (e.clientY - r.top) / z;
- e.__ox = e.clientX; e.__oy = e.clientY; // position réelle à l'écran, pour les autres scripts
- try {
- Object.defineProperty(e, 'clientX', { value: nx, configurable: true });
- Object.defineProperty(e, 'clientY', { value: ny, configurable: true });
- Object.defineProperty(e, 'x', { value: nx, configurable: true });
- Object.defineProperty(e, 'y', { value: ny, configurable: true });
- Object.defineProperty(e, 'pageX', { value: nx + (window.pageXOffset || 0), configurable: true });
- Object.defineProperty(e, 'pageY', { value: ny + (window.pageYOffset || 0), configurable: true });
- } catch (err) {}
- }, true);
- });
- window.addEventListener('keydown', function (e) {
- if ((e.key !== 'z' && e.key !== 'Z') || e.ctrlKey || e.metaKey || e.altKey) return;
- var t = document.activeElement;
- if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.tagName === 'SELECT')) return;
- setOn(!on);
- }, true);
- window.addEventListener('keydown', function (e) {
- if ((e.key !== 'a' && e.key !== 'A') || e.ctrlKey || e.metaKey || e.altKey) return;
- var t = document.activeElement;
- if (t && (t.tagName === 'INPUT' || t.tagName === 'TEXTAREA' || t.tagName === 'SELECT')) return;
- autoPan = !autoPan; held = false; try { localStorage.setItem('jigex-zoom-autopan', autoPan ? '1' : '0'); } catch (er) {}
- refreshBadge();
- }, true);
- try { autoPan = localStorage.getItem('jigex-zoom-autopan') === '1'; } catch (e) {}
- ['pointerup','mouseup','pointercancel','dragend','lostpointercapture','blur','contextmenu'].forEach(function (t) {
- window.addEventListener(t, function () { held = false; }, true);
- });
- document.addEventListener('visibilitychange', function () { held = false; });
- window.addEventListener('pointermove', function (e) {
- mX = e.__ox !== undefined ? e.__ox : e.clientX; mY = e.__oy !== undefined ? e.__oy : e.clientY;
- mOver = e.target === getCanvas();
- }, true);
- window.addEventListener('mouseleave', function () { mOver = false; }, true);
- document.addEventListener('mouseleave', function () { mOver = false; });
- window.addEventListener('keydown', function (e) {
- if ((e.key !== 'e' && e.key !== 'E') || e.ctrlKey || e.metaKey || e.altKey) return;
- var t = document.activeElement; if (t && /INPUT|TEXTAREA|SELECT/.test(t.tagName)) return;
- hoverPan = !hoverPan; try { localStorage.setItem('jigex-zoom-hover', hoverPan ? '1' : '0'); } catch (er) {} refreshBadge();
- }, true);
- try { hoverPan = localStorage.getItem('jigex-zoom-hover') !== '0'; } catch (e) {}
- // ---- Journal de diagnostic (touche L : copie le journal) ----
- var LOG = [], t0 = Date.now(), prevSig = '';
- function lg(m) { LOG.push(((Date.now() - t0) / 1000).toFixed(2) + ' ' + m); if (LOG.length > 400) LOG.shift(); }
- ['pointerdown', 'pointerup', 'pointercancel', 'mouseup', 'click', 'dblclick', 'resize', 'scroll', 'focusin', 'blur', 'keydown'].forEach(function (t) {
- window.addEventListener(t, function (e) { lg('évt ' + t + (e.target && e.target.id ? '#' + e.target.id : '') + (e.clientX !== undefined ? ' @' + Math.round(e.__ox !== undefined ? e.__ox : e.clientX) + ',' + Math.round(e.__oy !== undefined ? e.__oy : e.clientY) : '')); }, true);
- });
- function sample() {
- var c = getCanvas(); if (!c) return;
- var r = c.getBoundingClientRect(), p = c.parentElement;
- var sig = [Math.round(r.left), Math.round(r.top), Math.round(r.width), c.offsetWidth, c.width, c.style.transform, p ? p.scrollLeft + '/' + p.scrollTop : '', window.pageXOffset + '/' + window.pageYOffset, z.toFixed(2), Math.round(tx), Math.round(ty), c.style.cssText.length].join('|');
- if (sig !== prevSig) { lg('état rect=' + Math.round(r.left) + ',' + Math.round(r.top) + ' w=' + Math.round(r.width) + ' off=' + c.offsetWidth + ' px=' + c.width + ' z=' + z.toFixed(2) + ' tx,ty=' + Math.round(tx) + ',' + Math.round(ty) + ' scrollP=' + (p ? p.scrollLeft + '/' + p.scrollTop : '-') + ' scrollW=' + window.pageXOffset + '/' + window.pageYOffset + ' style=' + c.style.cssText); prevSig = sig; }
- }
- window.addEventListener('keydown', function (e) {
- if ((e.key !== 'l' && e.key !== 'L') || e.ctrlKey || e.metaKey || e.altKey) return;
- var t = document.activeElement; if (t && /INPUT|TEXTAREA|SELECT/.test(t.tagName)) return;
- e.preventDefault(); e.stopImmediatePropagation();
- var txt = LOG.join('\n');
- try { navigator.clipboard.writeText(txt); } catch (er) {}
- var d = document.createElement('textarea'); d.value = txt; d.style.cssText = 'position:fixed;left:10%;top:10%;width:80%;height:70%;z-index:2147483647;font:11px monospace;';
- d.addEventListener('keydown', function (ev) { ev.stopPropagation(); if (ev.key === 'Escape') d.remove(); });
- document.body.appendChild(d); d.focus(); d.select();
- }, true);
- // Redimensionnement : on ne remet à ×1 que si la taille du canvas a vraiment changé
- window.addEventListener('resize', function () {
- var c = getCanvas(); if (!c) return;
- if (baseW && Math.abs(c.offsetWidth - baseW) > 2) reset();
- });
- // Boucle : (1) remet la transformation si le site l'a effacée, (2) défilement auto du bord pendant le déplacement d'une pièce
- var EDGE = 70, SPEED = 22;
- (function loop() {
- var c = getCanvas();
- if (c) {
- baseW = c.offsetWidth; sample();
- if (on && z > 1.0001) { // le zoom agrandit la zone défilable : on empêche tout défilement parasite (focus, glisser...)
- for (var q = c.parentElement; q; q = q.parentElement) { if (q.scrollLeft) q.scrollLeft = 0; if (q.scrollTop) q.scrollTop = 0; }
- if (window.pageXOffset || window.pageYOffset) window.scrollTo(0, 0);
- }
- if (on && z > 1.0001) {
- if (hoverPan && !held && !panning && mOver) { // survol du bord de l'écran : la vue glisse dans cette direction
- var rh = c.getBoundingClientRect(), Lh = rh.left - tx, Th = rh.top - ty, wh = c.offsetWidth, hh = c.offsetHeight, EH = edgeSize, SH = edgeSpeed, hx = 0, hy = 0;
- if (mX < Lh + EH) hx = SH * Math.min(1, (Lh + EH - mX) / EH); else if (mX > Lh + wh - EH) hx = -SH * Math.min(1, (mX - (Lh + wh - EH)) / EH);
- if (mY < Th + EH) hy = SH * Math.min(1, (Th + EH - mY) / EH); else if (mY > Th + hh - EH) hy = -SH * Math.min(1, (mY - (Th + hh - EH)) / EH);
- if (hx || hy) { tx += hx; ty += hy; apply(); }
- }
- if (autoPan && held && !panning) {
- var r0 = c.getBoundingClientRect();
- var L = r0.left - tx, T = r0.top - ty, w = c.offsetWidth, h = c.offsetHeight;
- var sx = lastX, sy = lastY; // position réelle du curseur à l'écran
- var dx = 0, dy = 0;
- if (sx < L + EDGE) dx = SPEED * Math.min(1, (L + EDGE - sx) / EDGE);
- else if (sx > L + w - EDGE) dx = -SPEED * Math.min(1, (sx - (L + w - EDGE)) / EDGE);
- if (sy < T + EDGE) dy = SPEED * Math.min(1, (T + EDGE - sy) / EDGE);
- else if (sy > T + h - EDGE) dy = -SPEED * Math.min(1, (sy - (T + h - EDGE)) / EDGE);
- if (dx || dy) {
- var ox = tx, oy = ty;
- tx += dx; ty += dy; apply();
- if (tx !== ox || ty !== oy) {
- // le curseur n'a pas bougé mais la vue oui : on prévient le jeu pour que la pièce suive
- try {
- var ev = new PointerEvent('pointermove', { clientX: sx, clientY: sy, buttons: 1, button: -1, pointerId: 1, pointerType: 'mouse', isPrimary: true, bubbles: true, cancelable: true, view: window });
- c.dispatchEvent(ev);
- c.dispatchEvent(new MouseEvent('mousemove', { clientX: sx, clientY: sy, buttons: 1, bubbles: true, cancelable: true, view: window }));
- } catch (err) {}
- }
- }
- }
- }
- }
- requestAnimationFrame(loop);
- })();
- // ---- Interface : bouton dans la barre du site + panneau de réglages ----
- var btn = null, panel = null, ctl = {};
- function sv(k, v) { try { localStorage.setItem(k, String(v)); } catch (e) {} }
- function ld(k, d) { try { var v = localStorage.getItem(k); return v === null ? d : v; } catch (e) { return d; } }
- edgeSize = parseInt(ld('jigex-zoom-esz', '36'), 10) || 36; edgeSpeed = parseInt(ld('jigex-zoom-esp', '14'), 10) || 14;
- MAX = parseInt(ld('jigex-zoom-max', '6'), 10) || 6;
- function refreshBadge() {
- if (btn) {
- var tip = on ? 'Zoom molette ×' + z.toFixed(1) + ' — réglages' : 'Zoom molette désactivé — réglages';
- btn.setAttribute('data-tooltip', tip); btn.title = tip; btn.style.opacity = on ? '1' : '.5';
- var q = btn.querySelector('.jz-lvl'); if (q) q.textContent = on && z > 1 ? '×' + z.toFixed(1) : '';
- }
- if (ctl.on) {
- ctl.on.checked = on; ctl.ctrl.checked = ctrlOnly; ctl.mode.value = String(modeI); ctl.hover.checked = hoverPan; ctl.auto.checked = autoPan;
- ctl.esz.value = edgeSize; ctl.esp.value = edgeSpeed; ctl.max.value = MAX;
- ctl.eszv.textContent = edgeSize + ' px'; ctl.espv.textContent = edgeSpeed; ctl.maxv.textContent = '×' + MAX;
- ctl.lvl.textContent = 'Zoom actuel : ×' + z.toFixed(1);
- }
- }
- function mk(tag, css, txt) { var e = document.createElement(tag); if (css) e.style.cssText = css; if (txt) e.textContent = txt; return e; }
- function row(label) {
- var r = mk('label', 'display:flex;align-items:center;gap:8px;margin:7px 0;justify-content:space-between;cursor:pointer;');
- r.appendChild(mk('span', '', label)); return r;
- }
- function buildPanel() {
- panel = mk('div', 'position:fixed;z-index:2147483000;width:290px;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:4px;', 'Zoom molette'));
- var r = row('Activé (Z)'); ctl.on = mk('input'); ctl.on.type = 'checkbox'; r.appendChild(ctl.on); panel.appendChild(r);
- ctl.on.addEventListener('change', function () { setOn(ctl.on.checked); refreshBadge(); });
- r = row('Déplacer la vue avec (M)'); ctl.mode = mk('select', 'max-width:150px;');
- MODES.forEach(function (m, i) { var o = mk('option', '', m.label); o.value = i; ctl.mode.appendChild(o); });
- r.appendChild(ctl.mode); panel.appendChild(r);
- ctl.mode.addEventListener('change', function () { modeI = parseInt(ctl.mode.value, 10); panning = null; sv('jigex-zoom-panmode', modeI); refreshBadge(); });
- r = row('Zoom seulement avec Ctrl + molette'); ctl.ctrl = mk('input'); ctl.ctrl.type = 'checkbox'; r.appendChild(ctl.ctrl); panel.appendChild(r);
- r.title = 'Utile si la rotation des pièces est activée : la molette seule tourne alors la pièce tenue';
- ctl.ctrl.addEventListener('change', function () { ctrlOnly = ctl.ctrl.checked; sv('jigex-zoom-ctrl', ctrlOnly ? '1' : '0'); refreshBadge(); });
- r = row('Défiler en touchant les bords (E)'); ctl.hover = mk('input'); ctl.hover.type = 'checkbox'; r.appendChild(ctl.hover); panel.appendChild(r);
- ctl.hover.addEventListener('change', function () { hoverPan = ctl.hover.checked; sv('jigex-zoom-hover', hoverPan ? '1' : '0'); refreshBadge(); });
- r = row('… aussi en portant une pièce (A)'); ctl.auto = mk('input'); ctl.auto.type = 'checkbox'; r.appendChild(ctl.auto); panel.appendChild(r);
- ctl.auto.addEventListener('change', function () { autoPan = ctl.auto.checked; held = false; sv('jigex-zoom-autopan', autoPan ? '1' : '0'); refreshBadge(); });
- function slider(label, min, max, key, set, valKey) {
- var rr = mk('div', 'margin:7px 0;'); var top = mk('div', 'display:flex;justify-content:space-between;'); top.appendChild(mk('span', '', label));
- ctl[valKey] = mk('span', 'opacity:.8;'); top.appendChild(ctl[valKey]); rr.appendChild(top);
- var inp = mk('input', 'width:100%;'); inp.type = 'range'; inp.min = min; inp.max = max; inp.step = 1;
- inp.addEventListener('input', function () { set(parseInt(inp.value, 10)); sv(key, inp.value); refreshBadge(); });
- rr.appendChild(inp); panel.appendChild(rr); return inp;
- }
- ctl.esz = slider('Largeur de la zone des bords', 10, 120, 'jigex-zoom-esz', function (v) { edgeSize = v; }, 'eszv');
- ctl.esp = slider('Vitesse du défilement', 3, 40, 'jigex-zoom-esp', function (v) { edgeSpeed = v; }, 'espv');
- ctl.max = slider('Zoom maximum', 2, 12, 'jigex-zoom-max', function (v) { MAX = v; if (z > MAX) { z = MAX; apply(); } }, 'maxv');
- var foot = mk('div', 'display:flex;justify-content:space-between;align-items:center;margin-top:10px;');
- ctl.lvl = mk('span', 'opacity:.8;'); foot.appendChild(ctl.lvl);
- var rb = mk('button', 'cursor:pointer;padding:4px 10px;border-radius:6px;border:1px solid #666;background:#3a3d44;color:#eee;', 'Revenir à ×1');
- rb.addEventListener('click', function () { reset(); }); foot.appendChild(rb); panel.appendChild(foot);
- panel.appendChild(mk('div', 'margin-top:8px;font-size:11px;opacity:.65;', 'Molette : zoomer (pas pendant qu\'un bouton est enfoncé) · L : journal'));
- ['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 placePanel() {
- var br = btn.getBoundingClientRect();
- panel.style.top = Math.round(br.bottom + 6) + 'px';
- panel.style.left = Math.max(8, Math.min(window.innerWidth - 300, Math.round(br.right - 290))) + 'px';
- }
- function togglePanel(force) {
- if (!panel) buildPanel();
- var show = force === undefined ? panel.style.display === 'none' : force;
- if (show) { applyTheme(panel); placePanel(); refreshBadge(); }
- 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-zoomcfg-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-linecap:round">' +
- '<circle cx="10" cy="10" r="6"/><path d="M15 15l6 6M7.5 10h5M10 7.5v5"/></g></svg>' +
- '<span class="jz-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(); togglePanel(); });
- if (bar) bar.insertBefore(btn, clock);
- else { btn.style.cssText = 'position:fixed;left:8px;bottom:96px;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)) togglePanel(false); }, true);
- window.addEventListener('resize', function () { if (panel && panel.style.display !== 'none') placePanel(); });
- refreshBadge();
- }
- function start() {
- var tries = 0;
- (function wait() {
- if (document.getElementById('jigex-clock') || ++tries > 60) { if (!document.getElementById('jigex-zoomcfg-btn')) buildBtn(); }
- else setTimeout(wait, 500);
- })();
- }
- if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', start); else start();
- // Le site peut reconstruire sa barre : on remet le bouton si besoin
- setInterval(function () { var clock = document.getElementById('jigex-clock'); if (btn && clock && !btn.isConnected && clock.parentElement) clock.parentElement.insertBefore(btn, clock); }, 2000);
- })();
Advertisement
Add Comment
Please, Sign In to add comment