少し前では<marquee>タグで流れるテキストを実装できていたのですが,このタグは廃止されてしまいました.まだ動作するブラウザもあるかもしれませんが,いつ動かなくなるか分からないので使わないようにしましょう.今回はjQueryで流れるテキストを実装してみましょう.サイトのアクセントにとても有効なデザインなので,是非使ってみてください!
動作イメージは以下の図になります.親ボックスのfix-boxとその子ボックスflowing-boxで構成されます.簡単に言えば,子ボックスのleftプロパティの操作でアニメーションします.この図には書いていませんが,親ボックスにカーソルを乗せると,アニメーションがストップし,離すと再開します.
それでは,コードの説明をしていきます.ファイルの構成は以下の通りです.
HTML
<div id="flowing-text">
<h2>Flowing Text</h2>
<div class="fix-box">
<div class="flowing-box">
<p>これは流れるテキストです.初期状態は何も表示されません.すべてのテキストが終わると,再び先頭から流れてきます.</p>
</div>
</div>
</div>
親ボックスはfix-box,子ボックスはflowing-boxのクラスを付けています.親ボックスには,マウスオーバー判定のためのstopクラスがjQueryで付加されます.
SCSS(CSS)
#flowing-text {
margin: 100px;
h2 {
text-align: center;
margin-bottom: 20px;
}
.fix-box {
position: relative;
height: 35px;
box-shadow:0px 0px 8px 3px #ccc inset;
overflow: hidden;
.flowing-box {
position: absolute;
top: 50%;
transform: translateY(-50%);
p {
white-space: pre;
}
}
}
}
.fix-boxには{position: relative},.flowing-boxには{position: absolute}を指定します.また.fix-boxの外にある要素は非表示にして置きたいので,{overflow: hidden}を指定しましょう.
pタグ要素には改行をキャンセルする{white-space: pre}を指定しています.
jQuery(main.js)
$(function(){
//変数
var $flowText = $('#flowing-text'),
$fixBox = $flowText.find('.fix-box'),
$flowBox = $fixBox.find('.flowing-box'),
flowbox_width = $flowBox.width(), //流れてくるBoxの横幅
flowTime=10000, //全てのテキストが流れ終わるまでの時間.初期値10000ms
easing = 'linear', //アニメーションの軌跡
right_start, //流れるBoxの右側の初期位置を入れる変数
right_running, //動作中の右側の位置を入れる変数
timer;
//流れてくるBoxの初期値
$flowBox.css({left:'100%'});
//流れるBoxの右側の初期位置
right_start = $flowBox.offset().left+flowbox_width;
//ボックスを流す関数
function flowingStart (){
if(!$flowBox.hasClass('stop')){ //stopクラスがない場合の処理
$flowBox.animate(
{left: -flowbox_width},
flowTime,
easing,
function(){ //アニメーション後に行うコールバック関数
$flowBox.css({left: '100%'});
}
);
flowTime=10000; //次のアニメーションの時間を設定
} else { //stopクラスがある場合の処理
$flowBox.stop(true, false);
//流れるBoxの右側の初期値と現在の右側の位置からアニメーション時間を計算
//時間を固定するとアニメーションをストップさせるたびに流れる速度が遅くなる
right_running=$flowBox.offset().left+flowbox_width;
flowTime=Math.floor(((right_running)/right_start)*10000);
}
}
//繰り返し,flowingStart()を実行するための関数
function flowingMonitor(){
timer = setInterval(function(){
flowingStart();
},300);
}
//マウスが乗っていればstopクラスを追加
$fixBox.on('mouseover',function(){
$flowBox.addClass('stop');
})
.on('mouseout',function(){
$flowBox.removeClass('stop');
})
flowingMonitor();
});
animate()メソッドの第4引数にはコールバック関数を指定できます.これはアニメーション完了後に実行される関数です.この関数には子ボックスを初期位置に戻す処理を記述しています.
アニメーションをするflowingStart関数を実行するだけでは一度テキストが流れきって初期値に戻ると,そこで処理が止まってしまします.そこでflowingStart関数を一定時間ごとに実行する,flowingMonitor関数を定義します.
またマウスが乗ったときはstopクラスを親ボックスに追加し,そのクラスの有無で,アニメーションのスタートとストップを分けています.このmouseoverとmouseleaveは,スマホの画面などではうまく機能しないので,touchstartとtouchendに書き換えるといいでしょう!
マウスが乗った時の処理として,アニメーションの時間を再度設定するようにしましょう.初期値は10000msですが,アニメーションを止めて再開すると途中からさらに10000msかけてゴールに向かいます.これはマウスを乗せるたびに流れる速度がどんどんゆっくりになってしまいます.これを防ぐために現在のボックスの位置からアニメーション時間を再設定するようにしましょう.
サンプルページはこちらからも閲覧できます.
サンプルページのコードはこちらからダウンロードできます.