Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【JavaScript】スクロールメーター 自動スクロール機能つき

f:id:little_strange:20211230235525p:plain

 

 どうも!LSSです!!

 

2021年もまもなく終わる頃、またちょっと変わったものを作ってみました。

 

 

画面左下に表示されています

画面左下に、

f:id:little_strange:20211230230304p:plain

↑こんなものが表示されていると思います。

ページを開いた後、ちょっと画面をスクロールさせると画面左下定位置に出現します。

この黄緑が「現在このページをどこまでスクロールさせているか」を示しており、一番下までスクロールすると完全に黄緑の円になります。

 

また、自動スクロールスイッチを兼ねていて、クリックする毎に

「自動スクロール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;

横幅50ピクセル、高さ50ピクセルにしています。

 

次に、スクリプト
「スクロールメーター」表示部分と「自動スクロール」実現部分で分けています。

 

スクロールメーター表示部分のコード

/*スクロールメーター*/
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)さんからいただいたコメントに書かれていたもの…から自分の中でシンプルな方向に練り直したものが、今回のネタです。

「全体のどのあたりまで読んだかがわかっていいかな」の部分と「人差し指にタコができそう」なところだけを解決した感じで、だいぶ違うものになったような気も^^;

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^