2015年4月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
無料ブログはココログ

« コピペシール、その(1) | トップページ | MOONPhase version up で、MyStickerID() の修正が必要に・・・ »

2013年12月 4日 (水)

これでどうだ。コピペシール、その(2)

前回暫定公開した「矩形コピペ」シールですが、開発を始める段階から、GUI 部分を切り離しておいて、「いつか」ペンで範囲指定できるようにしたいと考えていました。

ところが、開発中にあれこれ調べていると、Canvas に isPointInPath() というメソッド があることや、enchantMOON Developers のページ に、ペンイベントの使い方 が載っているのをみつけ、これなら何とかなるだろう、と平行して開発に手を付けました。(実は後述のような罠があったのですが)とにかく、ペン周りは後に回して、 cut / copy / paste 周りのロジックを優先し、前回のシールで動くようになったので、週末からひたすらコーディングしてはデバッグしてました。

動いても処理が重くて使い物にならないことも想定していたのですが、意外と許せる程度には快適に動きます。前回の「矩形コピペ」とそんなにパフォーマンスも変わらず、使い勝手は明らかにこちらが上なので、「矩形コピペ」シールは公開しないことにしました。資料として残しておくだけにします。

で、公開 : Download : 「手書きコピペ」シール

使い方:

  • シール台帳から画面に貼りつけます。
    • 動作選択ボタンが表示されます。
  • Cut/Copy の対象としたい領域をペンで囲みます。領域を囲む線(ストローク)は、きっちりと閉じてしまう必要はありません。C 字型のように、最後が開いていても、内部で自動的に閉じて扱います。むしろ最後がクロスしてしまう(∝字型のように)の方が、思わぬ動作をしてしまうかもしれません。
    • 囲み線を描き損ねてしまったら、"Retry" ボタンをタップしてください。ストロークが消去されて、一から書き直せる状態に戻ります。
    • 囲み線は、一気に書き上げてしまわなくても、点線のように飛び飛びで書けば、自動的に直線補完してつなぎます。一筆書きしかできません。(その方が処理が簡単なので)
  • 対象領域が決まれば、"Cut", "Copy" ボタンにタップします。
    • "Cancel" ボタンをタップすると、何もせずに戻り、シールも自分で剥がしてきれいに終了します。
  • "Cut", "Copy" で、対象領域のストロークをシールに拾い上げます。始点と終点の両方が領域内に含まれるストロークだけを操作対象としますので、囲み線と交差しているストロークは残ってしまう場合があります。
    • 操作対象のストロークを、元の位置のままシールに張り付けられればよいのですが、MOONPhase v.2.7.0 現在、script からシールの位置変更ができません。(Issue Tracker #117)
    • そのため、取り込んだストロークが元のシールの位置に移動しますが、ご容赦ください。
      シールを、張り付けたい場所に移動させます。
  • タップすると、"Paste", reset Cut", "Cancel" が選択できるようになります。"Paste", "Cancel" は、そのままです。"reset Cut" は、"Copy" でなく、"Cut" でストロークを取り出していた場合、そのストロークをページのストロークに戻します。
  • "reset Cut" するとシールは剥がれますが、"Paste" ではシールは剥がれません。したがって、複数回 "Paste" できます。用が済めば、明示的に剥がしてください。

できなかったこと

シール貼り付けの際、3 本指キャンセルすると、画面上に「透明の」シールが残ってしまいます。3 本指キャンセルは、問答無用でシールが終了しますので後始末もできず、現状では回避困難です。残ったシールをタップしても何もできないので実害はありませんが、キャンセルしたければ "Cancel" ボタンをお勧めします。

この件については、Issue Tracker #154 に投稿しておきました。

囲み線が細くて大変見にくいです。これは、MOONPhase ver 2.8.0 現在、Canvas の lineWidth がサポートされておらず、1 pixel 幅のラインしか引けないからです。

あと、何故だかしりませんが、ボタン表示にゴミがでます。ほとんど、Canvas.fillRect() で描いてるんですが、座標計算まちがってるのかなぁ?

妥協したこと

上述の、囲み線が細いという件、本気になれば回避方法はあるのでしょう。@ina_ani さんの「ペイントアプリ」 では、筆圧対応などもできているそうですから、太い線を引くこともできるはずなのですが、今回は手を出しませんでした。

また、MOON で普通に線を手書きすると、info.json には サブピクセル単位の分解能でストローク情報が格納されますが、あまり細かくなると、今回の目的にはオーバースペックになるばかりか、動作が遅くなりそうです。ですので、囲み線を書く際に、1 ピクセルより小さい移動は無視するようにコーディングしてあります。(必要なら、3 ピクセル飛ばしとか、5 ピクセル飛ばしとかできるように作ってあります)

結果として、「領域を指示するなら十分」という stroke data を取得する GUI になっていますので、「手書きの味のある線」は書けません。もっとも、今回はそんな機能はない方がよいと思いますが。

後はデザイン関係ですね。線の色、ボタンの色…。もっといい色があったら、rgbコードで教えて下さい。線の色と、ボタンの色は、内部で定数としてまとめて定義しているので、気に入らなかったら変えてください。

それと、ボタンセットを画面上でドラッグするための "drag" ボタン。今回書いたコードでは、ボタンの表示は「文字」しか使えないので、今のような表示になっていますが、本当なら、

Drag こんな感じ

にしたかったのですが。まあ、いつか手が回ったら。

いろいろ

まず、冒頭で書いた「罠」ですが。

Canvas に isPointInPath() というメソッド .があるのに気付いたので開発を始めたのですが、ある程度動くようになってからテストしても期待した動作をしない。よくよく調べてみると、なんと Canvas の isPointInPath() もサポートされていませんでした。

一旦諦めかけたのですが、閉曲線内外判定ルーチンくらいなら、頑張れば書けなくもない。しかし、今から数学の教科書を開かなくても、こういうのは既に定番があって、車輪の再発明をしなくても済むだろう、と検索しました。

最終的に参考にした(というより、そのままパクった)のは、このページ です。数学的には同じ内容をあちこちで見かけましたが、これは大変こなれたコードで、処理のほとんどが大小比較と boolean の一致比較です。掛け算・割り算の出てくる部分が最小限で、非常に計算強度の楽なコードです。

おかげで、部分適用みたいな回りくどい使い方をしているのに、そこそこのパフォーマンスが出ています。自力で考えていたら、まだできていないし、もっとパフォーマンスは落ちていたと思います。

そもそも、最初に、isPointInPath() がサポートされていないことに気づいていたら、今回のシールは作っていなかったでしょう。ほぼ出来上がりかけてから気付いたので、そのまま最後まで作り上げられました。怪我の功名でした。

なお、今回のシール、「コピペシール」なのですが、'reset Cut' 機能があるので、そのままで「UNDO のある、ストローク消去シール」としても使えます。UNDO 不要なら、ストロークデータをページから剥がしてそのまま MOON.peel() すれば即消去シールに改造できます。

長くなったので、コードと注釈・言い訳は、記事を別にして書きます。

« コピペシール、その(1) | トップページ | MOONPhase version up で、MyStickerID() の修正が必要に・・・ »

enchantMOON」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1527616/54139999

この記事へのトラックバック一覧です: これでどうだ。コピペシール、その(2):

« コピペシール、その(1) | トップページ | MOONPhase version up で、MyStickerID() の修正が必要に・・・ »