カーソルを追いかけるイメージ
前回カスタムカーソルを作ったことの続き。
せっかくカーソルを変えたので、よくあるカーソルを追いかけるイメージというのを JavaFX でも作ってみようと思います。
ここではマウスが移動するイベントを拾って、その都度シーケンスに挿入して、古いものは捨てるということをやっています。
ようするにシーケンスの先頭は現在のマウスの位置、次が 1 つ前のイベントの時のマウスの位置、次が 2 つ前のイベント時のマウスの位置、というようになっています。
で、そのシーケンスをイメージの位置と同期 (つまり bind です) させてしまうというものです。
後は領域から出た時にイメージを非表示にして、領域に再び入ったら表示して、かつ位置も初期化するということをやってます。
完成品が右のイメージ。一番大きい Duke がマウスカーソルです。
import javafx.application.Frame; import javafx.application.Stage; import javafx.scene.Cursor; import javafx.input.MouseEvent; import javafx.scene.geometry.Rectangle; import javafx.scene.image.ImageView; import javafx.scene.paint.Color; import java.awt.Dimension; import java.awt.Point; import java.awt.Toolkit; import java.lang.System; import java.net.URL; import javafx.scene.image.Image; var cursor: Cursor = Cursor { awtType: java.awt.Cursor.CUSTOM_CURSOR awtCursor: { var toolkit:Toolkit = Toolkit.getDefaultToolkit(); var image: java.awt.Image = toolkit.getImage(new URL("{__DIR__}duke0.gif")); toolkit.createCustomCursor(image, new Point(8, 0), "MAGNIFIER"); } }; // とりあえず、見えそうもない場所に設定 var previousX: Number[] = [-10000, -10000, -10000, -10000, -10000]; var previousY: Number[] = [-10000, -10000, -10000, -10000, -10000]; // それぞれのイメージの位置は (previousX[i], previousY[i]) に bind // previousX[0], previousY[0] は現在の位置なので使用しない var images: ImageView[] = [ ImageView { x: bind previousX[4] y: bind previousY[4] image: Image { url: "{__DIR__}duke4.gif" }, }, ImageView { x: bind previousX[3] y: bind previousY[3] image: Image { url: "{__DIR__}duke3.gif" }, }, ImageView { x: bind previousX[2] y: bind previousY[2] image: Image { url: "{__DIR__}duke2.gif" }, }, ImageView { x: bind previousX[1] y: bind previousY[1] image: Image { url: "{__DIR__}duke1.gif" }, }, ]; Frame { title: "CursorSample" width: 200 height: 200 closeAction: function() { java.lang.System.exit( 0 ); } visible: true stage: Stage { content: [ Rectangle { cursor: cursor x: 10, y: 10 width: 160, height: 140 fill: Color.AQUAMARINE onMouseMoved: function(event: MouseEvent) { // x 座標をシーケンスの先頭に追加 // 最後を削除する var x = event.getX(); insert x before previousX[0]; delete previousX[5]; // y 座標も同じ var y = event.getY(); insert y before previousY[0]; delete previousY[5]; } onMouseExited: function(event: MouseEvent) { // マウスカーソルが領域から出たら、イメージを非表示にする for (images in images) { images.visible = false; } } onMouseEntered: function(event: MouseEvent) { // マウスカーソルが領域に入ったら、イメージを表示する for (images in images) { images.visible = true; } // 領域に入った場所でシーケンスを初期化 var x = event.getX(); previousX = [x, x, x, x]; var y = event.getY(); previousY = [y, y, y, y]; } }, images ] } }