マウスホイールで「拡大率」を調節する 

「Lightbox」系のツールで、「拡大率」をマウスホイールで調節する操作を採り入れるのは初めてです。 マウスホイールがスクロール操作と拡大率調節の両方に使用されるので、上手く切り分ける事が必要です。

 

今回は、そのための簡単な関数を作っています。

 

「Uni Lightbox JS」 ver.0.5 181行

function ac_check(elem){
let opa=window.getComputedStyle(elem).getPropertyValue('opacity');
if(opa=='1' && disp_mode==2){
    return true; }}

 

関数の引数「elem」はチェック対象の要素で、「#mag_sw」という拡大率表示や起動仕様のボタンの表示枠です。 マウスポインターを Lightbox上部に載せると、この枠の「opacity」が「1」となり隠したボタン類を表示させますが、その「opacity」を調べてユーザーの操作状態を判定する関数です。

 

また「disp_mode」は、Lightbox表示は「1」、Lightbox内拡大の場合は「2」となるコントロールフラグです。 従って、上の関数は、ユーザーが「Lightbox内拡大」で、Lightbox上部をマウスでポイントした時にだけ「true」の判定をします。

 

この関数を使って、値が「true」の時のホイール操作を拡大率の調節操作として扱い、それ以外はスクロール操作として、ホイール操作を切り分けています。

 

 

 

操作の実際 

これまでの「+-」のボタンは、排除して簡素化しました。 その結果、拡大率の表示パネルだけになり、ホイール操作を使う事に気付き難いデザインになりました。

 

そこで、簡単なツールチップを表示する様にしました。 また「上下ボタン」の表示で可変である事を示しています。

 

 

また、表示するボタン類の組み合わせを変更しました。

 

◎〔通常の Lightbox表示〕

  ➔「Lightboxを表示する操作」「ヘルプボタン」

◎〔Lightbox内拡大〕

  ➔「拡大率の表示」「Lightboxを表示する操作」「ヘルプボタン」

 

従って、拡大率は「Lightbox内拡大」の状態でのみ調節・変更が可能です。

 

▪拡大率は素早く調節が出来る様に、従来の10%ずつのステップを 20%ずつのステップで調整する仕様に改めました。

 

 

通常の Lightbox表示 

 

Lightbox内拡大 

▪最初はデフォルトの「200%」の拡大率で表示されます。

 

 

 

● マウスポインターをLightbox上部に移動しホイール操作をすると、拡大率を調整する事が出来ます。 調整範囲は「100%~400%」です。

 

 

 

▪調整した拡大率は、ページのセッションが継続している間は維持されます。

 

 

 

操作マニュアル 

「Uni Lightbox JS」の全ての操作方法は以下のページに纏めています。

 

 

 

 

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

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

 

❶「Tampermonkey」を導入します

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

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

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

 

 

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

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

 

 

 

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

 

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

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

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

 

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

 

 

〔 Uni Lightbox JS 〕 ver. 0.5

 

// ==UserScript==
// @name         Uni Lightbox JS
// @namespace    http://tampermonkey.net/
// @version       0.5
// @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; // 拡大率
let view_ac; // クリック操作 0: Ctrl+右Click 1: 右Click

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

view_ac=sessionStorage.getItem('UL_ac')*1;
if(!view_ac){
    view_ac=0; // 🔴クリック動作の初期値
    sessionStorage.setItem('UL_ac', view_ac); }

let html_=document.documentElement;


box_env();

document.addEventListener('contextmenu', function(event){
    if(disp_mode==0){
        if(view_ac==0){
            if(event.ctrlKey){
                event.preventDefault();
                event.stopImmediatePropagation();
                let elem=document.elementFromPoint(event.clientX, event.clientY);
                if(elem){
                    set_img(elem);
                    set_link(elem); }}}
        if(view_ac==1){
            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 ud_SVG=
        '<svg height="20" width="20" viewBox="0 0 40 50">'+
        '<path style="fill: #000;" d="M20 6L13 21L28 21C25.9 15.9 23.5 '+
        '10.3 20 6M13 28L20 43C23.5 38.7 25.9 33.1 28 28L13 28z"></path>'+
        '</svg>';

    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>'+
        '<div id="mag_sw">'+
        '<p id="ws" class="bc" title="拡大率:マウスホイールで調節">Gz'+ ud_SVG +
        '<span id="wsv"></span></p>'+
        '<p id="ac" class="bc" title="Lightboxの起動操作"></p>'+
        '<a id="help_svg">'+ help_SVG +'</a>'+
        '</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; } '+
        '#mag_sw { position: fixed; top: 0; right: 20px; display: flex; padding: 20px; '+
        'width: auto; justify-content: flex-end; box-sizing: content-box; opacity: 0; } '+
        '#photo_sw:hover #mag_sw { opacity: 1; } '+
        '#help_svg { margin-left: 20px; cursor: pointer; } '+
        '.bc { height: 24px; padding: 0 5px; margin: 0 4px; '+
        'font: bold 22px/28px Meiryo; border: 2px solid #000; border-radius: 4px; '+
        'background: #fff; cursor: pointer; box-sizing: content-box; overflow: hidden; } '+
        '#ws svg { vertical-align: -3px; margin-right: 4px; } '+
        '#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 wsv=document.querySelector('#wsv');
    if(wsv){
        wsv.textContent=view_w; }
    zoom_set();

    ctrl_act();

    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 wsv=document.querySelector('#wsv');
    let mag_sw=document.querySelector('#mag_sw');


    function ac_check(element){
        let opa=window.getComputedStyle(element).getPropertyValue('opacity');
        if(opa=='1' && disp_mode==2){
            return true; }}


    if(wsv){
        document.onwheel=function(event){ // マスウホイールで設定
            if(event.deltaY<0 && ac_check(mag_sw) && view_w<381){
                event.preventDefault();
                event.stopImmediatePropagation();
                view_w=view_w*1 +20;
                let box_img=document.querySelector('#box_img');
                if(box_img){
                    box_img.style.width=view_w +'vw';
                    trim(view_w); }
                wsv.textContent=view_w;
                sessionStorage.setItem('UL_w', view_w); }

            else if(event.deltaY>0 && ac_check(mag_sw) && view_w>119){
                event.preventDefault();
                event.stopImmediatePropagation();
                view_w=view_w*1 -20;
                let box_img=document.querySelector('#box_img');
                if(box_img){
                    box_img.style.width=view_w +'vw';
                    trim(view_w); }
                wsv.textContent=view_w;
                sessionStorage.setItem('UL_w', view_w); }


            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 ctrl_act(){
    let ac=document.querySelector('#ac');
    if(ac){
        if(view_ac==0){
            ac.textContent='Ctrl+ R-Click'; }
        else{
            ac.textContent='R-Click'; }

        ac.onclick=function(event){
            event.stopImmediatePropagation();
            if(view_ac==0){
                view_ac=1;
                ac.textContent='R-Click'; }
            else{
                view_ac=0;
                ac.textContent='Ctrl+R-Click'; }
            sessionStorage.setItem('UL_ac', view_ac); } // Storage更新

    }} // ctrl_act()



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();
            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();
            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();
            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(){
    let ws=document.querySelector('#ws');
    if(ws){
        if(disp_mode==1){
            ws.style.display='none'; }
        else{
            ws.style.display='block'; }}}



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); }}


 

 

 

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

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

 

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