/MEGAMOJI

Create animoji easily

Primary LanguageJavaScriptOtherNOASSERTION

http://zk-phi.github.io/MEGAMOJI

開発者向け

新しいアイデアや新しいクソアニメを実装したらぜひ PR ください!

環境構築

生 js で書いているので、サーバーを立てたりビルド環境を作ったりは特に要りません。 git clone して index.html を開いてください。

GIF アニメエンコーダーを submodule で使っているので、動く絵文字を試したい場合は clone したあとに、 git submodule update --init もしてください。

===

「パーツから選ぶ」は file:// プロトコルだと (CORS できなくて) 動かないことがあるので、上手くいかないときは適当なローカルサーバーを立ち上げてみてください。

ディレクトリ構成

  • assets/ … 「パーツから選ぶ」で使用するパーツ画像が入っています
  • css/
  • fonts/ … web font が入っています。読込みは css/fonts.css でやっています
  • imgs/ … ドキュメントで使う画像が入っています
  • js/
    • animations.js … アニメーションの実装が入っています。詳細は以下
    • effects.js … エフェクトの実装が入っています。詳細は以下
    • filters.js … フィルタの実装が入っています。詳細は以下
    • ga.js … google analytics を読み込むやつです
    • megamoji.js … vue.js を使ったコントローラーが入っています
    • parts.js … 「パーツから選ぶ」のパーツ一覧が入っています
    • posteffects.js … ポストエフェクトの実装が入っています。詳細は以下

以下は各種設定ファイルなので、通常は気にしなくて良いです。

  • .github/
    • workflows/ … github actions の 設定
      • lint-pr.yml … PR を送った時に自動でコーディングスタイルをチェックしてくれる
      • lint.yml … gh-pages に直接 push した場合もチェックを走らせる
    • dependabot.yml … dependabot の設定
  • .eslintignore … eslint の設定
  • .eslintrc.js … eslint の設定
  • .gitignore … git の設定
  • .gitmodules … git の設定
  • .stylelintignore … stylelint の設定
  • .package-lock.json … npm の設定
  • .package.json … npm の設定
  • stylelint.config.js … stylelint の設定

フィルタの追加

filters.js に実装されている関数群は、「ファイルから選ぶ」で画像を読 み込む際、画像に対して行う前処理の実装です。

引数に img のオブジェクトが渡ってくるので、適宜処理をして、できあがっ た画像の BlobURL を返してください。

エフェクトの追加

effects.js に実装されている関数群は、「効果をつける」タブで選ぶこと のできる特殊効果たちの実装です。ユーザーは複数のエフェクトを組み合わせ て使用することができます。

以下の5引数を受けます:

keyframe
アニメーションの進行具合 (0.0 ~ 1.0 の浮動小数)
ctx
CanvasRenderingContext2D のオブジェクト
cellWidth
canvas の横幅
cellHeight
canvas の高さ

背景が塗りつぶされたあと、 drawImage される直前の ctx が渡ってくる ので、 transform, filter, clip など好みの変形をセットしてくださ い。 エフェクトは複数併用することを想定しているので、 setTransform など他のエフェクトが加えた効果をアンドゥしてしまうようなメソッドを呼ぶ ことは避けてください。

渡ってくる canvas は、最終的に絵文字としてレンダーされるものの4倍 (縦横それぞれ2倍)の大きさになっていることに注意してください。

+--------+
|        | <- cellHeight / 4 の余白
| +----+ |
| |    | | <- cellHeight / 2
| |    | |    最終的に絵文字に使われる部分
| +----+ |
|        | <- cellHeight / 4 の余白
+--------+

たとえば絵文字を上にスライドアウトさせたい場合、 cellHeight / 2 だけ (cellHeight ではなく) 上に translate してあげれば十分です

余白をトリミングする前の canvas の様子が見たい場合は、「整形方法を選ぶ」 の「その他」にある「余白を切らない」を有効にしてください。

===

仕様の背景:

びよんびよん などの拡大縮小 (特に縮小) や回転を伴うエフェクトを組み 合わせると、本来絵文字として使われる範囲外の、余白部分までチラ見えして しまうことがあります。このような場合でもアニメーションを綺麗に見せるた め、内部ではいったん、最終的に絵文字に使われる範囲より外まではみ出して レンダリングしてから、あとで余白をカットしています。

わかりづらい仕様なのでなんとかしたい気持ちはありますが、上手い方法が思 いついていないです。

アニメーションの追加

animations.js に実装されている関数群は「効果をつける」タブ内「アニ メーション」で選ぶことができる特殊効果たちの実装です。ユーザーは一つし か同時に使えません。

以下の9引数を受けます:

keyframe
(effect_ と同様)
ctx
(effect_ と同様)
image
アニメーションさせたい元画像
offsetH
元画像の描画したい範囲(左端)
offsetV
元画像の描画したい範囲(上端)
width
元画像の描画したい範囲 (幅)
height
元画像の描画したい範囲 (高さ)
cellWidth
(effect_ と同様)
cellHeight
(effect_ と同様)

エフェクトに比べて、元画像に関する引数が増えています。

アニメーションは、渡ってきた canvas に対して、 ctx.drawImage などを 使って実際に画像 image をレンダリングすることが期待されます。ユーザー の設定したトリミング範囲が offsetH, offsetV, width, height として渡っ てくるので、通常、 canvas に対するレンダリングは以下の形になります (効 果の一環としてあえてそうしないことは可能です):

ctx.drawImage(image, offsetH, offsetV, width, height, ...);

アニメーションに渡される canvas もエフェクトと同様、実際に絵文字として 出力されるものの4倍の大きさを持っています。

+--------+
|        | <- cellHeight / 4 の余白
| +----+ |
| |    | | <- cellHeight / 2
| |    | |    最終的に絵文字に使われる部分
| +----+ |
|        | <- cellHeight / 4 の余白
+--------+

たとえば、ただ画面の**に通常のサイズで絵文字を描画したいだけの場合 (なにもしないアニメーション)、実装は次のようになります:

ctx.drawImage(..., cellWidth / 4, cellHeight / 4, cellWidth / 2, cellHeight / 2);

エフェクトと比べると、レンダリング方法を自由に実装できる点で自由度が高 いです (2つ重ねてレンダリングするなど、単純な変形だけでは実現できない 効果を実装できる)。ただし、他のアニメーションと組み合わせることはでき なくなってしまうので、エフェクトとして同じ効果を実装することができない か、一度は検討してみてください。

ポストエフェクトの追加

postEffects.js に実装されている関数群は、「効果をつける」タブの「エ フェクト」で選ぶことのできる特殊効果たちの実装です。ユーザーは複数のポ ストエフェクトを組み合わせて使用することができます。

以下の5引数を受けます:

  • keyframe
  • ctx
  • cellWidth
  • cellHeight

それぞれの引数の意味はエフェクトと同様です。最終的にレンダーされる絵文 字の4倍の大きさの canvas が渡ってくるところも同様です。

エフェクトが drawImage (animation_ 関数群) より前に呼ばれるのに対 し、 ポストエフェクトはそれよりも後に呼ばれます。これによって、レンダー された画像の上からさらに効果を描き込むことができます。

フォントの追加

読み込みが遅くなるので慎重に。

どれだけ面白くても、アイコンサイズに縮小して読めないようなフォントは入れない。

  1. フォントのライセンスをよく確認する
  2. スクリプトで woff を作る (https://github.com/odemiral/woff2sfnt-sfnt2woff など)
    node sfnt2woff.js hoge.ttf hoge.woff
        
  3. fonts に woff を入れて、 fonts.css から参照