X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=org%2Fw3c%2Fdom%2Fsmil.js;h=98a3e8185c48f35d5f0051c54f33d7a5b1d6246b;hb=10d8ac51ff374615967e14c29e14f88df9a0e515;hp=e21f2d9c07f428d09e4d5697b1185e022a2a00c9;hpb=9619997183601656c5af59ec17bfc0ddd26f86c6;p=sie%2Fsie.git diff --git a/org/w3c/dom/smil.js b/org/w3c/dom/smil.js index e21f2d9..98a3e81 100644 --- a/org/w3c/dom/smil.js +++ b/org/w3c/dom/smil.js @@ -105,18 +105,35 @@ base("$frame").mix ( { } } ).mix( function($frame) { $frame.up("$list").mix( { - /*開始時刻リスト (後述のupdateStateメソッドで使う)*/ + /*終了時刻(単位フレーム数)のキャッシュとして使う*/ + end: 0, + + /*開始時刻(単位フレーム数)リスト (後述のupdateStateメソッドで使う)*/ beginList: { next: null, value: Number.MAX_VALUE }, - /*終了時刻リスト (後述のupdateStateメソッドで使う)*/ + /*終了時刻(単位フレーム数)リスト (後述のupdateStateメソッドで使う)*/ endList: { next: null, value: Number.MAX_VALUE }, + addBeginList: function (num) { + return ( this.beginList = { + value: num, + next: this.beginList + } ); + }, + + addEndList: function (num) { + return ( this.endList = { + value: num, + next: this.endList + } ); + }, + /*引数に渡された時刻リストの中から、現在フレームf以下の、最大値を求めるメソッド * -1を返したときはリストの中にf以下の値がないことを示す*/ getMaxList: function (f, list) { @@ -151,6 +168,13 @@ base("$frame").mix ( { /*終了処理をした後の待機状態を示す定数*/ POSTWAITING: 4, + /*初期化用メソッド*/ + init: function() { + this.state = this.WAITING; + this.begin = 0; + return this; + }, + /*引数で指定されたフレーム数に応じて、stateプロパティを更新するメソッド*/ updateState: function( /*number*/ f) { if (f === void 0) { @@ -162,32 +186,38 @@ base("$frame").mix ( { begin = /*this.BEGINNING*/ 1, play = /*this.PLAYING*/ 2, end = /*this.ENDING*/ 3, - post = /*this.POSTWAITING*/ 4, - isWait = (state === wait) || (state === post); + post = /*this.POSTWAITING*/ 4; /*beginListプロパティと、endListプロパティの中で、 * 現在フレーム数 f より大きい数値は、更新できる条件と無関係なので、除外しておく * また、f以下の値の中から、最大値を探して、 - * それをbeginプロパティと比較する*/ + * それをbeginプロパティの値cacheBeginと比較する*/ var startTime = this.getMaxList(f, this.beginList), endTime = this.getMaxList(f, this.endList), cacheBegin = this.begin; - if ( isWait && (startTime > cacheBegin) ) { - this.state = begin; - /*beginプロパティに開始時刻をキャッシュ用に保存*/ - this.begin = startTime; - } else if (isWait && !f && !startTime) { - /*開始時刻が0ならば、アニメーションを開始*/ - this.state = begin; - } else if (isWait) { - return this; + if ( (state === wait) || (state === post) ) { + if (startTime > cacheBegin) { + this.state = begin; + /*beginプロパティに開始時刻をキャッシュ用に保存*/ + this.begin = startTime; + } else if (!startTime) { + /*開始時刻が0ならば、アニメーションを開始*/ + this.state = begin; + } } else if (state === begin) { - this.state = play; + if (endTime >= cacheBegin) { + /*終了時刻にもう到達したときは、直接BEGINNING状態からENDING状態へ移行*/ + this.state = end; + /*現時点を終了時刻とみなす*/ + this.end = f; + } else { + this.state = play; + } } else if (state === play) { if ( (endTime >= cacheBegin) || (startTime > cacheBegin) ) { /*終了時刻に到達したか、再び開始イベントが発火されたとき*/ this.state = end; - } else { - return this; + /*現時点を終了時刻とみなす*/ + this.end = f; } } else if (state === end) { if (endTime >= cacheBegin) { @@ -202,13 +232,61 @@ base("$frame").mix ( { } cacheBegin = startTime = endTime = void 0; return this; + }, + + /*addEventメソッドで使われるイベントリスト(開始時に登録されたリスナー関数が呼び出される)*/ + _beginListenerList: [], + + /*addEventメソッドで使われるイベントリスト(終了時に登録されたリスナー関数が呼び出される)*/ + _endListenerList: [], + + /*addEventメソッドで使われるイベントリスト(再生時に登録されたリスナー関数が呼び出される)*/ + _playListenerList: [], + + /*開始と再生と終了時に発火されるイベントリスナーを登録するメソッド*/ + addEvent: function ( /*string*/ eventName, /*fnction*/ listener) { + var evtName = "_" +eventName+ "ListenerList"; + /*プロトタイプ継承していた場合は新しく配列を作成*/ + if (!this.hasOwnProperty(evtName)) { + this[evtName] = []; + } + this[evtName].push(listener); + }, + + /*入力されたフレーム数fの場面に切り替えるメソッド*/ + setFrame: function( /*number*/ f) { + this.currentFrame = f; + var state = this.updateState(f).state; + /*アニメーション開始と再生と、終了状態のときに、beginとplayとendイベントを呼び出しておいて、 + * 次の状態(再生状態)に遷移する*/ + if (state === /*this.PLAYING*/ 2) { + var list = this._playListenerList; + for (var i=0;i 0) { @@ -330,47 +406,76 @@ base("$frame").mix ( { this.begin = Math.floor( this.begin * this.fpms); if (str === "indefinite") { /*begin属性の値がindefiniteの場合は、何もしない。 - * 開始時刻はlistenerメソッドの呼び出しか、beginElementメソッドに依存*/ + * 開始時刻はbeginElementメソッドに依存*/ } else if (event) { ele = event.id ? this.eventTarget.ownerDocument.getElementById(event.id) : this.eventTarget; - /*イベントの時間差を設定しておく*/ - this.eventOffset = this.begin; + /*イベントの時間差を設定しておく + * eventOffsetとobjListの変数はクロージャとしてlistener関数で使われる*/ + var eventOffset = this.begin, + /*objListのvalueプロパティはあとで書き換えられる(イベントの場合のみ)*/ + objList = this.$list.addList(Number.MAX_VALUE), + /*イベントのリスナーとして使う*/ + listener = function(evt) { + objList.value = this.begin = eventOffset + base("$frame").currentFrame; + endList.value = this.begin + this.activeTime; + this.isResolved = true; + }; + this.eventOffset = eventOffset; if (this.repeat > 0) { ele && ele.addEventListener("repeatEvent", (function(evt) { if (evt.detail === this.repeat) { - this.listener(evt); + listener.call(this, evt); } }).bind(this), true); } else if (this.accessKey) { document.documentElement.addEventListener("keydown", (function(evt) { if (evt.char === this.accessKey) { - this.listener(evt); + listener.call(this, evt); } }).bind(this), false); } else { var evtName = /^(?:begin|end|repeat)$/.test(event.event) ? event.event + "Event" : event.event; - ele && ele.addEventListener(evtName, this.listener.bind(this), false); + ele && ele.addEventListener(evtName, listener.bind(this), false); } } else { - /*イベントの影響を防ぐため - * すでに、フレームオブジェクトのタイムラインには登録済みなので、 - * フレームではなく、自分独自のタイムラインに登録しておけばよい*/ - this.$frame = this; + /*開始リストに登録しておく($endの場合は終了リストに登録)*/ + this.$list.addList(this.begin); + /*活動継続時間から算出される終了フレーム数は、終了リストに入れておく*/ + endList.value = this.begin + this.activeTime; } s = event = str = plusminus = ele = void 0; + }, + + /*stringプロパティを解析して、 + * 開始フレーム数の算出や、イベントリスナーの登録をするメソッド*/ + parse: function() { + /*初期値を設定*/ + this.begin = 0; + this.isResolved = false; + var str = this.trim(this.string); + if (str.indexOf(";") > -1){ + /*;で区切られたリストを一つずつ解析*/ + var list = str.split(";"); + for (var i=0;i