[CSS + Javascript] 文字や画像の無限スクロール機能

2024年5月7日

CSS Javascript デザイン

eyecatch とあるWebページをパク参考にさせてもらって、似たような表現をしようと思いました。 これは、仕事で、「このページをコピッ同じような表現でお願いします。」 と言われたので、致し方なく行う行為であり、決して著作権を侵害したいなどと微塵も考えていません。 それはどんな表現かと言うと、画像や文字の無限スクロール機能です。 実際に、同じような表現をしているWebサイトはたくさんあるんですが、ほとんどが力技でソースコードベタ書きで行っているため、 汎用性に欠けるので、以後に同じ表現をやろうとすると、今回作ったコレが何も活かせないことになります。 そんな事はイヤなので、効率的な無限スクロールコードを書いてみたので、ブログで紹介しておきます。

完成デモ

とりあえず、完成形を見てもらったほうがわかりやすいので、以下のデモを御覧ください。

AbcdefgHijklmn-

※切替時にガクッとなっているのは、過剰なCSSの適用しているからですね・・・ ずっと2つの画像が繰り返しスクロールしてループしているのが分かりますか? これを実現する場合、どんなプログラミングが必要なのか、ソースの次に解説を書いてみたので参照してみてください。

ソースコード

demo.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> <script src="main.js"></script> </head> <body> <div class="telop-scroll"> <p>AbcdefgHijklmn-</p> </div> </body> </html>

style.css

html,body{ overflow:hidden; } *, :after, :before { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box; } .telop-scroll p{ margin:0; font-size:8em; white-space:nowrap; } .telop-scroll{ display:flex; gap:0; } .telop-scroll > *{ animation-name: anim-telop-scroll; animation-duration: 10s; animation-timing-function: linear; animation-iteration-count: infinite; animation-fill-mode : forwards; } .telop-scroll[data-direction="reverse"] > *{ animation-direction:reverse; } @keyframes anim-telop-scroll{ from{ transform:translateX(0); } to{ transform:translateX(-100%); } }

main.js

/** * # Title * - 1要素を横無限スクロールさせるスニペット * * # Summary * - 文字を無限スクロール * - 写真などのを無限スクロール * * # Howto * - <div class="telop-scroll">~</div>で単一要素を囲う * - 自動で、内部要素(単一要素)が画面幅に合わせて複製される。 */ function Main(){ window.addEventListener("resize" , this.set_copy.bind(this)) this.set_copy() } // telop-scrollクラスを全て抽出 Main.prototype.set_copy = function(){ const elms = document.querySelectorAll(`.telop-scroll`) for(const elm of elms){ this.copy(elm) } } // telop-scrollの内部をスクロールサイズに合わせて複製 // - root要素の2倍以上になるように、内部要素(単一要素)をコピーする(既にコピーされていて多い場合は削除する) Main.prototype.copy = function(root){ const root_width = root.offsetWidth const elm = root.firstElementChild const elm_width = elm.offsetWidth const elm_count = root.children.length let need_count = Math.ceil((root_width * 2) / elm_width) need_count = need_count > 2 ? need_count : 2 console.log(root_width,elm_width,elm_count,need_count) if(elm_count < need_count){ for(let i=0; i<need_count - elm_count; i++){ const node = root.firstElementChild.cloneNode(true) root.appendChild(node) } } else if(elm_count > need_count){ for(let i=0; i< elm_count - need_count; i++){ root.removeChild(root.lastElementChild) } } } switch(document.readyState){ case "complete": case "interactive": new Main() break default: window.addEventListener("DOMContentLoaded", (()=> new Main())) }

解説

簡単なように見えて、結構ハマりました。 かつて、ガラケー時代に良く使われたmarqueeという、文字をスクロールさせる機能がHTMLにありました。 参考 : https://developer.mozilla.org/ja/docs/Web/HTML/Element/marquee でも、これはIE専用として作られたもので、今現在使うことは推奨されていないようです。 今回の基本的な仕様として、無限ループなので、marqueeのように、文字がスクロールするだけではなく、繰り返しのタイリングパターンみたいになる必要がありました。 そこで、繰り返したい要素を、必要な個数分コピーする必要があります。

スクロール要素が画面より大きい場合

画面サイズ(スクロールエリア)よりも大きい要素の場合は、後ろにひとつだけ同じ要素をコピーします。

スクロール要素が画面より小さい場合

要素が小さい場合は、必要なサイズに達する(サイズよりも1個多く)まで、要素をコピーする必要があります。 ※計算式としては、エリアサイズ / 要素サイズ(少数値繰り上げ) + 1で考えると簡単に計算できます。

cssとjavascriptの併用

できるだけCSSでやりたかったんですが、要素をコピーするという任意の処理がどうしてもJavascripを必要としました。 アニメーションの設定などは、CSSで行い、要素コピーのみjavascriptに徹すればシンプルにできるかと思いますね。

画面リサイズ対応

Javascriptがもう一箇所必要でした。 パソコンブラウザの場合に、ブラウザサイズを任意に変更した場合の、onresizeイベントで、要素のコピー数を変更しなければいけないという点です。 これも、イベント操作で、効率的に画面サイズに応じてコピー数(多い場合は削除数)などを割り出して追加と削除処理を行っています。

いろいろなデモ

今回のプログラムを使って、いろいろな応用の表現ができるので、サンプルを掲載しておきます。

画像のスクロール

スクロールスピードは、.telop-scrollの要素に、以下のように属性記述するとコントロールできます。 <div class="telop-scroll" style="--telop-time:20.0s;"> ... </div>

逆スクロール

文字が逆に流れますよ!!!

上記と同じ様に、.telop-scrollの要素に、以下のように属性記述するとスクロール方向を逆にできます。 <div class="telop-scroll" data-direction="reverse" > ... </div>

あとがき

LPの制作に役立つ、スクロールテクニックのスニペットいかがでしたか? できるだけ、コピペで使えるように作ってみましたが、上手く以下ない場合は、スクロール要素のサイズなどが原因になっている場合があるので、 シンプルに見直してみるといいでしょう。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ