動画サムネイルのライトボックス表示
「GYAO!」サイトの動画コンテンツ数は大変に多く、サイトの半分以上の機能は、このデータベースをユーザーが利用し易くする事に費やされています。 検索だけでなく、色々なリストアップを使って、ユーザーに合ったコンテンツを探せる様に工夫されているわけです。
ただ、リストページの動画サムネイルが小さく、画像上のタイトル等の文字が読めない事が気になっていました。 その動画ページを開かないとおうよその内容が判らない時は、とても不便に感じます。
そこで最初は、CSSでサムネイルをフォバーで拡大するコードを作りましたが、余り良い結果が得られず、これはスクリプトが必要と判断しました。「Gyao! Comfy」は便利で簡単なツールですが、これにアメブロ用の「Ameblo Lightbox JS」のコードを移植する事にしました。
制作過程
最低限の拡大機能があれば充分なので、あえて「Lightbox JS」の初期バージョンのコードを移植元に利用しました。
最も問題になったのは、「選択した画像の取得」の方法です。 コンテンツは大量で、ページを開いた後もスクロール操作で次々と追加され、メインのリストページでは最終的に数百のサムネイルが並びます。 この表示方式では、ページ上の画像を全取得してから画像を選択する「Lightbox JS」のコードは上手く働きません。
そこで、「マウスポイントした位置の要素を取得する」コードに変更しました。(ver. 0.4 204行)
上はコードの要点だけですが、「右Click」した位置の要素「elm」を取得して、その要素にセットされたリンク「link_elm」(a要素)を取得するコードです。
サムネイル画像は軽量化されている
現代のページデザインでは当然の事ですが、サムネイル画像はデータ量を減らすために軽量化されています。 これをCSSで拡大しても精細さに欠けますが、サムネイル画像は、多くの場合により精細な画像を変換して表示しているので、JavaScriptを使うと元画像の方を拡大表示できます。
動画サムネイル拡大の操作
「GYAO!」サイトのほぼ全てのページの動画サムネイルに対応していますが、リストに並んだサムネイルを「右Click」すると、暗転拡大表示になります。
暗転拡大画面の任意の場所を「左Click」すると、元のリスト表示の画面に戻れます。 その間、スクロール位置は元の位置のままで、動画を探す操作を妨げません。
画面の上部 15%にポインターに乗せると「🎦 Movie Page」ボタンを表示します。 これは、選択したサムネイルの動画ページへのリンクです。 ボタンを「左Click」する事で、元のサムネイルをクリックしたのと同様に、動画ページが開きます。
(ライトボックスを閉じて、元のサムネイルをクリックしても同じ事ですが)
「Gyao! Comfy」の他の操作について
「Gyao! Comfy」を常駐した状態で「動画ページ」を開くと、「動画再生開始」と同時に全画面表示になるなど、動画鑑賞上での操作が少し便利になります。 これは前ページの「操作マニュアル」に纏めているので参照ください。
「Gyao! Comfy」を利用するには
このツールは Chrome / Edge / Firefox版の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。
❶「Tampermonkey」を導入します
◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。
既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。
拡張機能の導入については、以下のページに簡単な説明があるので参照ください。
❷「Tampermonkey」にスクリプトを登録します
◎「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 軽量シンプルなツール「PreBox Button 」を使うと
コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」
の操作で、掲載コードのコピーが可能になります。
◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 Gyao! Comfy 〕 ver. 0.4
// ==UserScript== // @name Gyao! Comfy // @namespace http://tampermonkey.net/ // @version 0.4 // @description Gyao! 動画の「▶」のクリックで全画面表示 // @author You // @match https://gyao.yahoo.co.jp/* // @run-at document-start // @grant none // ==/UserScript== let retry=0; let interval=setInterval(wait_target, 1); function wait_target(){ retry++; if(retry>100){ // リトライ制限 100回 0.1secまで clearInterval(interval); } let target=document.body; // 監視 target if(target){ clearInterval(interval); style_in(); }} function style_in(){ let css1= '<style id="GC1" type="text/css">'+ '/* GYAO動画のフル画面表示 ver. 202203.08.01 */'+ ':root { --back: #91b4bf; --hove: #b9cfd6; }'+ 'html, body { background: var(--back); }'+ '.button-favorite { opacity: .6; }'+ '.button-favorite:hover { opacity: .8; }'+ '.button-favorite .button-favorite-text { color: #000; }'+ '.navigation-header-searchbar_searchSuggestResult__tU9rX, '+ '.search-suggest-result { background-color: #d2dee3 !important; }'+ '.arrow-button_arrowButton__aMtur:focus, '+ '.arrow-button_arrowButton__aMtur { box-shadow: inset 0 0 0 4px #fff; }'+ '.button-arrow:hover { box-shadow: 0 0 0 3px #fff; }'+ '.schedule-list-item { padding: 0 6px; }'+ '.schedule-list-item:hover { background: var(--hove); }'+ '.schedule-list-item-sub-text { color: #000 !important; }'+ '.schedule-list-container h3 { border-top: 1px solid #f0f0f0; }'+ '.schedule-list .schedule-list-row-item:not(:last-child) { padding-right: 0; }'+ '.schedule-list .schedule-list-row-item { border: none !important; }'+ '.schedule-list .schedule-list-row-item h3, .schedule-list .schedule-list-row-item ul { '+ 'border-left: 1px solid #f0f0f0; border-right: 1px solid #f0f0f0; }'+ '.program-list .program-list-more-link { margin-top: 30px; }'+ '.more-link .more-link-text { color: #000; outline: 1px solid #eee; }'+ '.more-link .more-link-text:active, .more-link .more-link-text:hover { '+ 'color: #fff; background-color: rgb(60 125 150 / 50%); }'+ '.breadcrumb .breadcrumb-list-item-link, '+ '.breadcrumb .breadcrumb-list-item:last-child .breadcrumb-list-item-link { color: #000; }'+ '.breadcrumb_item__KOyoB * { color: #000 !important; }'+ '.ad.ad-yads { display: none !important; }'+ '.overlay-ad_ad__grVga { display: none !important; }'+ '.timeline-ad_timelineAd__zM3OV { display: none !important; }'+ '.image-lazy { background-color: #90aeb7; }'+ 'html::-webkit-scrollbar { width: 16px; }'+ 'html::-webkit-scrollbar-thumb { '+ 'background: #000; border: 1px solid var(--back); border-right: none; }'+ 'html::-webkit-scrollbar-track { background: transparent; }'+ 'html { scrollbar-color: #000 transparent; }'+ 'html { overflow: overlay; overflow-x: hidden; }</style>'; if(!document.querySelector('#GC1')){ document.documentElement.insertAdjacentHTML('beforeend', css1); } let path=document.location.pathname; if(path.match(/^\/ranking|^\/arrivals|^\/titles|^\/search|^\/schedule/)){ let css2= '<style id="GC2" type="text/css">'+ '/* 共通設定 */'+ '.tab .tab-title > span { color: #000; }'+ '.tab .tab-title.is-active { background: none; }'+ '.tab .tab-title:active > span, .tab .tab-title:focus > span, '+ '.tab .tab-title:hover > span { color: #000; }'+ '.option-selector .option-selector-item > label { color: #000; }'+ '.option-selector .option-selector-item > input:hover + label { color: #000; }'+ '.program-list .program-list-item-title { color: #000; }'+ '.program-list .content-label { color: #000; }'+ '.program-list .program-list-item-sub-text { color: #000; }'+ '.item-list .item-list-more-link { margin-top: 30px; }'+ 'html::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, .2); }'+ 'html { scrollbar-color: rgba(0, 0, 0, .2) transparent; }</style>'; if(!document.querySelector('#GC2')){ document.documentElement.insertAdjacentHTML('beforeend', css2); }} if(path.match(/^\/p\/|^\/player\/|^\/episode\/|^\/title\//)){ let css3= '<style id="GC3" type="text/css">'+ '/* 個別の動画ページ 基本表示 */'+ '.video-player.is-pip .video-player-titles { background-color: #223e4c; }'+ '.video-player.is-pip .video-player-titles p { color: #ccc; }'+ '.video-player.is-pip .video-player-titles:after { content: "▲"; '+ 'position: fixed; right: 20px; bottom: 15px; font: normal 32px/44px Meiryo; '+ 'text-indent: 6px; color: #fff; display: block; height: 50px; width: 50px; '+ 'border: 3px solid #fff; border-radius: 50%; }'+ '.video-information .datetime { color: #000; }'+ '.video-descriptions .video-description-main, '+ '.program-descriptions .program-description-main { color: #000; }'+ '.video-descriptions .content-text, .program-descriptions .content-text { color: #000; }'+ '.container-clipper .container-clipper-content::after { '+ 'background: linear-gradient(to bottom, rgba(255, 255, 255, 0), #b9cfd6); height: 50px; }'+ '.video-list-more { background: var(--hove); }'+ '.item-tile .item-tile-item-details { background: none; }'+ '.item-tile-item-link:hover { background: var(--hove); }'+ '.button.type-primary-white { background: var(--hove); }'+ '.button.type-primary-white:hover { background: #c2edfb; }'+ '.button.type-secondary { background: var(--hove); }'+ '.button.type-secondary:hover { background: #c2edfb; }'+ '.review-list-item-header-post-info .datetime { color: #000; }'+ '.review-list .review-list-item-content-text { color: #000; }'+ '.review-list-item-content-interstitial { color: #000 !important; background: var(--hove); }'+ '.review-list-more { background: var(--hove); }'+ '.video-list .video-list-item { padding: 0 4px; }'+ '.video-list .video-list-item:hover { background-color: var(--hove); }'+ '.video-list .video-list-item.is-current { background-color: var(--hove); }'+ '.video-list .video-list-item-titles time { color: #000; }'+ '.video-list .video-list-item-sub-text { color: #000; }'+ '.section-upsell-item { padding: 0 4px; }'+ '.ad-banner.ad.section { display: none; }'+ '.to-app-banner.to-app-banner-footer, .footer-aside.footer-container { display: none; }'+ '.vjs-gyao .vjs-head-bar .vjs-head-title { font-size: 1em; }'+ '.vjs-gyao .vjs-control-bar .vjs-play-progress { background-color: #29b6f6; }'+ 'html::-webkit-scrollbar { width: 0px; }'+ 'html { scrollbar-width: none; }</style>'; if(!document.querySelector('#GC3')){ document.documentElement.insertAdjacentHTML('beforeend', css3); }} if(path.match(/^\/specials\/|^\/special\//)){ let css6= '<style id="GC6" type="text/css">'+ '/* 特設ページ */'+ 'body { font-family: "メイリオ", Meiryo, sans-serif !important; }'+ '#cnt p, #cnt h3 { color: #fff !important; }</style>'; if(!document.querySelector('#GC6')){ document.documentElement.insertAdjacentHTML('beforeend', css6); }} } // stylein() window.addEventListener("load", function(){ wider(); catch_click(); }); function wider(){ // 動画PLAYで自動的に全画面表示にする //動作確認用のメニューボタンのアウトライン表示 let lamp=document.querySelector('.header-menu-button'); if(lamp){ lamp.style.outlineOffset='-8px'; lamp.style.outline='auto red'; setTimeout(()=>{ lamp.style.outline='none'; }, 2000); } let play_button=document.querySelector('.vjs-big-play-button'); let full_cont=document.querySelector('.vjs-gyao .vjs-fullscreen-control'); if(play_button && full_cont){ play_button.onclick=function(event){ if(!event.ctrlKey && !event.shiftKey){ full_cont.click(); }} document.onkeydown=function(event){ if(event.ctrlKey || event.shiftKey){ play_button.style.filter='hue-rotate(-135deg)'; }} document.onkeyup=function(event){ play_button.style.filter=''; if((event.ctrlKey && event.keyCode==13) || (event.shiftKey && event.keyCode==13)){ full_cont.click(); }}} } // wider() function catch_click(){ // 動画のサムネイルの暗転拡大表示 let html_=document.querySelector('html'); box_env(); document.addEventListener('contextmenu', function(event){ if(!event.shiftKey && !event.ctrlKey){ event.preventDefault(); let elem=document.elementFromPoint(event.clientX, event.clientY); let link_elem=elem.closest('a'); if(link_elem){ set_link(link_elem); set_img(link_elem); close(); }}}); function box_env(){ let lightbox= '<div id="lightbox">'+ '<div id="photo_sw"><a id="photo_link">🎦 Movie Page</a></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; z-index: 3000; visibility: hidden; '+ 'background: black; width: 100vw; height: 100vh; text-align: center; } '+ '#photo_sw { position: absolute; width: 100%; height: 15%; } '+ '#photo_sw:hover #photo_link { opacity: 1; } '+ '#photo_link { position: absolute; top: 20px; left: 30px; opacity: 0; '+ 'font: bold 21px Meiryo; padding: 4px 12px 2px 10px; background: #fff; '+ 'color: #000; border: 2px solid #000; border-radius: 6px; cursor: pointer; } '+ '#box_img { width: 100vw; height: 100vh; padding: 2vh 2vw; object-fit: contain; } '+ '</style></div>'; if(!document.querySelector('#lightbox')){ document.body.insertAdjacentHTML('beforeend', lightbox); }} function set_link(target){ let photo_link=document.querySelector('#photo_link'); if(photo_link){ let url=target.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'); let img=target.querySelector('img'); if(lightbox && box_img && img){ let img_url=img.getAttribute('src').replace(/\?.*$/,""); if(img_url){ box_img.src=img_url; html_.style.overflow='hidden'; lightbox.style.visibility='visible'; lightbox.classList.remove('fout'); lightbox.classList.add('fin'); }}} function close(){ let html_=document.querySelector('html'); let lightbox=document.querySelector('#lightbox'); let box_img=lightbox.querySelector('#box_img'); if(lightbox){ lightbox.onclick=function(event){ event.preventDefault(); html_.style.overflow='inherit'; lightbox.classList.remove('fin'); lightbox.classList.add('fout'); setTimeout(()=>{ lightbox.style.visibility='hidden'; box_img.src=''; }, 200); }}} } // catch_click()