現在進行形の「うまくいってない」メモ。
とにかく「ダメな状態」なのでソースコード管理としてリビジョン管理してるけどコミットは出来ない「試行錯誤」を、メモの形で貼り付けときたいな、という読者には迷惑な話。
とにかく全然意味不明なんだけれど、今のところわかっていること:
- cy.center() は最も一般的なニーズの振る舞いとは違うらしい。
- cy.fit() と限りなく似た振る舞いをする。
- ふつーはノードを中心に持ってくんではねーの?
- となれば、と、仕方なく cy.panBy() と cy.extent() で動かそうとするも…。なんか凄くヘン。
1つ目を「そういうもんだ」と諦めるつもりで「許容出来る」として忘れることが出来るとしても、その代替実装をすんなり書けないのが困っているんであるよ。
こういうコードを書いた:
1 var target_ele = ...; // ターゲットのノード (実際は cy.elements("node") で取って来たノード一つ)
2 var pos = target_ele.position();
3 var extent = cy.extent();
4 var center = {
5 x: extent.x1 + extent.w / 2,
6 y: extent.y1 + extent.h / 2
7 };
8 var vec = {x: center.x - pos.x, y: center.y - pos.y}; // pos -> center のベクトル
9 cy.panBy(vec);
最初「全くダメじゃん」なちょっとというにはズレ過ぎの位置に移動して、うーん、と思ってしばらく操作してて、あることに気付いた。
「何度も上のコードを実行し続ける(つまり作った UI のボタンを押し続ける)と、少しずつ正しい位置に収束していく」。なんぢゃそりゃぁ、ということなのだが、それだけでもないのが困っておってな。どうもレイアウト依存なの。「実行し続ければ収束する」のは grid、random、spread (と多分 preset も) で、ほかは「ぶっ飛んだまま返ってくることはない(永遠に収束しない)ということで、なので「だったら繰り返せばええんか」:
1 var target_ele = ...; // ターゲットのノード (実際は cy.elements("node") で取って来たノード一つ)
2 var pos = target_ele.position();
3 for (var _i = 0; _i < 1000; ++_i) {
4 var extent = cy.extent();
5 var center = {
6 x: extent.x1 + extent.w / 2,
7 y: extent.y1 + extent.h / 2
8 };
9 var vec = {x: center.x - pos.x, y: center.y - pos.y}; // pos -> center のベクトル
10 cy.panBy(vec);
11 }
なこれは、grid、random、spread (と多分 preset も) にしか通用しない、ということ。
なんなんだそれ。
ほかの pan 系もこないだ試して全然言うこと効いてなかったし zoom 系も同様なんだけど、それらの「どううまくいってないか」はまだ整理出来てない。
うーん、解決出来るんであろうか、これ。
03:50追記:
「節穴だった、解決した」と言えれば良かったんだけれど、解決には至らず。が、節穴は節穴に違いない。
#notation/position に model position と renderd position について説明されてることを見落としていた。間違いなくこれが関係している、ということだけはわかった。でもね…、わからんのよ、要するに両座標系の変換を cy.zoom() を参照して計算するとか node.renderedPosition() を使え、とかそういうことなはずなんだけどね、そこは多分そうなんだけどね、頭こんがらがっちゃって。
2018-01-23追記:
やっと解決した。本当はめちゃくちゃ単純な話だった、ということが読めばわかる…、がちょっと長いか? 正しくしたコードを引用しとく:
1 var target_ele = ...; // ターゲットのノード (実際は cy.elements("node") で取って来たノード一つ)
2 var pos = target_ele.renderedPosition();
3 var center = {
4 x: $(cy.container()).width() / 2,
5 y: $(cy.container()).height() / 2
6 };
7 var vec = {x: center.x - pos.x, y: center.y - pos.y}; // pos -> center のベクトル
8 cy.panBy(vec);