月別アーカイブ: 2012年10月

[JS] 配置済み要素のbackground-image読み込みハンドリング

HTML/CSS


<style type="text/css">
	#bg {
		background: url("bg.jpg") no-repeat;
	}
</style>

<div id="bg">Lorem ipsum<div>

JavaScript



var getBgImage = (function() {

	var func;

	if ( document.documentElement.currentStyle ) {
		func = function( element ) {
			var val = element.currentStyle.backgroundImage;
			return val.replace( /(url\(|\)|")/g, '' );
		}
	} else if ( window.getComputedStyle ) {
		func = function( element ) {
			var val = document.defaultView.getComputedStyle( element, null ).getPropertyValue( 'background-image' );
			return val.replace( /(url\(|\)|")/g, '' );
		}
	}

	return func;
})();

var img,
src = getBgImage( document.getElementById( 'img1' ) );

if ( src !== '' ) {
	img = new Image();
	img.onload = function() {
		alert( '読み込み完了' );
	};
	img.src = src;
}

こういうことでいいのかな。

画像読み込み用のクラスみたいなのを作っておいて、そこに上記で得たパスやdocument.imagesの中身も合わせて全部ブチ込んで、ページ全体の画像読み込みの進捗を調べるってのはさすがに乱暴だろうか。

なんでこんなことで悩まなきゃならんのだ。



[JS] パラパラマンガ用JSを作ってみました

2013/02/16: 改修したバージョンがこちらにあります。
2012/10/16: スクリプトと記事の内容を修正しました。

さるお方の情報により初めて知ったのですが、jQueryの.animate()などで一度に複数の要素をアニメーションさせると、IE8環境では配置済みのgifアニメが停止しちゃうらしい。しかもIE7でもIE TesterでもIE9の8モードでもなく、ネイティブIE8でしか再現しないというなんともややこしい症状。

自宅にネイティブIE8環境が無いので自分の目では確認できていませんが、原因が多重に発生する再配置や再描画にあるのなら、jQueryだと$.fx.intervalを調整するなどしてその処理を減らしてやれば、ある程度までは緩和できそうです。しかし、それでもダメならこれはもうgifアニメを何か他のもので代替するしかないような…?負荷や処理落ちは別として、あくまでアニメーションの停止を回避する策としては。

前置きが長くなりましたが、ここでようやっと記事タイトルに繋がります。
簡単かつアナクロなスクリプトですが、ネタも無いことだし以下に公開します。


Flipbook.js – デモFlipbook.js – ダウンロード

使い方とか


まず flipbook.min.js を読み込んでおき、CSSでposition(relative or absolute)、width、heightを設定したID付き要素を配置。
<style>
	#screen {
		position: relative;
		width: 500px;
		height: 250px;
	}
</style>

<div id="screen"></div>

以下はJS記述例。
// 画像パスを格納した配列。格納した順で表示します。
var imgList = [ 'img0.jpg', 'img1.jpg', 'img2.jpg' ];
 
// インスタンスを作成。第一引数にターゲットID名、第二引数に画像のリストを渡します。
// 要素を確実にゲットできるよう、DOM構築完了後である必要があります。
var flipbook = new Flipbook( 'screen', imgList );
 
// 第一引数は要素を渡してもいいですし、
// var flipbook = new Flipbook( document.getElementById('screen'), imgList );
 
// jQueryオブジェクトを渡してもOKです。
// var flipbook = new Flipbook( $('#screen'), imgList );
 
// 必要に応じてハンドラメソッドを定義して下さい。
var handler = function( data ){
	console.log( data.type ); // イベント名
	console.log( data.frameNumber ); // 現在のフレームを示す数字
}
flipbook.onFirstFrame = handler; // 最初のフレームに達した
flipbook.onLastFrame = handler; // 最後のフレームに達した
flipbook.onUpdate = handler; // フレームが更新された
 
// 再生
flipbook.play();


メソッド


再生:
.play()
一時停止:
.pause();
停止:
.stop();
逆再生:
.reverse()
最初から再生(逆再生フラグが立ってる場合は最終フレームから逆再生):
.replay()
任意フレームにジャンプ:
.setFrame( frameNumber:Integer );

ゲッター / セッター etc.


再生スピード(ミリ秒。デフォルトは33):
.getSpeed():Integer
.setSpeed( milliSecond:Integer )
ループ再生(デフォルトはtrue):
.getLoop():Boolean
.setLoop( value:Boolean )
現在のフレーム:
.getCurrentFrame():Integer
フレーム総数:
.getTotalFrames():Integer
再生中?:
.isPlaying():Boolean
逆再生フラグ?
.isReverse():Boolean


アニメーション(パラパラマンガ)部分については、配置したimgのsrcを書き換えたりなどいろいろ試しましたが、スタイルシートでbackgroundを書き換えるという方法が一番安定していたのでそれで実装しました。

が、改めて確認するとIEでまともに動いてなかったため、imgを枚数分position:absoluteで重ねて配置してvisibilityを切り替える方法に修正しました。

ちょっと扱いにくくなるので採用しませんでしたが、負荷の軽さで言えばスプライトシートを用意してbackground-positionでアレする方法が多分一番じゃないかと思います。