「JavaScriptでスクロールに連動した足跡をつける」という記事に一応の完成版がありますが、そこに至るまでの試作コードをメモとして残しているページです。
なお、cssは完成版と同じなので省いています。
試作コード1(jsのみ)
以下のコードで動くと思いますが、問題もあるコードです。
//足跡設置
//上下のスクロールを判別するための基準の初期化
var nowPosition;
//足跡削除用にIDへ連番を付けるため
var count = 1;
//上向き用の連番で、偶数奇数で左右を判別
var countA = 1;
//下向き用の連番で、偶数奇数で左右を判
var countU = 1;
//スクロールしたら実行
window.addEventListener( "scroll", function() {
//現在のスクロール量を計測
var y = window.pageYOffset;
//基準値と現在値の差
diffPosition = y - nowPosition;
//現在の位置を更新
nowPosition = y;
//上向き用の連番で、偶数奇数で左右を判別設定
if(countA % 2 == 0){
idNameA = '-even';
} else {
idNameA = '-odd';
}
//下向き用の連番で、偶数奇数で左右を判別設定
if(countU % 2 == 0){
idNameU = '-even';
} else {
idNameU = '-odd';
}
//足跡を左右に散らす
var rand = Math.floor( Math.random() * 16 );
//表示用の間隔を設定
var interval = 20;
if( (diffPosition >= 0) && (y % interval == 0)){
//下向き向き、かつ、intervalの値で割り切れるスクロール量の時に実行
var foot = document.createElement('div');
foot.className = 'walk-under' + idNameU;
foot.id = 'foot' + count;
foot.style.top = 300 + y + 'px';
foot.style.marginRight = rand + 'px';
var objBody = document.getElementsByTagName("body")[0];
objBody.appendChild(foot);
countU++;
count++;
} else if ( y % interval == 0) {
//上向き、かつ、intervalの値で割り切れるスクロール量の時に実行
var foot = document.createElement('div');
foot.className = 'walk-above' + idNameA;
foot.id = 'foot' + count;
foot.style.top = 300 + y + 'px';
foot.style.marginRight = rand + 'px';
var objBody = document.getElementsByTagName("body")[0];
objBody.appendChild(foot);
countA++;
count++;
}
});
//足跡削除
var deleatId = 1;
function footsDeleat(){
var objBody = document.getElementsByTagName("body")[0];
//足跡追加の連番(countの数値と連動する形)
var e = document.getElementById("foot"+deleatId);
if (typeof(e) !== "undefined"){
objBody.removeChild(e);
deleatId++;
}
}
setInterval("footsDeleat()",3000);
問題点は、スクロールで発生する処理が多すぎるせいか、足跡の適切な表示ができていない点です。
状態としては「足跡が途切れて連続性がなくなりやすい」という見映えになります。
また、足跡を削除する部分も、表示タイミングと削除タイミングが無関係であり、突然足跡が消えるように見えてしまうことがありました。
試作コード2(js+Lodash)
jQueryを使わないのにLodashを使うのもどうかと思いましたが、スクロールによる処理の間引きが可能なthrottleを使いたいという理由があったので試した次第です。
コードは以下の通りですが、LodashのFull buildの方を読み込んでおく必要があります。
また、Lodashの利用に伴い、IE10以下は切り捨ての状態です。
//上下のスクロールを判別するための基準の初期化
var nowPosition;
//足跡削除用にIDへ連番を付けるため
var count = 1;
//上向き用の連番で、偶数奇数で左右を判別
var countA = 1;
//下向き用の連番で、偶数奇数で左右を判別
var countU = 1;
//足跡削除用の連番
var deleatId = 1;
//スクロールしたら実行するコールバックで足跡設置
var callback = function () {
//現在のスクロール量を計測
var y = window.pageYOffset;
//基準値と現在値の差
diffPosition = y - nowPosition;
//現在の位置を更新
nowPosition = y;
//上向き用の連番で、偶数奇数で左右を判別設定
if(countA % 2 == 0){
idNameA = '-even';
} else {
idNameA = '-odd';
}
//下向き用の連番で、偶数奇数で左右を判別設定
if(countU % 2 == 0){
idNameU = '-even';
} else {
idNameU = '-odd';
}
//足跡を左右に散らす指定
var rand = Math.floor( Math.random() * 16 );
if( (diffPosition >= 0)){
//下向きスクロールの時に実行
var foot = document.createElement('div');
foot.className = 'walk-under' + idNameU;
foot.id = 'foot' + count;
foot.style.top = 300 + y + 'px';
foot.style.marginRight = rand + 'px';
var objBody = document.getElementsByTagName("body")[0];
objBody.appendChild(foot);
countU++;
} else {
//上向きスクロールの時に実行
var foot = document.createElement('div');
foot.className = 'walk-above' + idNameA;
foot.id = 'foot' + count;
foot.style.top = 300 + y + 'px';
foot.style.marginRight = rand + 'px';
var objBody = document.getElementsByTagName("body")[0];
objBody.appendChild(foot);
countA++;
}
//処理開始時刻を削除用の関数を呼び出し
footsDeleatTimer();
count++;
};
//スクロールの間引き処理。設定数(今は250)ごとに関数を実行する目的
window.addEventListener('scroll', throttle(callback, 250));
function throttle(fn, wait) {
var time = Date.now();
return function() {
if ((time + wait - Date.now()) < 0) {
fn();
time = Date.now();
}
}
}
//足跡削除する時間を指定
var footsDeleatTimer = function(){
setTimeout("footsDeleat()",3000);
};
//削除用関数
function footsDeleat(){
var objBody = document.getElementsByTagName("body")[0];
//足跡追加の連番。実行回数と連動して追加された足跡ごとに削除を行う
var elements = document.getElementById("foot"+deleatId);
if (elements !== null){
objBody.removeChild(elements);
deleatId++;
}
}
試作コード1からは、足跡の削除部分なども少しブラッシュアップを試みています。
参考サイト
以下のサイトなどを参考にさせていただきました(完成版の記事と内容は同じです)。
- ライブラリを使わない素のJavaScriptでDOM操作
- javascriptでタグのidを文字列と変数で構成する方法を教えてください。
- javascriptでスクロールの上下を検知
- JavaScriptで要素の位置座標を取得する方法
- JavaScriptでランダムの数(乱数)を作る方法
- カッコいいけど遅すぎる! JSのスクロールイベントを改善するベストな方法
- JavaScriptプログラミング講座【ウェブパフォーマンスについて】
- JS:setInterval()やsetTimeout()で指定する関数に引数を渡す
- Quick Tip: How to Throttle Scroll Events
結び
勉強になった反面、実現したい形があってもそれがうまく形にできないもどかしさも強く。
求める動作をどう実現するのか?という根本的な部分をまず組み上げないことには、うまく作れないのだと実感します。
1人がこの記事を評価
役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。
連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。