this.style.setProperty = function(){};
this._tar = null;
/*readonly SVGElement*/ this.targetElement;
- this._beginValue = "0ms";
- this._endValue = null;
+ /*それぞれのプロパティは、_を除いた属性に対応している*/
+ this._begin = this._end = this._repeatCount = this._repeatDur = null;
+ this._dur = "indefinite";
this._currentFrame = 0;
- this._currentCount = 0;
/*_maxCountはrepeatCount属性で指定された数値
*_maxDurはrepeatDur属性で指定された数値
*/
this._maxCount = 0;
this._maxDur = 0;
+ /*_isRepeatと_numRepeatは繰り返し再生のときに使う。なお、後者は現在のリピート回数*/
this._isRepeat = false;
- /*_simpleDurationプロパティは
- *dur属性の数値を収納しておく。属性がなければnullのまま
- */
- this._simpleDuration = null;
- /*_beginと_endプロパティはミリ秒数を収納する。リピート時に書き換えられることがある。
- *_beginはアニメ開始時の秒数。_endはアニメ終了時の秒数。
+ this._numRepeat = 0;
+ /*_startと_finishプロパティはミリ秒数を収納する。
+ *_startはアニメ開始時の秒数。_finishはアニメ終了時の秒数。
*なお、文書読み込み終了時(アニメ開始時刻)の秒数を0とする。
*/
- this._begin = null;
- this._end = null;
+ this._start = this._finish = null;
this._from = this._to = this._values = this._by = null;
this._keyTimes = null;
this.addEventListener("beginEvent", function(evt) {
- var tar = evt.target;
- if (!tar.isRepeat) {
- tar.endElementAt(tar.getSimpleDuration());
- } else {
- tar.beginElementAt(tar.getSimpleDuration());
- if (tar.getCurrentTime() !== 0) {
- var ttd = tar.ownerDocument, evt = ttd.createEvent("TimeEvents");
- tar._currentCount++;
- evt.initTimeEvent("repeatEvent", ttd.defaultView, tar._currentCount);
- tar.dispatchEvent(evt);
+ try {
+ var tar = evt.target,
+ be = tar._start,
+ dur = tar.getSimpleDuration(),
+ durv = tar._dur,
+ end = tar._finish,
+ endv= tar._end,
+ td = tar._repeatDur,
+ tc = tar._repeatCount,
+ ac = 0;
+ /*Activate Duration (活性持続時間と呼ぶことにする)を計算
+ *計算方法は以下を参照のこと
+ *http://www.w3.org/TR/smil-animation/#ComputingActiveDur
+ *3.3.4. Computing the active duration
+ */
+ if ((td === "indefinte") || (tc === "indefinte")) {
+ if (endv) {
+ ac = end - begin;
+ } else {
+ /*活性持続時間が不定(indefinte)なので、強制的にアニメを終了させる*/
+ }
+ } else if (durv === "indefinte") {
+ if (!tc && !endv) {
+ /*活性持続時間が不定(indefinte)なので、強制的にアニメを終了させる*/
+ } else if (tc && !endv) {
+ ac = tar._getOffset(td);
+ } else if (!tc && endv) {
+ ac = end - begin;
+ } else {
+ ac = (tar._getOffset(td) > (end - begin)) ? tar._getOffset(td) : (end - begin);
+ }
+ } else if (durv && !td && !tc && !endv) {
+ ac = dur;
+ } else if (durv && !td && tc && !endv) {
+ ac = dur * (+tc);
+ } else if (durv && td && !tc && !endv) {
+ ac = tar._getOffset(td);
+ } else if (durv && !td && !tc && endv) {
+ ac = (dur > (end - begin)) ? dur : (end - begin);
+ } else if (durv && td && tc && !endv) {
+ ac = (+tc*dur > tar._getOffset(td)) ? +tc*dur : tar._getOffset(td);
+ } else if (durv && td && tc && endv) {
+ ac = (+tc*dur > Math.min(+td, (end-begin))) ? +tc*dur : Math.min(tar._getOffset(td), (end - begin));
+ } else if (durv && td && !tc && endv) {
+ ac = (tar._getOffset(td) > (end - begin)) ? tar._getOffset(td) : (end - begin);
+ } else if (durv && !td && tc && endv) {
+ ac = (+tc*dur > (end - begin)) ? +tc*dur : (end - begin)
}
+ } catch (e) {
+ throw new DOMException(DOMException.INVALID_STATE_ERR);
}
+ tar.endElementAt(active);
}, false);
this.addEventListener("DOMAttrModified", function(evt){
if (evt.eventPhase === /*Event.BUBBLING_PHASE*/ 3) {
}
var tar = evt.target,
name = evt.attrName,
- timing = function(val, name) {
- /*timing関数は時間のタイミングをidとeventと、clock-value(offset)に分割して処理していく
- *まず、idを検出するためのsearcIdローカル関数を作る
- */
- var offset = 0,
- searchId = function () {
- var n = val.indexOf(".");
- if ((n > 0) && val.charAt(n+1).test(/[a-z]/i)) { //. (dot)の後がアルファベットならば
- return (val.slice(0, n));
- }
- n = nn = void 0;
- return "";
- },
- _tar = tar,
- id;
- /*offsetの計算*/
- var n = parseFloat(val.match(_tar._timeRegExp));
- if (isFinite(n) && RegExp.$1) {
- offset = n * _tar._unit[RegExp.$1]
- } else if (isFinite(n)) {
- offset = n;
- }
- /*
- *W3CのSMIl AnimationのTimingモデルは7パターンがあるので、場合分けする
- */
- if (isFinite(parseFloat(val))) { //1) offset-valueの場合
- _tar[name](offset);
- } else if (val.indexOf("repeat(") > -1) { //2) repeat-valueの場合
- n = 0;
- var inte = parseFloat(val.slice(7)),
- ds = function (evt) {
- ++n;
- if (inte === n) {
- _tar[name](offset);
- }
- };
- id = searchId();
- if (id) {
- _tar.ownerDocument.getElementById(id).addEventListener("repeat", ds);
- } else {
- _tar.addEventListener("repeat", ds);
- }
- } else if (val.test(/\.(begin|end)/)) { //3) syncbase-valueの場合
- id = searchId();
- if (id) {
- var ds = function (evt) {
- _tar[name](offset);
- },
- ev = "";
- if (RegExp.$1 === "begin") {
- ev = "beginEvent";
- } else if (RegExp.$1 === "end") {
- ev = "endEvent";
- }
- _tar.ownerDocument.getElementById(id).addEventListener(ev, ds);
- }
- } else if (val.indexOf("wallclock(") === 0) { //4) wallclock-valueの場合
-
- } else if (val === "indefinte") { //5) indefinteの場合
- } else if (val.indexOf("accesskey(") > -1) { //6) accesskey-valueの場合
-
- } else { //7) event-valueの場合
- id = searchId();
- var ds = function (evt) {
- _tar[name](offset);
- };
- if (id && val.match(new RegExp(id+"\.([a-zA-Z]+)"))) {
- _tar.ownerDocument.getElementById(id).addEventListener(RegExp.$1, ds);
- } else {
- _tar.targetElement.addEventListener(val.match(/^[a-z]+/i), ds)
- }
- }
- };
+ evtv = evt.newValue;
if (name === "begin") {
- tar._beginValue = evt.newValue;
- timing(evt.newValue, "beginEvent");
+ tar._begin = evtv;
} else if (name === "end") {
- tar._endValue = evt.newValue;
- timing(evt.newValue, "endEvent");
+ tar._end = evtv;
} else if (name === "dur") {
- tar._simpleDuration = tar._getOffset(evt.newValue);
+ tar._dur = evtv;
} else if (name === "repeatCount") {
- tar._maxCount = parseFloat(evt.newValue);
+ tar._maxCount = parseFloat(evtv);
+ tar._repeatCount = evtv;
tar._isRepeat = true;
} else if (name === "repeatDur") {
- tar._maxDur = parseFloat(evt.newValue);
+ tar._maxDur = parseFloat(evtv);
+ tar._repeatCount = evtv;
tar._isRepeat = true;
} else if (name === "from") {
- tar._from = evt.newValue;
+ tar._from = evtv;
} else if (name === "to") {
- tar._to = evt.newValue;
+ tar._to = evtv;
} else if (name === "values") {
- tar._values = evt.newValue.split(";");
+ tar._values = evtv.split(";");
} else if (name === "by") {
- tar._by = evt.newValue;
+ tar._by = evtv;
} else if (name === "keyTimes") {
- var s = evt.newValue.split(";");
+ var s = evtv.split(";");
tar._keyTimes = []; //_keyTimesプロパティを初期化
for (var i=0;i<s.length;++i) {
tar._keyTimes[i] = parseFloat(s[i]);
}
s = void 0;
}
- evt = void 0;
+ evt = evtv = void 0;
}, false);
this.addEventListener("DOMNodeInserted", function(evt){
if (evt.eventPhase === /*Event.BUBBLING_PHASE*/ 3) {
*/
return this;
}
+ /*begin属性とend属性を処理する*/
+ var _begin = tar._begin ? tar._getOffset(tar._begin) : 0,
+ that = tar,
+ timing = function(val, name, offset) {
+ /*timing関数は時間のタイミングをidとeventと、clock-value(offset)に分割して処理していく
+ *まず、idを検出するためのsearcIdローカル関数を作る
+ */
+ var searchId = function () {
+ var n = val.indexOf(".");
+ if ((n > 0) && (/[a-z]/i).test(val.charAt(n+1))) { //. (dot)の後がアルファベットならば
+ return (val.slice(0, n));
+ }
+ n = nn = void 0;
+ return "";
+ },
+ id;
+ /*
+ *W3CのSMIl AnimationのTimingモデルは7パターンがあるので、場合分けする
+ */
+ if (isFinite(parseFloat(val))) { //1) offset-valueの場合
+ that[name](offset);
+ } else if (val.indexOf("repeat(") > -1) { //2) repeat-valueの場合
+ var inte = parseFloat(val.slice(7)),
+ ds = function (evt) {
+ if (inte === evt.target._numRepeat) {
+ that[name](offset);
+ }
+ };
+ id = searchId();
+ if (id) {
+ that.ownerDocument.getElementById(id).addEventListener("repeatEvent", ds);
+ } else {
+ that.addEventListener("repeatEvent", ds);
+ }
+ } else if ((/\.(begin|end)/).test(val)) { //3) syncbase-valueの場合
+ id = searchId();
+ if (id) {
+ var ds = function (evt) {
+ that[name](offset);
+ },
+ ev = "";
+ if (RegExp.$1 === "begin") {
+ ev = "beginEvent";
+ } else if (RegExp.$1 === "end") {
+ ev = "endEvent";
+ }
+ that.ownerDocument.getElementById(id).addEventListener(ev, ds);
+ }
+ } else if (val.indexOf("wallclock(") === 0) { //4) wallclock-valueの場合
+
+ } else if (val === "indefinte") { //5) indefinteの場合
+ } else if (val.indexOf("accesskey(") > -1) { //6) accesskey-valueの場合
+
+ } else { //7) event-valueの場合
+ id = searchId();
+ var ds = function (evt) {
+ that[name](offset);
+ };
+ if (id && val.match(/\.([a-z]+)/i)) {
+ that.ownerDocument.getElementById(id).addEventListener(RegExp.$1, ds);
+ } else if (val){
+ that.targetElement.addEventListener(val.match(/^[a-z]+/i)[0], ds)
+ }
+ }
+ val = searchId = id = void 0;
+ };
+ timing((tar._begin || "0ms"), "beginElementAt", _begin);
+ if (tar._end) {
+ timing(tar._end, "endElementAt", tar._getOffset(tar._end));
+ }
+ that = void 0;
if (tar.hasAttributeNS("http://www.w3.org/1999/xlink", "xlink:href")) {
tar.targetElement = tar.ownerDocument.getElementById(tar.getAttributeNS("http://www.w3.org/1999/xlink", "xlink:href").substring(1))
} else {
tar.targetElement = tar.parentNode;
}
- tar._eventSync(tar._beginValue,
- (function(te, offse, ta, t) {
- ta.addEventListener( t.match(te._eventRegExp)[0],
- function(){
- if (offse !== 0) {
- te.beginElementAt(offse);
- } else {
- te._begin = NAIBU.Time.currentFrame;
- te.beginElement();
- te._currentFrame++;
- }
- }, false);
- }), "beginElementAt");
- if (tar._endValue) {
- tar._eventSync(tar._endValue,
- (function(te, offse, ta, t) {
- ta.addEventListener( t.match(te._eventRegExp)[0],
- function(){
- te.endElementAt(offse);
- }, false );
- }), "endElementAt");
- }
evt = tar = void 0;
}, false);
evt = tar = void 0;
}, false);
- this.addEventListener("repeatEvent", function(evt) {
- var tar = evt.target;
- if ((tar._currentCount >= tar._maxCount) || (tar.getCurrentTime() >= (tar._maxDur+tar.getStartTime()))) {
- tar._isRepeat = false;
- }
- }, false);
return this;
};
SVGAnimationElement.constructor = SVGElement;
};
/*void*/ SVGAnimationElement.prototype.beginElementAt = function(/*float*/ offset) {
var ntc = this.ownerDocument.documentElement.getCurrentTime();
- this._begin = offset + ntc;
+ this._start = offset + ntc;
};
/*void*/ SVGAnimationElement.prototype.endElementAt = function(/*float*/ offset) {
var ntc = this.ownerDocument.documentElement.getCurrentTime();
- this._end = offset + ntc;
+ this._finish = offset + ntc;
};
SVGAnimationElement.prototype._eventRegExp = /(mouse|activ|clic|begi|en)[a-z]+/;
SVGAnimationElement.prototype._timeRegExp = /[\-\d\.]+(h|min|s|ms)?$/;
** Note that when the simple duration is "indefinite", some simple use cases can yield surprising results. See the related example #4 in Appendix B.
*/
SVGAnimationElement.prototype._getOffset = function(/*string*/ t) {
- var n = parseFloat(t.match(this._timeRegExp));
- if (!isNaN(n) && RegExp.$1) {
+ var n = parseFloat(t.match(this._timeRegExp)),
+ offset = 0;
+ if (isFinite(n) && RegExp.$1) {
var offset = n * this._unit[RegExp.$1]
- } else if (!isNaN(n)) {
- var offset = n;
- } else {
- var offset = 0;
+ } else if (isFinite(n)) {
+ offset = n;
}
n = t = void 0;
return offset;
};
-/*_eventSyncメソッド
- *イベントがある場合とない場合とで、別々の処理に分けるメソッド
- */
-SVGAnimationElement.prototype._eventSync = function(/*string*/ t, /*function*/ f, /*string*/ methodName) {
- var offset = this._getOffset(t);
- this._begin = NAIBU.Time.Max;
- if ( /(mouse|activ|click|begin|end)/.test(t) ) { //イベントがある場合
- var tar;
- if ( /([^;]+)\.\D/.test(t) ) {
- tar = this.ownerDocument.getElementById(RegExp.$1);
- } else {
- tar = this.targetElement;
- }
- if (!offset && offset !== 0) {
- offset = NAIBU.Time.Max;
- }
- f(this, offset, tar, t);
- } else if (!offset && (t !== "undefined") && (offset !== 0)) {
- this._begin = 0;
- } else {
- this[methodName](offset);
- }
-};
+
/*float*/ SVGAnimationElement.prototype.getStartTime = function(){
- if (!!this._begin || (this._begin === 0)) {
- return (this._begin);
+ if (this._start || (this._start === 0)) {
+ return (this._start);
} else {
throw new DOMException(DOMException.INVALID_STATE_ERR);
}
return (this._currentFrame * 125 * 0.8);
};
/*float*/ SVGAnimationElement.prototype.getSimpleDuration = function(){
- if (!!!this._simpleDuration && !!!this._end && (this._simpleDuration !== 0)) {
+ if (!this._dur && !this._finish && (this._dur === "indefinte")) {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR);
- } else if (!!this._simpleDuration && !!this._end) {
- var s = (this._simpleDuration > this._end - this._begin) ? this._end - this._begin : this._simpleDuration;
} else {
- var s = !!this._end ? this._end - this._begin : this._simpleDuration;
+ return (this._getOffset(this._dur));
}
- return s;
};
//raises( DOMException );
NAIBU.Time = {
}
NAIBU.stop = setInterval( (function() {
/* try{*/
- var ntc = NAIBU.Time.currentFrame++;
- var nc = NAIBU.Clip;
- var s = ntc * 100; //フレーム数ntcをミリ秒数sに変換
+ var ntc = NAIBU.Time.currentFrame,
+ nc = NAIBU.Clip,
+ s = ntc * 100; //フレーム数ntcをミリ秒数sに変換 (100 = 125 * 0.8)
if (ntc > NAIBU.Time.Max) {
clearInterval(NAIBU.stop);
}
+ nc[0] && nc[0].ownerDocument.documentElement.setCurrentTime(s);
for (var i=0,ncli=nc.length;i<ncli;++i) {
- var nci = nc[i];
- nci.ownerDocument.documentElement.setCurrentTime(s);
- if ("_begin" in nci) {
- if (nci.getStartTime() <= s) {
- if (nci.getCurrentTime() === 0) {
- nci.beginElement();
- }
- nci._currentFrame++;
- }
- if (nci._end && (nci._end <= s) && (nci.getCurrentTime() !== 0)) {
- nci.endElement();
- nci._frame && nci._frame();
- nci._currentFrame = 0;
- delete nci._begin;
- nci._end = null;
- } else if (!!nci._frame) {
- nci._frame();
- }
+ var nci = nc[i]
+ s2 = s + 100,
+ s1 = s - 100;
+ if ((nci._start || (nci._start === 0)) && (nci.getCurrentTime() === 0) && (s1 <= nci._start && nci._start < s2)) {
+ nci.beginElement();
+ }
+ if (nci._isRepeat && (nci.getCurrentTime() !== 0) && ((nci.getSimpleDuration() % s) === 0)) {
+ var ttd = nci.ownerDocument,
+ evt = ttd.createEvent("TimeEvents");
+ ++nci._numRepeat;
+ evt.initTimeEvent("repeatEvent", ttd.defaultView, nci._numRepeat);
+ nci.dispatchEvent(evt);
+ ttd = evt = void 0;
+ }
+ if ((nci._finish || (nci._finish === 0)) && (s1 <= nci._finish && nci._finish < s2) && (nci.getCurrentTime() !== 0)) {
+ nci.endElement();
+ nci._frame && nci._frame();
+ nci._currentFrame = 0;
+ }
+ if (nci._frame) {
+ nci._currentFrame++;
+ nci._frame();
}
- nci = void 0;
}
+ ++NAIBU.Time.currentFrame;
+ nci = s1 = s2 = void 0;
/* } catch (e) {
stlog.add(e, 4157);
}*/