マウスホイールで「拡大率」を調節する
「Lightbox」系のツールで、「拡大率」をマウスホイールで調節する操作を採り入れるのは初めてです。 マウスホイールがスクロール操作と拡大率調節の両方に使用されるので、上手く切り分ける事が必要です。
今回は、そのための簡単な関数を作っています。
「Uni Lightbox JS」 ver.0.5 181行
関数の引数「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」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。