From ccbdea08d60c957ba9bf122febd4de4e8afa4c05 Mon Sep 17 00:00:00 2001 From: dhrname Date: Sat, 5 Nov 2016 22:37:22 +0900 Subject: [PATCH] Modify the activeTime property of the object --- org/w3c/dom/smil.js | 32 +++++++++++++++++++++----------- tool/Spec/spec/SvgDomSpec.js | 5 +++++ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/org/w3c/dom/smil.js b/org/w3c/dom/smil.js index 67e21aa..d0ba046 100644 --- a/org/w3c/dom/smil.js +++ b/org/w3c/dom/smil.js @@ -108,6 +108,10 @@ base("$frame").mix ( { /*終了時刻(単位フレーム数)のキャッシュとして使う*/ end: 0, + /*開始時刻から終了時刻までのフレーム数 + * これがactiveTimeより短ければ、活動継続時間とみなす*/ + beginEnd: Number.MAX_VALUE, + /*開始時刻(単位フレーム数)リスト (後述のupdateStateメソッドで使う)*/ beginList: { next: null, @@ -201,6 +205,7 @@ base("$frame").mix ( { this.begin = startTime; } else if (!startTime) { /*開始時刻が0ならば、アニメーションを開始*/ + this.begin = 0; this.state = begin; } } else if (state === begin) { @@ -209,23 +214,30 @@ base("$frame").mix ( { this.state = end; /*現時点を終了時刻とみなす*/ this.end = f; + /*activeTimeプロパティは、begin属性とend属性が反映されていないため、 + * beginEndプロパティに別に設定しておく*/ + this.beginEnd = 0; } else { this.state = play; } } else if (state === play) { - if ( (endTime >= cacheBegin) || (startTime > cacheBegin) ) { + if ( (f >= cacheBegin + this.activeTime) + || (endTime >= cacheBegin) || (startTime > cacheBegin) ) { /*終了時刻に到達したか、再び開始イベントが発火されたとき*/ this.state = end; /*現時点を終了時刻とみなす*/ this.end = f; + /*activeTimeプロパティは、begin属性とend属性が反映されていないため、 + * beginEndプロパティに別に設定しておく*/ + (endTime > 0) && (this.beginEnd = endTime - startTime); } } else if (state === end) { - if (endTime >= cacheBegin) { - this.state = post; - } else { + if (startTime > cacheBegin) { /*再生中に開始イベントが発火されて、終了状態となったとき*/ this.state = begin; this.begin = startTime; + } else { + this.state = post; } } else { this.state = begin; @@ -418,7 +430,6 @@ base("$frame").mix ( { /*イベントのリスナーとして使う*/ listener = function(evt) { objList.value = this.begin = eventOffset + base("$frame").currentFrame; - endList.value = this.begin + this.activeTime; this.isResolved = true; }; this.eventOffset = eventOffset; @@ -440,8 +451,6 @@ base("$frame").mix ( { } else { /*開始リストに登録しておく($endの場合は終了リストに登録)*/ this.$list.addList(this.begin); - /*活動継続時間から算出される終了フレーム数は、終了リストに入れておく*/ - endList.value = this.begin + this.activeTime; } s = event = str = plusminus = ele = void 0; }, @@ -473,7 +482,7 @@ base("$frame").mix ( { var s = ( this.$activate = this.$activate.up() ); /*$endオブジェクトに付属している$listプロパティを更新したものと一致させておく*/ s.end && (s.end.$list = this.$list); - this.activeTime = s.call() || Number.MAX_VALUE; + this.activeTime = this.$list.activeTime = s.call() || Number.MAX_VALUE; this.simpleDuration = s.simpleDur; return this; } @@ -1191,7 +1200,6 @@ base("$calcMode").up("$attribute").mix( { ele.beginElement = (frame.string !== "indefinite") ? function(){} : function() { objList.value = frame.begin = base("$frame").currentFrame; - endList.value = frame.begin + frame.activeTime; frame.isResolved = true; var evt = this.ownerDocument.createEvent("MouseEvents"); evt.initMouseEvent("beginEvent" ,true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, this); @@ -1202,8 +1210,8 @@ base("$calcMode").up("$attribute").mix( { ele.endElement = (endFrame.string !== "indefinite") ? function(){} : function() { if (frame.isResolved) { - endList.value = frame.begin + frame.activeTime; endFrame.isResolved = true; + endList.value = base("$frame").currentFrame; var evt = this.ownerDocument.createEvent("MouseEvents"); evt.initMouseEvent("endEvent" ,true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, this); this.dispatchEvent(evt); @@ -1465,7 +1473,9 @@ base("$calcMode").up("$attribute").mix( { var line = this.timeline, duration = line.simpleDuration; if (duration) { - var advance = ( line.activeTime % duration ) / duration; + var time = (line.activeTime > $list.beginEnd) ? $list.beginEnd + : line.activeTime; + var advance = ( time % duration ) / duration; /*例外が発生するため、進捗率が1を超えないように処理*/ advance = (advance > 1) ? 1 : advance; /*活動継続時間と単純継続時間が一致すると、余りは0となるため以下の処理*/ diff --git a/tool/Spec/spec/SvgDomSpec.js b/tool/Spec/spec/SvgDomSpec.js index edd03ce..729e8fc 100644 --- a/tool/Spec/spec/SvgDomSpec.js +++ b/tool/Spec/spec/SvgDomSpec.js @@ -167,6 +167,7 @@ describe("SMIL Animation Spec", function() { expect(frame.POSTWAITING).toBe(4); expect(frame.state).toBe(frame.WAITING); expect(frame.end).toBe(0); + expect(frame.beginEnd).toBe(Number.MAX_VALUE); expect(frame.beginList).toEqual({ next: null, @@ -269,6 +270,7 @@ describe("SMIL Animation Spec", function() { expect(frame.begin).toBe(0); expect(frame.updateState(1).state).toBe(frame.ENDING); expect(frame.end).toBe(1); + expect(frame.beginEnd).toBe(Number.MAX_VALUE); expect(frame.updateState(1).state).toBe(frame.BEGINNING); expect(frame.begin).toBe(1); expect(frame.updateState(1).state).toBe(frame.PLAYING); @@ -291,6 +293,7 @@ describe("SMIL Animation Spec", function() { expect(frame.updateState(3).state).toBe(frame.ENDING); expect(frame.state).toBe(frame.ENDING); expect(frame.end).toBe(3); + expect(frame.beginEnd).toBe(2); expect(frame.updateState(4).state).toBe(frame.POSTWAITING); expect(frame.state).toBe(frame.POSTWAITING); @@ -303,6 +306,7 @@ describe("SMIL Animation Spec", function() { expect(frame.updateState(3).state).toBe(frame.ENDING); expect(frame.state).toBe(frame.ENDING); expect(frame.end).toBe(3); + expect(frame.beginEnd).toBe(2); expect(frame.updateState(4).state).toBe(frame.POSTWAITING); expect(frame.state).toBe(frame.POSTWAITING); expect(frame.updateState(4).state).toBe(frame.POSTWAITING); @@ -312,6 +316,7 @@ describe("SMIL Animation Spec", function() { expect(frame.updateState(1).state).toBe(frame.BEGINNING); expect(frame.updateState(1).state).toBe(frame.ENDING); expect(frame.end).toBe(1); + expect(frame.beginEnd).toBe(0); expect(frame.updateState(1).state).toBe(frame.POSTWAITING); } ); /*無効同値クラスを調べておく (Equivalence partitioning, the following is the invalid partion)*/ -- 2.11.0