どうも!LSSです!!
2021年もまもなく終わる頃、またちょっと変わったものを作ってみました。
画面左下に表示されています
画面左下に、
↑こんなものが表示されていると思います。
ページを開いた後、ちょっと画面をスクロールさせると画面左下定位置に出現します。
この黄緑が「現在このページをどこまでスクロールさせているか」を示しており、一番下までスクロールすると完全に黄緑の円になります。
また、自動スクロールスイッチを兼ねていて、クリックする毎に
「自動スクロールOFF」→「低速自動スクロール」→「高速自動スクロール」
が切り替わります。
コード
<style>
#scrlm{
position:fixed;
bottom:50px;
left:10px;
border-radius:50%;
width:50px;
height:50px;
}
</style>
<div id="scrlm"></div>
<p>
<script>
/*スクロールメーター*/
document.addEventListener('scroll',()=>{
grph=Math.floor(360*window.pageYOffset/(document.body.scrollHeight-window.innerHeight));
scrlm.style.backgroundImage='conic-gradient(#88ff88 '+grph+'deg,#000000 '+grph+'deg)';
},false);
/*自動スクロール*/
scrlauto=0;
scrlm.addEventListener('click',()=>{
scrlauto++;
scrlauto%=3;
if(scrlauto>0){scrltm=setInterval(()=>{window.scrollBy(0,3*scrlauto)},100);}
else{{clearInterval(scrltm);}};
},false);
</script>
</p>
一部解説
まず冒頭のCSSから。
これはメーターの外観を設定している部分となります。
コード
<style>
#scrlm{
position:fixed;
bottom:50px;
left:10px;
border-radius:50%;
width:50px;
height:50px;
}
</style>
position:fixed;
画面スクロールに追従せず、常に一定位置に表示させるポジション指定です。
bottom:50px;
left:10px;
bottomは「画面下から」、leftは「画面左から」の配置距離をそれぞれ指定しています。
「上から」にするならtop、「右から」にするならrightで指定できます。
border-radius:50%;
要素を円形にする常套句です。「50%」の数値を小さくすると角丸四角になり、「0%」で完全な四角形になります。
width:50px;
height:50px;
次に、スクリプト。
「スクロールメーター」表示部分と「自動スクロール」実現部分で分けています。
スクロールメーター表示部分のコード
/*スクロールメーター*/
document.addEventListener('scroll',()=>{
grph=Math.floor(360*window.pageYOffset/(document.body.scrollHeight-window.innerHeight));
scrlm.style.backgroundImage='conic-gradient(#88ff88 '+grph+'deg,#000000 '+grph+'deg)';
},false);
赤文字部分がイベントリスナー設定、document(Webページ)に対してscrollイベントの監視を設定し、スクロールが発生した時(するたび)にその中の
grph=Math.floor(360*window.pageYOffset/(document.body.scrollHeight-window.innerHeight));
scrlm.style.backgroundImage='conic-gradient(#88ff88 '+grph+'deg,#000000 '+grph+'deg)';
を実行する、としています。
「grph=…」の行は「現在のスクロール量/一番下までスクロールした時のスクロール量」の比率に360(一周の角度)を掛けたものを算出しています。
window.pageYOffset
現在のスクロール量。
document.body.scrollHeight
ページ全体の高さ。
window.innerHeight
画面表示部の高さ。
ページ全体の高さである「document.body.scrollHeight」は、一番下までスクロールした時の画面底までのサイズとなりますので、そこから画面の高さである「window.innerHeight」を引いたものが「一番下までスクロールした時のスクロール量」となります。
例えばこれがちょうど半分スクロールした時点だと、
grph=Math.floor(360*0.5));
という計算になり(Math.floorは整数化する関数)、grphの値は「180」となります。
次の行は、算出した変数grphの値を元に、スクロールメーターの背景にconic-gradientで円グラフを描いています。
先ほどの180の例でいうと、
#scrlm{
background-image:conic-gradient(#88ff88 180deg,#000000 180deg);
}
とCSSで指定するのと同じ状態になります。
赤い180の部分がスクロールのたびに計算・再設定される事で、スクロールメーターとして表示される事になります。
自動スクロール実現部分のコード
/*自動スクロール*/
scrlauto=0;
scrlm.addEventListener('click',()=>{
scrlauto++;
scrlauto%=3;
if(scrlauto>0){scrltm=setInterval(()=>{window.scrollBy(0,3*scrlauto)},100);}
else{{clearInterval(scrltm);}};
},false);
scrlauto=0;
自動スクロール量の初期値を「0」にしています。
スクロールメーターをクリックした時の処理内容で、まず、
scrlauto++;
scrlauto%=3;
変数scrlautoの値を「+1」した上で、「3で割った余り」を代入しています。
こうする事で、変数scrlautoの値はクリックされるごとに「0→1→2→0→1→2→0→…」のように「0か1か2」の3つの状態を繰り返すことになります。
window.scrollBy(0,3*scrlauto)
「window.scrollBy(横スクロール増加量,縦スクロール増加量)」という書式で、現在のスクロール位置から増加分だけスクロールさせます。
今回の場合、横スクロールは考慮しないので0、縦スクロール量は「3*変数scrlautoの値」で、結局0か3か6という事になります。
それが
setInterval(()=>{window.scrollBy(0,3*scrlauto)},100);
100ミリ秒(=0.1秒)ごとに実行される事で、自動スクロールが実現しています^^
あとがき
昨日の記事、
【JavaScript】画面スクロールにあわせてCSS指定内容の変化 - Little Strange Software
に、カメさん(id:tn198403s)さんからいただいたコメントに書かれていたもの…から自分の中でシンプルな方向に練り直したものが、今回のネタです。
「全体のどのあたりまで読んだかがわかっていいかな」の部分と「人差し指にタコができそう」なところだけを解決した感じで、だいぶ違うものになったような気も^^;
ってなとこで、今回はこのへんで!
次回もまた、よろしくお願いします^^