要約: | - アニメーションは変化と動きをグラフィック ディスプレイに追加します。
- アニメーションを制御するには、Visual.animate メソッドを使用して Timer を作成します。
- Timers は、コードを指定された間隔または頻度で実行する必要がある場合に役に立ちます。
|
アニメーションは変化と動きをグラフィック ディスプレイに追加します。「
テキスト プロシージャにおけるアニメーションの使用」のセクションでは、簡単なアニメーションを使ってテキストの色を変える方法を示しています。この章ではアニメーションについてさらに詳しく説明します。
要約: | - interval および frequency プロパティを使用してアニメーションを制御します。
- アニメーションの開始および停止されるには、repeat プロパティを使用します。
- アニメーションの開始を遅らせるには、after マクロを使用します。
|
Curl® 言語でのアニメーションは非常にシンプルです。
Timer の設定には、
Visual.animate メソッドを使用します。
Timer は、それ自体で
TimerEvent を発生させてコード実行を制御します。
Timer に与えるイベント ハンドラのコードにより、グラフィックの外観を変更してタイマー イベントに応答します。Curl 言語は、
Timer 管理の下位レベルの詳細を扱います。
interval または
frequency のいずれかを指定して、発生するアニメーションの速度を制御します。次の例では、アニメーションは四角形で発生する一連の色の変化で構成されています。この変化のタイミングは
interval 引数の値によって調整されています。
例:
簡単なアニメーションによる色の変更 |
|
{let r:Fraction, g:Fraction, b:Fraction}
{let f:Fill = {Fill width=1cm, height=1cm, background="black"}}
{let cb:CommandButton =
{CommandButton
label = "change color for 5.5 seconds...",
{on Action do
{f.animate
interval=0.1s,
repeat = 55,
{on TimerEvent do
set r = (r + 0.05) mod 1.0
set g = (g + 0.02) mod 1.0
set b = (b + 0.03) mod 1.0
set f.background = {Color.from-rgb r, g, b}
}
}
}
}
}
{spaced-vbox f, cb}
| |
Curl 言語で可能な範囲でイベント ハンドラの Visual を変更することができます。次の例では、四角形のサイズが色とともに変わります。
例:
サイズと色の変更 |
|
{let r:Fraction, g:Fraction, b:Fraction}
{let f:Fill =
{Fill width = 1cm,
height = 1cm,
background = "black"}
}
{let cb:CommandButton =
{CommandButton
label = "change size and color for 5.5 seconds...",
{on Action do
{f.animate
interval = 0.1s,
repeat = 55,
{on TimerEvent do
set r = (r + 0.05) mod 1.0
set g = (g + 0.02) mod 1.0
set b = (b + 0.03) mod 1.0
set f.background = {Color.from-rgb r, g, b}
set f.width = 4cm * r
set f.height = 4cm * g
}
}
}
}
}
{VBox
{HBox height = 5cm, width = 5cm, f},
{HBox cb}
}
| |
interval または frequency 属性のいずれかを指定する必要があることに注意してください。両方とも省略または指定した場合、エラーが発生します。次の例では、アニメーションのタイミングの制御のために interval を frequency に置き換えています。
例:
タイミング制御に frequency を使用 |
|
{let r:Fraction, g:Fraction, b:Fraction}
{let f:Fill = {Fill width=1cm, height=1cm, background="black"}}
{let cb:CommandButton =
{CommandButton
label = "change color for 5.5 seconds...",
{on Action do
{f.animate
frequency=10Hz,
repeat = 55,
{on TimerEvent do
set r = (r + 0.05) mod 1.0
set g = (g + 0.02) mod 1.0
set b = (b + 0.03) mod 1.0
set f.background = {Color.from-rgb r, g, b}
}
}
}
}
}
{spaced-vbox f, cb}
| |
animate メソッドは
Timer を返します。この
Timer を変数に格納すると、
Timer の作成後にこれを操作することができます。タイマーがアクティブなときに
Timer の任意のプロパティを変更すると、変更後もアクティブである場合は
Timer の停止や新しい値での開始などの効果を得ることができます。
次の例では、ユーザーは Timer のコマンド ボタンを使用してアニメーションの速度を変更することができます。タイマーの間隔が短すぎると、ユーザーが間隔を増やすまで "Faster" ボタンは無効になっています。
例:
後で使用できるように Timer を格納 |
|
{let r:Fraction, g:Fraction, b:Fraction}
{let f:Fill = {Fill width=1cm, height=1cm, background="black"}}
{let t:Timer =
{f.animate
interval=0.1s,
repeat = 0,
{on TimerEvent do
set r = (r + 0.05) mod 1.0
set g = (g + 0.02) mod 1.0
set b = (b + 0.03) mod 1.0
set f.background = {Color.from-rgb r, g, b}
}
}
}
{let run-button:CommandButton =
{CommandButton label = "Start",
{on Action do
set t.repeat = 1000
}
}
}
{let stop-button:CommandButton =
{CommandButton label = "Stop",
{on Action do
set t.repeat = 0
}
}
}
{let faster-button:CommandButton =
{CommandButton
label="Faster",
{on Action do
{if t.interval > 0.03s
then
set t.interval = t.interval - 0.02s
else
set faster-button.enabled? = false
}
}
}
}
{let slower-button:CommandButton =
{CommandButton
label="Slower",
{on Action at slower-button:CommandButton do
set t.interval = t.interval + 0.02s
{if t.interval > 0.03s and not faster-button.enabled?
then
set faster-button.enabled? = true
}
}
}
}
{HBox
run-button,
stop-button,
faster-button,
slower-button,
{value f}
}
| |
Timer を作成してから、このプロパティのいくつかを設定できます。特に重要なプロパティは
repeat で、
Timer イベントが停止するまでに発生する回数を指定します。
repeat が 0 に設定されている場合、アニメーションは起こりません。-1 に設定されている場合は、アニメーションは永久に続きます。既定値は -1 です。次の例では
repeat を使用して、一度に 1 フレームまたは 10 フレームの速さでアニメーションを進めます。
例:
repeat 引数の使用 |
|
{let r:Fraction, g:Fraction, b:Fraction}
{let f:Fill = {Fill width=1cm, height=1cm, background="black"}}
{let t:Timer =
{f.animate
interval=0.1s,
repeat=10,
{on TimerEvent do
set r = (r + 0.05) mod 1.0
set g = (g + 0.02) mod 1.0
set b = (b + 0.03) mod 1.0
set f.background = {Color.from-rgb r, g, b}
}
}
}
{HBox
{CommandButton
label="Ten More Frames",
{on Action do
set t.repeat = 10
}
},
{CommandButton
label="Step (1 more frame)",
{on Action do
set t.repeat = 1
}
},
{value f}
}
| |
アニメーションの開始や停止には、repeat プロパティを使用できます。次に例を示します。
例:
アニメーションの開始または停止で repeat を使用 |
|
{let r:Fraction, g:Fraction, b:Fraction}
{let f:Fill = {Fill width=1cm, height=1cm, background="black"}}
{let t:Timer =
{f.animate
repeat = 0,
{on TimerEvent do
set r = (r + 0.05) mod 1.0
set g = (g + 0.02) mod 1.0
set b = (b + 0.03) mod 1.0
set f.background = {Color.from-rgb r, g, b}
},
interval=0.1s
}
}
{HBox
{CommandButton
label="Start",
{on Action do
set t.repeat = -1
}
},
{CommandButton
label="Stop",
{on Action do
set t.repeat = 0
}
},
{value f}
}
| |
after 式を使用して、アニメーションが始まる前に一定の時間待機させておくことができます。次に例を 2 つ示します。
例:
after を使用してアニメーションを遅らせる方法 |
|
{let r:Fraction, g:Fraction, b:Fraction}
{let f:Fill = {Fill width=1cm, height=1cm, background="black"}}
{let t:Timer =
{f.animate
repeat = 0,
{on TimerEvent do
set r = (r + 0.05) mod 1.0
set g = (g + 0.02) mod 1.0
set b = (b + 0.03) mod 1.0
set f.background = {Color.from-rgb r, g, b}
},
interval=0.1s
}
}
{HBox
{CommandButton
label="Start in 5 seconds...",
{on Action do
{after 5s do
set t.repeat = -1
}
}
},
{CommandButton
label="Stop right now!",
{on Action do
set t.repeat = 0
}
},
{value f}
}
| |
例:
after を使用してアニメーションを遅らせる別の方法 |
|
{let r:Fraction, g:Fraction, b:Fraction}
{let f:Fill = {Fill width=1cm, height=1cm, background="black"}}
{let t:Timer = {f.animate
interval=0.1s,
repeat=0,
{on TimerEvent do
{after 5s do
set r = (r + 0.05) mod 1.0
set g = (g + 0.02) mod 1.0
set b = (b + 0.03) mod 1.0
set f.background = {Color.from-rgb r, g, b}
}
}
}
}
{HBox
{CommandButton
label="Start in 5 seconds...",
{on Action do
set t.repeat = -1
}
},
{CommandButton
label="Stop in 5 seconds...",
{on Action do
set t.repeat = 0
}
},
{value f}
}
| |
要約: | - Timer はそれ自体で TimerEvent を発生させて、コード実行のタイミングを制御します。
- Visual.animate から Timer を取得した場合、Curl 言語が適当な時点で、その有効および無効の設定などの指定事項を処理します。
- Timer クラスを直接インスタンス化して Timer を作成した場合、タイマーの有効または無効はユーザーが設定する必要があります。
|
Timer はコード実行のタイミングを制御し、アニメーション製作には必須のツールです。
Timer はまた、指定の間隔または頻度でコードを実行する必要がある任意の状況で役に立つツールです。「
値を持たない新しいコントロール」のセクションでは、
Timer を使用して clock コントロールの時間表示を更新する例を示しています。
各タイマーは
Timer クラスによって表され、格納されているタイミング情報を使用してそれ自体で
TimerEvent を発生させます。
TimerEvent クラスは、
Timer オブジェクトで発生するタイマー イベントすべてを表します。
Timer はグラフィック オブジェクトではありません。したがってグラフィック階層を上に向かってイベントを発生し続けるグラフィック オブジェクトとは異なり、作成した場所には関係なくタイマー自身で
TimerEvent を発生させます。
Visual.animate から
Timer を取得する場合、引数として
Timer のプロパティの値を
animate に与えます。
Timer クラスを直接インスタンス化して
Timer を作成する場合、クラス コンストラクタが
Timer のプロパティを設定します。
次のリストにこれらのプロパティを示します。
- enabled? :true に設定すると、Timer が有効になります。Timer を無効にするには false に設定します。
- repeat :TimerEvent の発生回数。負の値 (既定) の場合、Timer が明示的に無効になるまで停止しません。Timer を無効にするには 0 に設定します。
- interval :最初の TimerEvent が発生する前の時間、および後続のイベントが発生する間隔。interval を設定すると frequency も設定されます。interval または frequency のいずれかを設定します。両方は設定できません。
- frequency :TimerEvent が発生する頻度。たとえば 10fps、1 秒間に 10 フレーム。frequency を設定すると interval も設定されます。interval または frequency のいずれかを設定します。両方は設定できません。
- when :Timer 発生の開始時間。
- delay :Timer 発生の開始前の遅延間隔。
- on-timer-event :このタイマーで発生するタイマー イベントのイベント ハンドラ。タイマーの発生時に実行されるコードは、このハンドラに記述することを推奨します。
各プロパティの詳細については、『API リファレンス』を参照してください。
Timer は、アクティブである限り発生します。
アクティブ タイマーの状態は次のとおりです。
注意: Visual.animate から
Timer を取得した場合は、
Visual で発生した
AttachEvent により
Timer が有効になります。したがって、このような場合は
repeat プロパティを
0 に設定してアニメーションを停止するようにしてください。
Timer.enabled? を false に設定するだけでは不十分です。その理由は、関連付けられている
Visual で別の
AttachEvent が発生すると、タイマーがすぐに有効になるからです。
Timer を
Visual.animate を使用せずに直接取得する場合、タイマーのアクティブ化とインアクティブ化を考慮に入れる必要があります。1 つには、アプレット、Curl 言語プロセス、およびスレッドに関連する
Timer の寿命です。
- 各アプレットは、それ自体の Curl 言語プロセスで存続します。
- 各 Curl 言語プロセスには 1 つまたは複数のスレッドがあります。
- 各スレッドはアクティブ タイマーのリストを保持します。
タイマーを明示的にインアクティブにしない場合、Curl アプレットが存続する限りタイマーも存在します。アプレットが消滅すると、関連する Curl 言語プロセス、関連するスレッドも消滅し、アクティブ タイマーのリストが消えます。アプレットがブラウザ内またはブラウザの履歴にある限り存続することに注意してください。
ブラウザ内ではなくブラウザ履歴でアプレットが存続している場合、
一時停止の状態にあると言えます。一時停止しているアプレットの状態は次のとおりです。
- タイマー イベントは発生しません (イベント ループのタイマーの段階)
- イベントを処理しません (イベント ループのイベントの段階)
アプレットが一時停止されているときは、アクティブなモーダル ダイアログは自動的にキャンセルされます。
アブレットが消滅するまでタイマーを発生させ続けるより、必要がなくなれば
Timer をインアクティブにすることをお勧めします。たとえば、ダイアログまたはアプレット領域の外側のビューで
Timer を作成すると、ビューを閉じても
Timer はインアクティブになりません。実際には、新しい
View を繰り返し作成した場合、複数の
Timer が作成されることになり、アプレットが消滅するまでこれらのタイマーはアクティブのままになります。
Timer が
Visual に関連づけられている場合、
DetachEvent のイベント ハンドラを
Visual に追加できます。このイベント ハンドラは
Timer を無効にできます。
Visual が
DetachEvent を取得したときに、関連する
Timer を無効するのがいいタイミングです。その理由は、この時点ではオブジェクトがグラフィック階層にはない、つまり表示されていないからです。
AttachEvent のイベント ハンドラを追加することもできます。
Visual が
AttachEvent を取得したときに、関連する
Timer を再度有効にすることができます。その理由は、この時点でオブジェクトがグラフィック階層にある、つまり表示されているからです。
次の例は、次のプロパティを設定したタイマーを示します。
例:
Timer イベント |
|
{CommandButton
width=5cm,
height=2.5cm,
label="Click and watch this space",
margin=5mm,
|| When the user clicks on it ...
{on Action at cb:CommandButton do
|| A timer is created that fires 3 times, at 1-second intervals
let t:Timer =
{Timer
interval=1s,
repeat=3,
|| When the timer gets the TimerEvent ...
{on TimerEvent do
|| the button's size is changed
set cb.width = cb.width + 1cm
}
}
}
}
| |
一度だけ発生するイベントの場合は、「
after の使用」で説明されている
after 式を使用します。
タイマーは、マシンによってはナノ秒に近い単位まで正確に時間を測定します。ただし、タイマーが開始したときにコンピュータが別のイベント処理で忙しい場合は、TimerEvent 処理がしばらく遅れることがあります。
注意: このような遅延のため、
Timer を使用してそれ自体で時間を測定することは推奨されません。
TimerEvent 間の正確な時間が必要な場合は、
TimerEvent 内の
DateTime クラスを使用して経過時間を取得することを推奨します。
「
タイマーのインアクティブ化」で説明されているように、必要がなくなってもまだアクティブ状態の
Timers は、システムのパフォーマンスを遅くする可能性があります。
アニメーションがプロセッサ時間を消費し、ドキュメントのスクロールや配置が遅くなる可能性があるため、アニメーションを含むアプレットはタイマーを無効にしてロードすることを推奨します。
簡単なアニメーションで計算があまり起こらないような場合は、安定したフレーム率で実行され残りのドキュメントも対応時間が遅くなりません。
発生したイベントは、一般的なイベント用の標準イベント キュー、タイマー イベント用のタイマー イベント キューに置かれます。
イベント ループにはイベント処理の順序が定義されています。イベント ループの各ラウンドには、2 つの段階があります。
- イベント ループの各ラウンドの第 1 段階では、現在イベント キューにある一般イベントがすべて順番に処理されます。
これらのイベントが処理されている間、新しいイベントが入ってくることがあります。
- 新しいタイマー イベントは、発生の予定時間とは無関係にタイマー キューに蓄積されます。
- 新しい一般イベントはイベント キューの最後に追加され、イベント ループの次のラウンドのイベント段階で処理されることになります。
- イベント ループの各ラウンドの第 2 段階では、現在の時刻で発生するようスケジュールされているタイマー イベントすべてが発生します。
タイマー イベントの発生中に新しいイベントが入って来ることがあります。新しいイベントは適切なキューに追加されますが、イベント ループのこのラウンドでは発生されません。
Copyright © 1998-2019 SCSK Corporation.
All rights reserved.
Curl, the Curl logo, Surge, and the Surge logo are trademarks of SCSK Corporation.
that are registered in the United States. Surge
Lab, the Surge Lab logo, and the Surge Lab Visual Layout Editor (VLE)
logo are trademarks of SCSK Corporation.