「Lightbox」の中で拡張拡大 

「sessionStorage」(セッションストレージ)は、セッションが続いている間(ひとつのサイト参照しているタブを閉じない間)は、ページが切換っても登録した値を保持し続けるというものです。 ヤフーオークションのサイトでテストすると、思わぬ所で値がリセット(保持が無くなる)されたり、思わぬ所まで保持が継続したりといった感じですが、使わないよりはかなりマシです。 全サイト対応のツールで、やたらとブラウザのストレージ容量を減らすのは良くないので、このストレージを利用する事にしました。 拡大率の設定は、ブラウザを閉じるとリセットされます。

 

 

拡大率の設定 

記憶するのは、このツールの「ボックス内拡大」の拡大値で、ver.0.2 の固定値の 400%は過剰でした。 実際のテストから 200%をデフォルトとしましたが、何かのサイトで、ツールを使い始めた最初はこの初期値になります。

 

画像を最初に Lightbox表示した時は、ウインドウ内に内接する最大サイズで、この時の倍率はウインドウを拡げたサイズしだいです。 ボックス内で更に画像を右クリックして「ボックス内拡大」をした時の拡大率の初期値が 200%です。 これは、画像の横幅を、ウインドウ横幅の 2倍に拡大表示する指定です。

 

下は、この ver.0.3 から導入した拡大率の設定ボタンで、「110%」~「400%」の範囲で設定が可能です。 この拡大率をセッションストレージで維持します。

 

拡大率設定ボタン

 

この拡大率の設定は、やたらと表示されても邪魔なので、「ボックス内拡大」の状態でのみ、ボックスの右上隅に表示する様にしました。

 

 

 

ヘルプボタンの配置 

一方、最初の Lightbox表示の状態で、この場所に「ヘルプボタン」を配置しました。

 

キーボードと木目調の背景

 

「拡大率」「設定ボタン」「ヘルプボタン」などは、もちろん画像参照の邪魔にならない様に、マウスポインターをボックスの上部に移動しないと表示されません。

 

Lightboxヘルプボタンと拡大操作

 

 

 

シンプルな操作仕様 

「Uni Lightbox JS」は、コミック閲覧などは目的としていないので、操作機能はとてもシンプルになりました。 これまでのテクニックの継承で、無難なツールになったと思います。

 

 

 

「Uni Lightbox JS」を利用するには

このツールは Chrome・Edge・Firefox版の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。

 

❶「Tampermonkey」を導入します

◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。

既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。 

拡張機能の導入については、以下のページに簡単な説明があるので参照ください。

 

 

❷「Tampermonkey」にスクリプトを登録します

◎「Tampermonkey」の「」マークの「新規スクリプト」タブを開きます。

 

Tampermonkey新規スクリプト編集画面

 

 

◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。

 

〔コピー方法〕 軽量シンプルなツール「PreBox Button   」を使うと

  コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」

  の操作で、掲載コードのコピーが可能になります。

 

◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。

 

 

〔 Uni Lightbox JS 〕 ver. 0.3

 

// ==UserScript==
// @name         Uni Lightbox JS
// @namespace    http://tampermonkey.net/
// @version       0.3
// @description  ネット上の画像の高精細な暗転拡大表示
// @author        personwritep
// @match         https://*/*
// @match         http://*/*
// @exclude       https://ameblo.jp/*
// @exclude       https://abema.tv/*
// @exclude       https://*.ameba.jp/*
// @noframes
// @grant          none
// ==/UserScript==


let disp_mode=0; // 拡張ディスプレイモードの判別
let view_w; // 拡大率

view_w=sessionStorage.getItem('UL_w')*1;
if(!view_w){
    view_w=200; // 🔴🔴 拡大率の初期値
    sessionStorage.setItem('UL_w', view_w); }

let html_=document.documentElement;


box_env();

document.addEventListener('contextmenu', function(event){
    if(disp_mode==0){
        if(event.ctrlKey){
            event.preventDefault();
            event.stopImmediatePropagation();
            let elem=document.elementFromPoint(event.clientX, event.clientY);
            if(elem){
                set_img(elem);
                set_link(elem); }}}
    else{
        event.preventDefault();
        event.stopImmediatePropagation();
        ex_mag(event); }},true );


let lightbox=document.querySelector('#lightbox');
if(lightbox){
    lightbox.onclick=(event)=>{
        if(disp_mode!=0){
            close_box(event); }}}


let mag_sw=document.querySelector('#mag_sw');
if(mag_sw){
    mag_sw.onclick=(event)=>{
        event.preventDefault();
        event.stopImmediatePropagation(); }}



function box_env(){

    let help_SVG=
        '<svg height="28" width="28" viewBox="0 0 256 256">'+
        '<path style="fill: #000;" d="M114 12C96 15 79 '+
        '20 64 30C51 38 42 48 34 60C1 105 6 170 45 210C60 225 80 235 '+
        '100 241C114 245 129 245 144 243C160 241 175 235 188 227C201 '+
        '219 212 208 221 196C260 143 245 65 190 30C179 23 166 17 153 '+
        '15C140 12 127 11 114 12z"></path>'+
        '<path style="fill: #fff;" d="M115 26C100 29 85 34 72'+
        ' 42C60 49 51 57 43 69C16 109 19 167 54 202C66 213 81 223 97 '+
        '227C111 231 128 233 142 231C156 229 170 224 182 216C233 184 '+
        '246 110 208 63C194 47 175 36 155 30C143 26 128 25 115 26z"></path>'+
        '<path style="fill: #000;" d="M85 94C94 93 102 '+
        '88 110 85C121 82 143 85 137 102C134 111 125 116 119 122C110 '+
        '131 106 142 105 155L140 155C143 141 154 134 163 123C172 111 '+
        '176 95 171 81C162 57 133 55 111 58C104 59 94 60 88 65C82 71 '+
        '85 86 85 94M108 176L108 205C115 204 122 205 129 205C131 205 '+
        '136 205 138 204C140 202 139 198 139 196L139 176L108 176z"></path>'+
        '</svg>';


    let link_SVG=
        '<svg class="link_UL" viewBox="0 0 512 512">'+
        '<path d="M327 185c60 60 59 156.7.36 215-.11.12-.24.25-.36.37l-67 '+
        '67c-59 59-156 59-215 0-59-59-59-156 0-215l37-37c10-10 27-3 27 '+
        '10.6.6 18 4 36 10 53 2 5.8.6 12-4 17l-13 13c-28 28-29 74-1 102 28 '+
        '29 74 29 102.3.5l67-67c28-28 28-74 0-102-4-4-7-7-10-9a16 16 0 0 '+
        '1-7-13c-0-11 3-21 12-30l21-21c6-6 14-6 21-2a152 152 0 0 1 21 '+
        '17zM468 44c-59-59-156-59-215 0l-67 67c-.1.1-.3.3-.4.4-59 59-59 '+
        '154.8.4 215a152 152 0 0 0 21 17c6 4 15 4 21-2l21-21c8-8 12-19 '+
        '12-30a16 16 0 0 0-7-13c-3-2-7-5-10-9-28-28-28-74 0-101l67-67c28-28 '+
        '74-28 102.3.5 28 28 27 74-1 102l-13 13c-4 4-6 11-4 17 6 17 9 35 10 '+
        '52.7.5 14 17 20 27 11l37-37c59-59 59-155.7.0-215z"></path></svg>';

    let lightbox=
        '<div id="lightbox">'+
        '<div id="photo_sw">'+
        '<a id="photo_link">'+ link_SVG +' Linked Page</a>'+
        '<a id="help_svg">'+ help_SVG +'</a>'+
        '<div id="mag_sw">'+
        '<p id="ws" class="bc"></p>'+
        '<p id="wp" class="bc">+</p>'+
        '<p id="wm" class="bc">-</p>'+
        '</div></div>'+
        '<img id="box_img">'+
        '<style>'+
        '@keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1}} '+
        '.fin { animation: fadeIn .5s ease 0s 1 normal; animation-fill-mode: both; } '+
        '@keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0}} '+
        '.fout { animation: fadeOut .2s ease 0s 1 normal; animation-fill-mode: both; } '+
        '#lightbox { position: fixed; top: 0; left: 0; visibility: hidden; z-index: 3000000000; '+
        'display: grid; place-items: center; overflow: auto; user-select: none; '+
        'background: black; width: 100vw; height: 100vh; text-align: center; } '+
        '#photo_sw { position: fixed; top: 0; width: 100%; height: 15%; } '+
        '#photo_sw:hover #photo_link { opacity: 1; } '+
        '#photo_link { font: bold 21px Meiryo; position: absolute; top: 16px; left: 30px; '+
        'padding: 4px 12px 1px 10px; color: #000; background: #fff; cursor: pointer; '+
        'border: 2px solid #000; border-radius: 6px; text-decoration: none; opacity: 0; } '+
        '#photo_link:not([href]) { visibility: hidden; } '+
        '.link_UL{ height: 22px; vertical-align: -3px; fill: red; } '+
        '#help_svg { position: fixed; top: 20px; right: 39px; opacity: 0; } '+
        '#photo_sw:hover #help_svg { opacity: 1; cursor: pointer; } '+
        '#mag_sw { position: fixed; top: 0; right: 20px; display: flex; padding: 20px; '+
        'width: 170px; justify-content: space-between; box-sizing: content-box; } '+
        '#photo_sw:hover .bc { opacity: 1; } '+
        '.bc { height: 24px; overflow: hidden; '+
        'font: bold 22px/26px Meiryo; border: 2px solid #000; border-radius: 4px; '+
        'background: #fff; cursor: pointer; opacity: 0; margin: 0; box-sizing: content-box; } '+
        '#ws { line-height: 28px; padding: 0 5px; pointer-events: none; } '+
        '#box_img { width: 98vw; height: 98vh; padding: 1vh 1vw; object-fit: contain; '+
        'box-sizing: content-box; max-width: unset; max-height: unset; } '+
        'img { pointer-events: auto !important; } '+
        '</style></div>';

    if(!document.querySelector('#lightbox')){
        document.body.insertAdjacentHTML('beforeend', lightbox); }


    let ws=document.querySelector('#ws');
    if(ws){
        ws.textContent='Gz '+ view_w; }
    zoom_set();


    let help_svg=document.querySelector('#help_svg');
    if(help_svg){
        help_svg.onclick=(event)=>{
            event.stopImmediatePropagation();
            let help_url='https://ameblo.jp/personwritep/entry-12798649205.html';
            window.open( help_url, null, '_blank'); }}

} // box_env()



function zoom_set(){
    let ws=document.querySelector('#ws');
    let wp=document.querySelector('#wp');
    let wm=document.querySelector('#wm');

    if(ws && wp && wm){
        wp.onclick=function(event){
            event.stopImmediatePropagation();
            if(view_w<391){
                view_w=view_w*1 +10;
                let box_img=document.querySelector('#box_img');
                if(box_img){
                    box_img.style.width=view_w +'vw';
                    trim(view_w); }
                ws.textContent='Gz '+ view_w;
                sessionStorage.setItem('UL_w', view_w); }} // Storage更新


        wm.onclick=function(event){
            event.stopImmediatePropagation();
            if(view_w>119){
                view_w=view_w*1 -10;
                let box_img=document.querySelector('#box_img');
                if(box_img){
                    box_img.style.width=view_w +'vw';
                    trim(view_w); }
                ws.textContent='Gz '+ view_w;
                sessionStorage.setItem('UL_w', view_w); }} // Storage更新


        function trim(view_z){
            let lightbox=document.querySelector('#lightbox');
            let box_img=document.querySelector('#box_img');
            let i_width=box_img.naturalWidth;
            let i_height=box_img.naturalHeight;
            let w_width= window.innerWidth;
            let w_height= window.innerHeight;

            let view_width=w_width*view_z/100;
            lightbox.scrollTo((view_width - w_width)/2,
                              ((view_width*i_height)/i_width - w_height)/2); }

    }} // zoom_set()



function set_link(target){
    let photo_link=document.querySelector('#photo_link');
    if(photo_link){
        let link_a=target.closest('a');
        if(link_a){
            let url=link_a.getAttribute('href');
            if(url){
                photo_link.setAttribute('href', url); }}

        photo_link.onclick=function(event){
            event.stopImmediatePropagation(); }}}



function set_img(target){
    let lightbox=document.querySelector('#lightbox');
    let box_img=lightbox.querySelector('#box_img');

    if(lightbox && box_img && target){
        let img_url=target.getAttribute('src');
        if(img_url){
            disp_mode=1; // 拡張ディスプレイモードに入る
            disp_spm(0);
            box_img.src=img_url;
            html_.style.overflow='hidden';
            lightbox.style.visibility='visible';
            lightbox.classList.remove('fout');
            lightbox.classList.add('fin'); }}}



function ex_mag(event){
    let lightbox=document.querySelector('#lightbox');
    let box_img=lightbox.querySelector('#box_img');

    if(lightbox){
        if(disp_mode==1){
            disp_mode=2; // 拡張拡大
            disp_spm(1);
            lightbox.style.overflow='auto';
            box_img.style.height='auto';
            box_img.style.padding='0';
            box_img.style.width=view_w +'vw';
            mag_point(event); }
        else{
            disp_mode=1; // 通常拡大
            disp_spm(0);
            lightbox.style.overflow='hidden';
            box_img.style.height='98vh';
            box_img.style.width='98vw';
            box_img.style.padding='1vh 1vw'; }}

    function mag_point(event){
        let actal_x; // Actual Pixels表示スクロールx値
        let actal_y; // Actual Pixels表示スクロールy値
        let nwidth=box_img.naturalWidth;
        let nhight=box_img.naturalHeight;
        let ratio=nwidth/nhight
        let top=event.offsetY;
        let left=event.offsetX;
        let ww=lightbox.clientWidth;
        let wh=lightbox.clientHeight;

        if(ww<wh*ratio){
            actal_x=(left*view_w/100) - ww/2;
            actal_y=(2*top - wh + ww/ratio)*view_w/200 - wh/2; }
        else{
            let zk=((2*left - ww)/wh/ratio + 1)/2;
            actal_x=(zk*view_w -50)*ww/100;
            actal_y=(top*ww*view_w)/(wh*ratio*100) - wh/2; }

        lightbox.scrollTo(actal_x, actal_y); }
} // ex_mag()



function disp_spm(n){
    let mag_sw=document.querySelector('#mag_sw');
    if(mag_sw){
        if(n==0){
            mag_sw.style.visibility='hidden'; }
        else{
            mag_sw.style.visibility='visible'; }}
    let help_svg=document.querySelector('#help_svg');
    if(help_svg){
        if(n==0){
            help_svg.style.visibility='visible'; }
        else{
            help_svg.style.visibility='hidden'; }}}



function close_box(event){
    let lightbox=document.querySelector('#lightbox');
    let box_img=lightbox.querySelector('#box_img');
    if(lightbox && box_img){
        event.preventDefault();
        event.stopImmediatePropagation();
        disp_mode=0; // 拡張ディスプレイモード リセット
        html_.style.overflow='inherit';
        lightbox.classList.remove('fin');
        lightbox.classList.add('fout');
        lightbox.style.overflow='hidden'; // overflowのリセット
        box_img.style.height='98vh';
        box_img.style.width='98vw';
        box_img.style.padding='1vh 1vw';
        setTimeout(()=>{
            lightbox.style.visibility='hidden';
            box_img.src='';
        }, 200); }}

 

〔追記〕2023. 04.20

Firefox で動作に問題があり、コードを修正しました。「MutationObserver」が過剰に働く事が原因と思われ、上記コードは「MutationObserver」を取り除きました。 現在のテストでは「MutationObserver」無しで発火不良などの問題はない様です。

 

 

 

「Uni Lightbox JS」最新版について 

旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。

 

●「Uni Lightbox JS」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。