Help us understand the problem. What is going on with this article?

Nuxt.jsでリアルタイムでTシャツデザインするアプリ作ったからソース全部公開します

More than 1 year has passed since last update.

動くやつ 👉 https://condescending-kilby-96a5ca.netlify.com/
ソースコード 👉 https://github.com/nyallpo/dasa-t-shirt
thumb.JPG

こういう企画がまずあって、絵が描けなくても簡単にデザインの真似事みたいなことができるアプリが欲しいな~〜と思いました。ゆえに作った。

要求仕様

  • Tシャツの上に画像とか文字とかペタペタ貼っつけてブリブリ動かして~みたいなのがほしい
  • でも模様はシャツのラインに合わせてほしい(かわいいから)
  • そして服のシワとかは透けていてほしい(かわいいから)
  • 完成した画像をツイッターにハッシュ付きで公開するか、ダウンロード保存させたい
  • 企画に間に合わせるために数日で作りきる

技術的条件

  • とりあえずWindowsのChromeで動く
  • サーバ側の処理はなしで、ブラウザのみで完結させたい
  • 無料で作れて無料でホスティングしたい
  • デプロイも限りなく簡単にやりたい

上記を満たすべく、画像の合成のためにPixiJS、UIの構築と管理、ビルドのためにVue.jsNuxt.js、ホスティングサイトにNetlifyを採用しました。

おおざっぱな動き

各種処理を施した画像や文字をレイヤー化して合成し、Canvasタグ上へ描画します。
また、その結果を1枚のPNG画像として出力できるようにします。
合成.jpg
ユーザーが追加するオブジェクトは一番下層のレイヤーに配置し、別途HTML上に用意したボタンで拡大や回転などの操作ができます。
今回はシンプルにPNG画像の透過/非透過を使ってマスクを表現していますが、例えば背景を設定したいとか、シャツをショッキングピンクに染めたいとか、髪飾りを追加したいなどの複雑な機能を追加する際にはMaskやFilterが活用できます。

File APIでローカル画像をシャツに表示する

File APIを使うと、ローカルPC上のバイナリファイルをサーバーにアップロードすることなくJavascriptで扱うことができます。これを使って、フォームから画像ファイルを選び、シャツの柄として表示する機能を実装しています。

<template>
  <input type="file" accept="image/*" @change="onAddImage">
</template>
<script>
  // ファイルを選択すると、以下のコードが実行される
  onAddImage(e) {
    // 画像ファイルを読み込むためのFileReaderを用意する
    const reader = new FileReader();
    reader.onload = e => {
      // FileReaderで読み込んだバイナリをPixiJSでロード
      let sprite = PIXI.Sprite.from(e.target.result);
      // 以下略
    };
    // 画像読み込み開始
    const fileObj = e.target.files[0];
    reader.readAsDataURL(fileObj);
  }
</script>

ブレンドモードを設定する

シャツのレイヤーをただ被せるだけだと、自然な模様になりません。
Photoshopを使ったことがある方ならレイヤーに設定する描画モードをご存知かと思いますが、PixiJSでも同様に、SpriteごとにBlendModeが設定できます。

let sprite = new PIXI.Sprite.from("some_nice_pic.png");
sprite.blendMode = PIXI.BLEND_MODES.MULTIPLY;

ツイッターの絵文字をスタンプみたいにペタペタ貼りたい機能

Twitter内では、ブラウザ標準搭載の絵文字ではなく、Twemojiと呼ばれる独自の画像セットが使われています。
このPNG画像をボタンひとつでペタペタ貼り付けたい。

実装は至ってシンプルで、Vueのmounted()で絵文字を全て画像に変換し、そのURLをPixiJSに渡すだけです。

mounted() {
  window.twemoji.parse(document.body);
}

機能を作り終わってから気づいたんですが、PNG画像だとズーム機能を作ったときに見た目が粗くなってしまうので、SVGで管理させればよかったなぁと思いました。

その他

制作期間は3日でした。このQiitaの記事を書くのには2ヶ月かかりました。

ホスティングにNetlifyを使ったのは正解でした。無料だし、githubと連携させてgit pushいっぱつデプロイ〜!ってのが簡単で気持ちよかった。無料だし。
参考 https://qiita.com/shozzy/items/dadea4181d6219d2d326

ツイッターボタンで作った画像を一発シェア〜!という流れまでを作りたかったんですが、Twitterの仕様上、Canvasから生成したPNG画像を直接投稿することはできず、Ajaxで一度どこかのサーバに保存して、固有のURLを作らないとだめそう。
よって、画像のダウンロードボタンの設置で妥協しました。
参考: https://gorigins.com/posting-a-canvas-image-to-facebook-and-twitter
さっき調べたら、無料で使えるFirebaseとかが財布に優しそうなので今度はこれを使いたいなと思います。

Nuxt.jsやPixiJSを使ったアプリの参考になれば幸いです。

nyallpo
無職です https://github.com/nyallpo
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away