Hatena::ブログ(Diary)

_development, RSSフィード Twitter

2013-09-08

enchantMOONのストロークをラスタライズするライブラリをつくった


概要

enchantMOONストロークを操作するシールを作ろうとすると困ることがあります。それはレンダリングされたストロークを取得する手段がないことです。例えば、ページに描いた絵をアニメーションさせたり、範囲選択したストロークドラッグさせたり、といったことを行うにはラスタライズされたストロークが必要になります。現状、enchantMOONにはそのようなAPIがありません。じゃあつくるか...、できたよ...というお話。


enchantmoonstrokes的なデモ

D


ストロークをアニメーションさせるデモ

D


画面が赤っぽいのは、ぼくんちの蛍光灯が白熱灯色だからですね。どうでもいいですね。


ストロークをアニメーションさせるデモで使ってるシール

  1. 下記リンクからシールダウンロードする
  2. シールを適当なページ(ブランクのページがよい)に貼り付ける
  3. あまり大きくない、アニメーションさせたい絵を描く
  4. 動かしたい軌跡を一筆で描く(最後に描いたものが軌跡として認識されます)
  5. シールをタップする
  6. シールが軌跡に沿って動いたあと、絵は軌跡の最後の位置に移動し、軌跡のストロークが除去されます。

>>ストロークをアニメーションさせるデモで使っているシール





このライブラリの経緯について

基本的には過去エントリ「enchantMOONのストロークをTwitterに投稿するシールを公開しました」でCanvasへのレンダリングはできていました。このプログラムは当初、CanvasのlineToメソッドストロークを描画していました。しかし現行(2.5.0)のenchantMOONCanvasはlineTo、というかパスを扱うメソッドが軒並み使えません。というわけで、enchantMOONに移植するのはfillRectあたりで線を書くしかなく、めんどくさいので放置していました。

しかし、上述のプログラムレンダリング結果がなんだかenchantMOON実機と異なるので調べて「なんかうまくいかねーなー」的にぼやいていた(enchantMOONのレンダリングを調べてみた)ところ、enchantMOONの開発元であるUEIの清水さんから以下のようなmentionが。

そこでレンダリングの実装を、スプライン補間した座標にfillRectで埋めていくように変更したところ、かなりenchantMOONの実機に近づきました。そういうわけでlineToが使えなくてもできるようになったので、移植をはじめ(例によってブラウザで動いてるのをそのまま持ってきても動かなかった)、この度、ある程度動くようになった次第です。


使い方

  1. enchantMOON/enchantmoon.strokeクローンする
  2. lib/drawStroke.jsをシールのlibディレクトリなどにコピーしてimportJSを呼び出すなどしてインクルードする
  3. Strokes.drawStroke()メソッドを呼び出す

パラメータ

Strokes.drawStrokes()メソッドパラメータを説明します

Strokes.drawStrokes(paperJSON, canvas, opts)

paperJSON

MOON.getPaperJSON()で得られるオブジェクトを指定します。一部範囲のみをレンダリングしたい場合は呼び出し側で編集しておく必要があります。


canvas

レンダリングの対象になるCanavsオブジェクトを指定します。

以下は、Canvasを生成してdrawStrokes()メソッドを呼び出す例です。

var backing = MOON.getPaperJSON(MOON.getCurrentPage().backing),
    div = window.document.createElement("div"),
    canvas = window.document.createElement("canvas");

canvas.width = backing.width;
canvas.height = backing.height; 

window.document.body.appendChild(div);
window.Strokes.drawStrokes(backing, canvas);

opts

レンダリングオプションを指定する、省略可能なパラメータです。

殆どのオプションenchantmoonstrokesの再生速度とかの変え方と同じです。

例えばfpsとunitを指定する場合は以下のようにします。


window.Strokes.drawStrokes(backing, canvas, {fps: 15, unit: 512});

callback

optsにはコールバックが指定できます。コールバックはレンダリングが完了した際に呼び出されます。


window.Strokes.drawStrokes(backing, canvas, {callback: function(rect){
    console.log("描けたよ");
}});

コールバックの引数には、レンダリング範囲を囲む矩形範囲を表すオブジェクトが渡されます。このオブジェクトには、矩形範囲を表す左、上、右、下の座標が格納されています。

例えば以下のようなオブジェクトが渡された場合、画面の左100px、上200px, 右300px, 下400pxに囲まれた矩形範囲をレンダリングしたことを表します。これらの値は、引数として渡されたストロークの各点のX座標、Y座標のなかから、それぞれ最も左、最も上、最も右、最も下のものに、その時点での筆圧を加味した線の太さを加算して計算されます。

{
    l: 100,
    t: 200,
    r: 300,
    b: 400
}

サンプルコード

サンプルコードは同じリポジトリの以下の場所にあります。シールの中身は上記のストロークをアニメーションさせるデモ用のシールと同じです。

enchantMOON/enchantmoon.stroke/example


GitHubリポジトリ

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証