ASP.NET AJAX Control Toolkit の AnimationExtender には DiscreteAnimation というクラスがあります。このアニメーションは、指定したプロパティに、配列として渡したプロパティ値を一定の時間内で順に適用するものです。
この Discrete アニメーションを調べていて、XML 記述で Values 属性値にどのように値の配列を渡すのかがわかりませんでした。
ドキュメントをみても、
http://ajax.asp.net/ajaxtoolkit/Walkthrough/AnimationReference.aspx#DiscreteAnimation
Array values;
Array of possible values of the property that will be iterated over as the animation is played.
としか書いていないし・・・
以下のように、JSON, カンマ, セミコロン などを試しましたが当然NG。
<%-- JSON 記述 ( NG ) --%>
<Discrete Property="style" PropertyKey="backgroundColor" Duration="5.0"
Values="['white', 'lightskyblue', 'royalblue', 'blue', '#ffb6c1']" />
<%-- カンマ ( NG ) --%>
<Discrete Property="style" PropertyKey="backgroundColor" Duration="5.0"
Values="'white', 'lightskyblue', 'royalblue', 'blue', '#ffb6c1'" />
<%-- セミコロン ( NG ) --%>
<Discrete Property="style" PropertyKey="backgroundColor" Duration="5.0"
Values="'white'; 'lightskyblue'; 'royalblue'; 'blue'; '#ffb6c1'" />
ということで、Discrete Animation で検索してみたところ、US の ASP.NET Forums に答えが出ていました。
http://forums.asp.net/p/1108530/1705424.aspx
MSの方の回答で、Values 属性でなくて ValuesScript 属性を使って JSON 記述で記述するとのこと。
<%-- ValuesScript を使って JSON 記述 ( OK! )--%>
<Discrete Property="style" PropertyKey="backgroundColor" Duration="5.0"
ValuesScript="['white', 'lightskyblue', 'royalblue', 'blue', '#ffb6c1']" />
うおーっ、こんな裏技が隠されていたのか!!と驚愕(ドキュメントに書いてよー)。
ということで、この ValuesScript がどんな実装をしているかを早速調べてみたら、そこからは新たな事実が・・・
それは、
ダイナミックプロパティ ( Dynamic Properties ) というものの存在でした。
通常のプロパティ(属性)は、Animation オブジェクトの生成時に静的に値が決まってしまいますが、ダイナミックプロパティは、アニメーションの開始時( onStart メソッド実行時)に、その値が動的に評価され設定されるとのこと。
ダイナミックプロパティかどうかの判別は、プロパティ(属性)名の接尾辞(suffix)が "script" かどうかで決まります。また、ダイナミックプロパティの場合、その値は JavaScript の eval 関数で評価されます。
つまり、プロパティ(属性)名の終わりに script を付ければ、値に JavaScript が記述できるのです!
たまたま、Discrete Animation の ValuesScript でこのダイナミックプロパティの存在を知りましたが、AnimationExtender の他のアニメーションのプロパティにも応用可能です。
例えば、Duration プロパティのかわりに DurationScript を使って、テキストボックスから値を取得することも出来ます。
<%-- Panel1 のフェードイン、移動、リサイズの並列実行 --%>
<Parallel AnimationTarget="Panel1"
DurationScript="(isNaN($get('Text1').value)) ? 0 : $get('Text1').value;">
<FadeIn />
<Move Horizontal="80" Vertical="120" Unit="px" />
<Resize Width="300" Height="300" Unit="px" />
</Parallel>
このダイナミックプロパティ、他のアニメーションを見ていくと、
- Script Action の script プロパティ
- Condition Animation の conditionScript プロパティ
- Case Animation の selectScript プロパティ
などでも使われていますね。
AnimationExtender を使うにあたって、状況によっては利用価値がありそうですので、覚えておいて損はないでしょう。
以下、簡単にダイナミックプロパティ ( Dynamic Properties ) の実装の抜粋を記しておきます。
●Animations.js
$AA.createAnimation = function(obj, defaultTarget) {
for (var property in obj) {
var prop = property.toLowerCase();
...(中略)...
// Try to set the value of a dynamic property
if (prop.endsWith('script')) {
setter = properties[prop.substr(0, property.length - 6)];
if (setter && String.isInstanceOfType(setter) && animation[setter]) {
animation.DynamicProperties[setter] = value;
}
}
...(中略)...
}
onStart : function() {
...(中略)...
// Initialize any dynamic properties
for (var property in this.DynamicProperties) {
try {
// Invoke the property's setter on the evaluated expression
this[property](eval(this.DynamicProperties[property]));
} catch(ex) {
...(中略)...
}
}
},
※この実装から見ると、プロパティ(属性)名の大文字小文字は関係ないようですね。疑問がさらに1つ解決です。