« 2012年4月 | トップページ | 2012年6月 »

2012年5月

2012年5月30日 (水)

タッチパネルはよく解らん -4-

タブレット上の FlatTable 動作状況を報告します。

タブレット上の FlatTable には次の問題が見られました。

  • 球が小さくてタップが困難
  • 画面拡大・縮小が誤動作することが有る
  • ドラッグの応答が鈍い
  • テキストの寸法を取得できない
  • テキストのメニューが表示後すぐに消える
ここに、テキストとは FlatTable 上で作成・表示する文字列のことです。

それでは、各問題について説明します。

球が小さくてタップが困難

球が小さいため、タップミスが頻発しますが、指の先端で触ろうとしても上手く行きません。画面をタップした時、指の接触する部位は意外に内側に有ります。このことを意識して何度かタップを繰り返すうちに、打率は上がって来ます。

そうは言っても、PCのマウス・クリックが確実なのに比べたらタップミスはかなり多いと言えます。そこで、確実にタップするために一時的に画面を拡大するという方法が有ります。なお、画面を拡大して球をタップすると、拡大画像の上に元の大きさの画像が重なって表示されるという問題は有りますが、その後、画面をスクロールすれば、拡大画像は消えて、元の大きさの画像だけが残ります。

画面拡大・縮小が誤動作することが有る

画面の拡大・縮小を繰り返していると、その機能が誤動作することが有ります。その場合は、ダブルタップを何度か行えば、元の大きさの画面になり、拡大・縮小機能が復帰します。

ドラッグの応答が鈍い

ドラッグの動きが、PCに比べると信じられないほどギクシャクしています。タブレットと言うものは、こんなにも CPU 能力が低いのでしょうか? そうは考えられないので、タブレットならではの問題なのかなぁと思っています。例えば、指で操作しているので分解能が悪いとか、意図的に応答を鈍く設定しているとか・・・。

とにかく、これでは使い物にならないので何らかの改善を実施することにします。

テキストの寸法を取得できない

SVG のテキストの長さ(文字数ではなくて寸法のこと)は、

    textLength.baseVal.value
で取得できることが、Chrome のデバッグ機能により判っていました。しかし、どうもタブレットには対応していないようで、正しい長さを知ることが出来ません。そのため、テキスト作成直後のテキスト枠線は正しく表示できません。仕方無く、タブレットではテキスト作成直後は枠線を表示しないことにしました。また、同じ原因で、テキストのメニューの [ Fit Width ] も正しく動作しません。仕方無く、タブレットでは [ Fit Width ] は非対応にしました。

この不具合は、「タブレットが・・・」と言うよりも「私のタブレットのブラウザが・・・」と言うべきなのかも知れませんが。

テキストのメニューが表示後すぐに消える

配置図例 テキストをクリックすると、そのテキストに重なるようにしてメニューが表示されますが、タブレットでは、そのメニューが一瞬表示されてすぐに消失します。これは、タップした位置にメニューが表示されるため、メニューがテキスト・タップのイベントに反応しているのが原因と思われます。実際、メニューを離れた位置に表示させると、この不具合は発生しません。そこで、タブレットでは、テキストに対するメニューの表示を 400ms 遅らせることにしました。これでメニューの消失は無くなりました。因みに、300ms では不充分でした。

----

タブレットで動くソフトを作るためには、タブレットが必要でしたね。

ここまでの動作およびコードは、本ブログのサイドバー「Link」の「SVG+JavaScript 版 FlatTable の試作品」で確認できます。

2012年5月27日 (日)

タブレットを買った

知り合いのタブレットで FlatTable の動作確認をして、タブレットでは不具合の有ることが判った訳ですが、こうなったらタブレットを買って FlatTable をチューニングしなければなるまいと思い、遂にタブレットを買って来ました。目的は FlatTable のチューニングな訳なので、インターネットに接続する必要は無いと思い、本体だけの購入です。PC内の FlatTable ファイルをUSBか何かでタブレットに持って来て、それをウェブ・ブラウザで表示すれば良いと考えました。

ファイルをタブレットにコピーするのはすぐに出来たのですが、次の段階で躓きました。ウェブ・ブラウザ(Chrome)でどうやってローカルファイルにアクセスするのか? Chrome にはローカルファイル一覧機能が有りません。仕方無いので、ファイルマネージャでパスを確認してアドレスバーに直接入力しました。しかし FlatTable は表示されません。パスを間違えているのでしょうか? 仕方無いので、ファイルマネージャで FlatTable のファイルをタップしたら HTML-Viewer で表示されました。しかし、この HTML-Viewer は JavaScript に対応していないのか、画像を表示したところで止まって、JavaScript 部分を実行しません。

ローカルでの実行は出来ないという結論に至りました(何か方法が有るのかも知れませんが)。インターネットにアクセスするしか有りません。

WiFi の電波を調べたら10個程この界隈を飛び交っているのが有りました。そのほとんどどれもがパスワード必須ですが、1つだけ、パスワード無しで接続できるのが有りました。FON-FREE-INTERNET です。ユーザー登録が必要なのでそれをして、5分か10分ほどインターネットを使ったところでアクセス出来なくなりました。何度トライしてもログイン画面が出るだけです。やはり、ルーターを買わないとダメなのでしょう。

タブレット画像

翌日、電気屋へ行ってルーターを物色していたら、ルーターではありませんが、PCに取り付けてアクセスポイントにする装置を見つけました。それを買って来て、その装置に対してタブレットでアクセス。

接続は出来るのですが、肝心のインターネットには繋がりません。それはそうでしょう。タブレットにはプロバイダーへのログイン設定をしていないのですから。しかし、設定方法が分かりません。

PCのネットワーク設定を調べてみると、PCのインターネット接続を他の端末で共有するように出来ることが分かりました。その設定にして、やっとタブレットでインターネットにアクセスすることが出来ました。

そして、FlatTable の実行内容は、もちろん、知り合いのタブレットで実行したものと同じ訳ですが、詳しくは、また後ほど。

2012年5月22日 (火)

タッチパネルはよく解らん -3-

「携帯端末では navigator.userAgent に文字列 Mobile が入っている」という件ですが、今回参考にしたサイトで言っている「携帯端末」を誤解していました。「携帯できる端末」だからスマートフォン、タブレット両方を指しているのかと思ったら、スマートフォンだけを言っていました。つまり、「Mobile」が入っているのはスマートフォンだけのようです。他のサイトによると、スマートフォンおよびタブレットには

    Android, iPhone, iPad
のどれかが入っているそうです。

そういうことで、端末の判別ルーチンを修正して、やっとタブレットでの動作確認が出来ました。しかし、動作確認の結果は非常に不満足なもので、次の2点の不具合が判明しました。

  • 球が小さ過ぎてクリックできない
  • 球をドラッグする時、動きが滑らかでない

スマートフォンだと球が小さくてクリックできないかも知れないという予想は有りましたが、タブレットでも小さ過ぎるとは思いませんでした。一応、画面を拡大することでクリックできるようにはなるのですが、クリック直後に、拡大された画像の上に元の大きさの画像が重なって描画されてしまいます。
配置図 一応、画面をフリック(←クリックではない)すると拡大画像は消えて元の大きさの画像だけが残りはします。しかし、時には、元の画像は画面の外に行っており、それに気付かないことも有って使い物になりません。クリック処理ルーチン内で preventDefault() を実行しているのですが、これが原因で再描画しているのでしょうか?

もう1つの問題は、ドラッグです。球の動きがカクカクで滑らかではありません。CPU の能力不足ということが有るのでしょうか? 少なくとも、PCでは何の問題も無く動いています。

タブレットを購入して FlatTable をチューニングしないと使い物にならないでしょう。タブレットでさえこのザマですから、スマートフォンに至っては何をか言わんやでしょう。なんか、やる気が失せて来ました。

2012年5月18日 (金)

配置コード機能の実装 -1-

FlatTable の2つの大きな山のうち「配置コード処理」の実装を開始することにします。配置コードは、その名の通り配置を示すコードで、URL のクエリ(URL の "?" 以降の部分)に付けて FlatTable にアクセスすることで配置図を再現するものです。FlatTable は配置図をただの画像として扱うのではなく、配置コードを指定して FlatTable にアクセスすることで配置図を表示するのが本来の使い方なのです。

まず、配置コードの仕様の概略を説明します。

配置コードは次の要素で構成されます。

  1. ttl=タイトル
  2. ILC=初期配置コード
  3. cmtn =テキスト
ここに、タイトルとは FlatTable 上部に表示する文字列のことです。これは必須ではありません。ILC は Initial Layout Code の略です。テキスト は配置図内に任意に作成する文字列です。数に応じて n には数字が振られます。Flash 版の作成時には、配置図内文字列をコメントと呼んでいたので、cmt という名前になっています。配置コードはクエリなので、これらの要素は & で繋がっています。

初期配置コードは、次の要素で構成されます。

  • 特性付け(2桁の数字)
    • FlatTable 全体に対する特性付け(1x)
    • ページに対する特性付け(2x)
    • 球に対する特性付け(3x)
  • 球の種類(アルファベット1文字)
  • 球の座標(アルファベット4文字、例外有り)
  • ページのデリミタ(.)

球の種類を表す文字は次のようになっています(プールの場合)。


 球 :cue 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15   comment
記号: P  Q  R  S  T  U  V  W  X  Y  Z  p  q  r  s  t・・・z

球の座標はX座標、Y座標各2文字のアルファベットとしてコーディングされます(座標値0は例外的に 00 となります)。座標のコーディングに関しては FlatTable Inside - 論理座標と物理座標を参照してください。

各ページの配置コードは「.」(ピリオド)で終端されます。これにより、複数ページの配置を扱うことが出来ます。

配置コードの例およびそれに対応する配置図を以下に示します(配置図はコードを Flash 版 FlatTable に実際に適用して表示しています)。

http://spacelike.in.coocan.jp/flat/FlatTable_P.swf?ttl=SAMPLE&
ILC=21Q0000KeuyPfTKiaYAr.

2012年5月14日 (月)

タッチパネルはよく解らん -2-

携帯端末はマウスが無いのに、何故 mouseover のイベントを発行するんですか? そんなこと知らないものだから、mouseover のイベントで携帯端末とPCを判別しようとしたじゃないですか!

mouseover のイベントハンドラーに

    alert("Yes, Mouse driving!");
を仕込んでおいて、タブレットで FlatTable の試作品にアクセスしたら、ガッツリ alert が表示されたじゃないですか!

仕方ないから、他の方法で判別することにします。携帯端末では navigator.userAgent に文字列 Mobile が入っているそうなので、これを使うことにします。

今度こそ、うまく行きますように!

タッチパネルはよく解らん

タブレットは持ってないので知り合いのタブレットで FlatTable の動作確認したところ、球をドラッグ出来ないことが判明しました。タッチパネルでは mousedownmousemove の代わりに touchstarttouchmove を使わないといけないことは分かっているので、そうしているのですが、まだ何か問題が有るようです。

そこで、家に帰ってから、PCのタッチパネル機能を使ってあれこれ動作確認してみました。

因みに、球のドラッグは次のイベント・シーケンスに従って実行されます。

touchstart --> touchmove --> touchend
              ↑_______↓

次のような現象が確認できました。

  • タッチしてすぐに指を動かすとイベント(touchstart, touchmove)は発生しない
  • タッチしてすぐに離すとイベント(click)が発生する
  • タッチして1秒程度待つとイベント(touchstart)が発生し、更に指を動かすとイベント(touchmove)が発生する
画面スクロールの時は、タッチしてすぐに指を動かしても画面が反応するので、上記で反応しないというのは、アプリケーションにはイベントが届かないということなのでしょう。それは、システムが click を検出するために touchstarttouchmove のイベント通知を鈍らせているのでしょうか?

もう1つ、次のことも確認できました。

FlatTable では、次のコードでタッチパネルの検出を行っています(有効性の確認は出来ていません)。

// タッチパネルの検出
var fTouchPnl = true;
var mouseDown = "touchstart";
var mouseMove = "touchmove";
var mouseUp = "touchend";

addEvent(flattable, "mouseover", yesMouse);

function yesMouse(){
    fTouchPnl = false;
    mouseDown = "mousedown";
    mouseMove = "mousemove";
    mouseUp = "mouseup";
    removeEvent(flattable, "mouseover", yesMouse);
}
タッチパネルの検出と言うよりも、マウスの検出と言うべきでしょうか。このコードは、「もしマウスが有ればマウス用のイベントを検出し、マウスが無ければタッチパネル用のイベントを検出せよ」ということです。

このコードで、yesMouse() の最初の箇所に alert() を置いてみたところ、次のことが分かりました。

  • 開始してすぐに mouse を画面に乗せた時、yesMouse() は1回だけ呼ばれる
  • 開始してすぐに(mouse は乗せずに)画面を touch した時、yesMouse() は3回呼ばれる
訳解りません。

2012年5月11日 (金)

ページの合成 -2-

FlatTable のページ合成機能の実装が終了しました。

ページが複数の時は、台の右横に合成指定・表示ボタンが表示されます。ボタンは縦2列に並んで、左側は現行ページが合成するページを指定するボタン、右側は現行ページを合成しているページを表示するボタン(表示だけだからボタンではないですが)です。左側のボタンをクリックすると、そのボタンは緑色になり、それに対応しているページが合成表示されます。再度クリックすると合成は解除されます。右側のボタンで緑色になっているのは、それに対応しているページが現行ページを合成していることを表しています。現行ページのボタン [ CUR ] を中心にして、上はページ番号が増加する方向、下は減少する方向を示しています。

配置図 図に表示されている1~9番の球は、それぞれ1~9ページに配置されたものです。現行のページは5ページ目になっており、ボタンに示されているページを合成しています。3ページ目と8ページ目は合成していません。また、2ページ目は現行ページ(5ページ目)を合成しています。現行ページを2ページ目にすれば、2ページ目の配置に5ページ目を合成したものが表示されることになります。

この合成の状況は各ページの変数 peepAt および peepBy で管理しています。この変数の下位4ビットは前方(ページ番号が増加する方向)の合成を表すフラッグで、上位4ビットは後方(ページ番号が減少する方向)の合成を表すフラッグです。

新しいページを生成した時の peepAt および peepBy の処理ルーチンを示します。ここに curPage は現行ページです。

// 新ページ追加時のビット処理
function ppShiftIns(){
    shiftFlag(curPage, 15, true);    // (1)

    var i;
    var page;
    var mask;

    for (i = 1, page = curPage.prev, mask = 1;    // (2)
        (i <= 4)&&(page != curPage);
        mask |= (1 << i++), page = page.prev)    // (3)
    {
        shiftFlag(page, 15 - mask, true);    // (4)
    }
    for (i = 1, page = curPage.next;    // (5)
        (i <= 4)&&(page != curPage);
        i++, page = page.next)
    {
        shiftFlag(page, (15 << 4), true);
    }
}

function shiftFlag(page, mask, fAdd){
    var flagAt;
    var flagBy;
    if (fAdd){
        flagAt = (page.peepAt & mask) << 1;
        flagBy = (page.peepBy & mask) << 1;
    } else {
        flagAt = (page.peepAt & mask) >> 1;
        flagBy = (page.peepBy & mask) >> 1;
    }
    flagAt &= mask;
    flagBy &= mask;

    page.peepAt &= ~mask;
    page.peepAt |= flagAt;

    page.peepBy &= ~mask;
    page.peepBy |= flagBy;
}
新しいページは現行ページとその次のページの間に挿入されます。従って、現行のページから見て前方のページは1つずつ遠くにズレます。その処理は (1) で実行されています。15 は下位4ビットのマスクです。他のページについてもビット処理をします。それが (2) および (5) です。(2) は現行ページよりも若い番号のページに属している変数 peepAt および peepBy の処理です。それらのページが新ページ挿入で影響を受けるのは現行ページよりも番号の大きい方向なので、それより手前に関しては現状のビットは維持することになります。それが (3) の
    mask |= (1 << i++)
および (4) の
    15 - mask
で実現されています。ppShiftIns() では、この箇所がキモで、実はここで手こずっていたのでした。

--------
ここまでの動作およびコードは、本ブログのサイドバー「Link」の「SVG+JavaScript 版 FlatTable の試作品」で確認できます。

2012年5月 6日 (日)

ページの合成

連休の後半は FlatTable のページの合成機能の実装をしていました。FlatTable は複数の配置図(ページと呼んでいる)を扱えますが、それらの配置図を1つの画面に合成して表示することが出来ます。それがページの合成機能です。

配置図

FlatTable では、1つのページに表示できる基礎球は各種類1個づつですが、時には同じ基礎球を複数表示したいことが有ります。そのような時にページの合成を利用します。添付図では2つのページを合成して2個の手球を表示しています。楕円で示されている部分は、合成を指定したり、合成の状況を表示しているボタンです。

この機能は Flash 版で既に実装しているので、コピペして SVG+JavaScript 用にチョチョイと修正すれば良いだろうと思っていたのですが、忘れている部分も少なくなく、内容を把握するのに時間が掛かりました。さらに、素直に移植するだけにしておけば良いものを、改良も加えようなどと企てたものだから、デバッグの泥沼でもがいています。この機能の9割は出来ているのですが、あと少しのバグが取れていません。

合成の状況は各ページに2つのフラッグを持たせて管理しています。1つは他のページを合成するフラッグ、もう1つは他のページに合成されるフラッグです。

フラッグの種類上位4ビット下位4ビット
他を合成するprev 方向next 方向
他に合成されるprev 方向next 方向

ビットの位置は現行のページからの距離(何ページ目か)を表しています。ページの前後それぞれに4ビットが振られているので、前後各4ページまで合成が可能です。これらのフラッグを、ページの移動や作成・削除などの操作に合わせてビット単位で処理します。

集中力が無くて、10分コーディング・50分息抜きというようなペースでやっているものだから、長い連休中に合成機能の実装を終わらせることが出来ませんでした。合成機能の後にはもっと大きな山が待っています。まだまだ移植は続きます。

--------
ここまでの動作およびコードは、本ブログのサイドバー「Link」の「SVG+JavaScript 版 FlatTable の試作品」で確認できます。

2012年5月 1日 (火)

SVG コードの手直し(または Inkscape 恨み節)

FlatTable の移植で次に予定している作業は手間がかかりそうなので、ちょっと寄り道をして SVG コードの手直しをしました。この手直しもいつかはやらないといけなかったので、それを先にやっただけなのですが。

まず始めたのはコードのダイエットです。FlatTable の画像は Inkscape で作成したのですが、以前に書いたように、座標が使い物にならず手直ししたことが有りました。今回は、Inkscape の生成していたコードで、

    fill-opacity:1
など意味の無い箇所を削除しました。これらに意味が有ることを私が知らないだけなのかも知れませんが、削除しても見た目が変わっていないので、たぶん意味が無いのでしょう。

それに続いて Inkscape 由来のコードも削除しました。Inkscape の生成するコードには Inkscape 由来の属性などが挿入されています。これは Inkscape で作業する時に必要となるのでしょうが FlatTable ではもうこの画像を Inkscape で処理することは無いだろうから、ダイエットのために、それらも削除しました。本来なら、Inkscape に敬意を表してそれらの箇所は残すところなのですが、あんなバカソフトに対してそんな気持ちには成れません。また、改変が禁止されていないか気になりますが、ソフトの性格上、SVG コードの手直しが許されない訳は無いので、たぶん大丈夫でしょう。

さらに、円から円への修正(変な言い方!)も行いました。Inkscape で円を描いても、生成されるコードは path ですが、これを circle に変更したということです。

    使用前
    <path
        style="fill:#666666;fill-opacity:0.6;stroke:none"
            id="path3969-3-3"
            d="m 332.274,146.81255 a 3.8082979,3.8082979 0 1 1
                -7.6166,0 3.8082979,3.8082979 0 1 1 7.6166,0 z"
            transform="matrix(0.525169,0,0,0.525169,331.5,147.8986)" />
    使用後
    <circle
        style="fill:#666666;fill-opacity:0.6;stroke:none"
        cx="504"
        cy="225"
        r="2" />
このコードを見ても判る通り、「使用後」の方はスッキリスリムで、その円はどの位置に有りどれだけの半径なのかがすぐに分かります。一方、「使用前」は、位置も半径もサッパリ分かりません。そもそも、これが円であることもすぐには分かりません。さらに、以前にも書いた「変換」が使用されています(transform)。

因みに Inkscape で円を描くことは出来ません(たぶん)。「私が知らないだけかも」と思って、試しに Ctrl キーや Shift キー等を併用して楕円描画の操作をしてみたのですが、楕円しか描けませんでした。たぶん、円は描けないのでしょう( Ctrl キーを押しながら±45°付近の方向にドラッグすると円になります)。そして、その楕円は ellipse ではなくて path でした。何故なんだ!?

最後にラック部分の三角枠線を修正しました。今までの三角枠線は小さかったので少し広いものに描き替えました。Inkscape で上手に正三角形を描く方法が分からないので、SVG コードを手動計算しました。三角枠線は純粋な三角形ではなくて頂点が丸まっていますが、その計算と描画に煩わされました。そのカーブを初めは円弧で描いたのですが、形が良くなかったので、2次のベジェ曲線に変更しました。ただ、円弧よりも2次のベジェ曲線の方が座標の指定が単純なので反って好都合でした。

配置図例

Inkscape は FlatTable で扱っているような製図的な画像の作図ではなくて、絵画的なものの製作を意図して作られているのかも知れません。そうだとすれば、違う用途に使っているので不満に思うのも当然です(つまり、Inkscape に罪は無い)。因みに、今更ながら思うのですが、製図的な作図の場合 XML エディタで SVG コードを直接編集するのが Inkscape の正しい使い方なのかも知れません。

« 2012年4月 | トップページ | 2012年6月 »