つくったもの
**[Oicollamaker](https://obcat.github.io/oicollamaker/)**(GitHubは[こちら](https://github.com/obcat/Oicollamaker))できました。*明治おいしい牛乳*のパッケージのコラージュ画像を生成できるアプリです。
Q. こんなアプリだれがつかうんですか?
A. 知りません。
Q. スマホにも対応していますか?
A. 完全非対応です。
なぜつくったか
JavaScriptでDOMを操作する方法を学び、何かをつくりたくなったからです。
html2canvas
明治おいしい牛乳(以下「おい牛」という)のパッケージ部分はHTMLでできています。
そのため右クリックで保存することができません。
もちろんスクショを撮ってトリミングすれば保存できますが、ちょっとめんどうです。
そこで、おい牛のパッケージ部分を画像化する機能をつけてみました。
その部分ではhtml2canvasというJavaScriptのライブラリを利用しています。
公式サイトはこちら:
html2canvas - Screenshots with JavaScript
つかいかたは至ってかんたんです。
たとえばHTML内の画像化したい要素にtarget
というid
をつけておいて、
html2canvas(document.getElementById("target")).then(canvas => {
document.body.appendChild(canvas);
});
という魔法を唱えると、target
の内容が描画されたcanvas
をbody
の子要素として追加することができます。
問題点
肝心のおい牛パッケージを画像化する機能ですが、いろいろと問題があります。
ヨとグのあいだの長音符(のばし棒)の向きがおかしいですね。
おそらくhtml2canvasが縦書きのテキストに対応していないのでしょう。
また、画面最上部からいくらか下にスクロールした状態でボタンを押して画像化を実行すると・・
このように、スクロールした分だけ下にずれた画像が生成されてしまいます。
このバグはなんとかしたら直せそうなので、気が向いたらやってみようとおもいます。
工夫した点
はじめは、input
要素をHTMLに直接記述することで入力用のテキストボックスを設置していました。
<form>
<input type="text" placeholder="明治">
<input type="text" placeholder="おいしい牛乳">
<input type="text" placeholder="ナチュラルテイスト製法">
</form>
<section>
<div class="output">明治</div>
<div class="output">おいしい牛乳</div>
<div class="output">ナチュラルテイスト製法</div>
</section>
こんなかんじです(コードは説明のために簡略化しています)。
このうえでJavaScriptを次のように書いていました。
const inputs = document.querySelectorAll("input");
const outputs = document.querySelectorAll(".output");
for (i = 0; i < inputs.length; i++) {
// 入力した文字がリアルタイムで反映されるように設定
inputs[i].addEventListener("input", e => {
outputs[i].textContent = e.target.value;
}
このままでもいいのですが、HMTLのほうで重複している箇所が多いのが気になります。
たとえば「おいしい牛乳」を「世界一おいしい牛乳」にさしかえたい場合、
input
要素のplaceholder
属性の値と、div
内のテキストの2箇所を修正しなければなりません。
これはちょっとめんどうです。
そこで、ページが読み込まれたときにDOMを操作することによって、
入力用のテキストボックスが自動的に設置されるようにしてみました。
まず、HTMLを次のように修正します。
<form></form>
<section>
<div class="output">明治</div>
<div class="output">おいしい牛乳</div>
<div class="output">ナチュラルテイスト製法</div>
</section>
input
要素をすべて取りのぞきました。
そしてJavaScriptを次のように修正します。
const outputs = document.querySelectorAll(".output");
for (i = 0; i < outputs.length; i++) {
const form = document.querySelector("form");
// input要素を作成
const input = document.createElement("input");
// 作成したinput要素に属性を付与
input.setAttribute("type", "text");
input.setAttribute("placeholder", outputs[i].textContent);
// 入力した文字がリアルタイムで反映されるように設定
input.addEventListener("input", e => {
outputs[i].textContent = e.target.value;
});
// formの子要素としてinputを追加
form.appendChild(input);
}
このようにすれば、ページが読み込まれたときに、
output
クラスをつけておいたHTML要素それぞれについて、
対応する入力用のテキストボックスが設置されるようになります。
もしもコラージュの対象を*明治エッセルスーパーカップに変更したくなったら、
HTML内の該当する部分をスーパーカップ*仕様にかきかえて、
編集させたい要素にoutput
クラスをつけるだけでOKです。ラクチンですね。
おわりに
なんか明治のまわしものみたいになってしまいましたが、
いっさい関係ありません。。。
最近はPHPもさわりはじめたので、今度はPHPもつかって何かつくってみようとおもいます。