以前CreateJSによるコラ画像ジェネレータを作成しましたが、html2canvasというライブラリの使い勝手がよさそうだったので試してみました。
あわせて最近勉強中のVue.jsで入力内容の制御もやってみました。
ADs
HTMLの要素をcanvasとして生成するJavascriptライブラリです。
<body>を対象とすればページのスクリーンショットを生成できますし、div#hogeのような指定の要素のみを対象とすることも可能です。
html2canvas自体がHTMLやCSSを解釈してcanvasへと変換する仕組みのようで、いわばJS製レンダリングエンジンです。作者の人すごい。
</body>の直前でVue.jsとhtml2canvasを読み込みます。
ちゃんとしたものを作るときはvue-cliを使うほうがいいと思いますが、今回は単一ページで完結する簡単なものなのでCDNから直接読み込みます。
1 2 |
<script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-alpha.12/dist/html2canvas.min.js"></script> |
html2canvasはCDNjsでも配信されていますが、現行1.0.0αなのに0.4.1という古いバージョンしか配信されていないため、jsDelivrを使うかファイルをダウンロードして使用しましょう。
html2canvasはhtmlの要素をcanvasで画像化するライブラリです。ですのでHTMLとCSSでレイアウトを作成すれば、その要素がそのまま画像になります。
今回は以下のように画像+吹き出しをHTMLとCSSで作成し、吹き出し部分に入力値が反映されるというものにしました。
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<style type="text/css"> /* コラ画像用のCSS */ #preview { overflow: auto; width: 100%; } #preview_inner { background: url(torokko_trolley_rail_businesswoman_out.png) no-repeat left bottom; background-size: 200px auto; position: relative; padding-bottom: 250px; width: 600px; } #baloon { position: relative; border: 4px solid #ff8888; background: #fff; border-radius: 8px; display: inline-block; font-weight: bold; font-size: 1.2rem; color: #444; padding: 10px; min-width: 200px; white-space: pre-wrap; } #baloon:before, #baloon:after { content: ''; display: block; width: 0; height: 0; border-style: solid; border-width: 50px 15px 0 15px; border-color: #fff transparent transparent transparent; position: absolute; left: 20px; bottom: -50px; } #baloon:before { left: 16px; bottom: -60px; border-width: 58px 19px 0 19px; border-color: #ff8888 transparent transparent transparent; } </style> <div id="preview"> <div id="preview_inner"> <div id="baloon">{{ message }}</div> </div> </div> |
{{ message }} という部分がありますが、この部分にユーザーが入力したテキストが表示されます。
入力した内容に手を加えなくてもいい場合、textareaにv-modelを指定するだけで入力値がリアルタイムに反映されるフォームができあがります。Vue.jsすごい。
1 |
<textarea class="form-control" v-model="message"></textarea> |
あとはhtml2canvasでcanvasを生成すればできあがりです。
ボタンをクリックしたらdiv#preview_innerの中身をdiv#resultの中にcanvasとして生成する、という処理にしました。
1 |
<button class="btn btn-primary btn-block" v-on:click="generate">画像を生成</button> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var app = new Vue({ el: '#app', data: { message: '' }, methods: { generate(){ html2canvas(document.querySelector("#preview_inner")).then(function(canvas){ var result = document.querySelector("#result"); result.innerHTML = ''; result.appendChild(canvas) }); } } }) |
できあがったcanvasは右クリックや長押しタップで保存して使ってもらうということにしてます。
File APIを使えばボタンをクリックしてダウンロードさせる処理も多分できると思います。
見た目を整えるのでBootstrapを使いましたが、実際のコードは数行です。CreateJSのときはもっと苦労したのに…。
今回は画像の上に文字をかぶせるパターンですが、FileReader APIを使って画像をアップロードするようなジェネレータも簡単に作成できそうです。
ADs
こちらうまく動作しないようです。