vue.js で html2canvas 決定版
ラブレターみたいなのを作りたい。
ラブレターではphp側で画像を生成して出力している。
参考
https://love-letter.club/
https://wood-roots.com/web/vue-js/2253
特徴
PHP側
○ ユーザーの環境に依存しない
X サーバー重くなる
X 絵文字使えない (強引にライブラリ入れりゃ使えるが・・・ユーザー側の絵文字更新に応じ要変更)
JS側で生成
○ サーバーに負荷をかけない
○ 絵文字使える
X ユーザーの環境によってバグったりする
X 環境がバラバラなのでデバッグに手間がかかる
ただ、これからの時代は jsで 生成したい。
インストール
α版を指定してインストールする
npm install html2canvas@1.0.0-alpha.12
注意
・CSSで body に フォントを設定しない。
・バージョンは アルファ版を使う。
・npm update すると α版ではなく、stableにされるので、再度入れ直す必要がある。
・でかいモニターで出力すると線が入る ( 画像がにじむ )
これはしょうがないので諦める。
hoge.vue
<style>
#preview {
overflow: auto;
width: 100%;
}
#preview_inner {
background-size: 600px auto;
position: relative;
width: 600px;
}
#letter_body {
position: relative;
border-left: 17px solid #fbbfc8;
border-right: 17px solid #fbbfc8;
display: inline-block;
font-size: 1.5rem;
color: #444;
margin-top: -30px;
padding: 10px 10px 10px 10px !important;
min-width: 600px;
text-align: center;
height:200px;
display: table-cell; /* IE8から使用可能 */
vertical-align: middle;
white-space: pre-wrap;
}
</style>
<template>
<div>
<img v-if="imgData" :src="'/gcp-storage/' + imgData" style="width: 95%;">
<el-input type="textarea" v-model="message" :rows=5></el-input>
<el-button type="primary" @click="generate">画像を生成</el-button>
<div id="preview" style="display: block;">
<div id="preview_inner">
<div id="letter_top"><img src="/img/tegami-top.png"></div>
<div id="letter_body">--</div>
<div id="letter_bottom"><img src="/img/tegami-bottom.png"></div>
</div>
</div>
<div id="text_body">{{ message }}</div>
<h2>完成品</h2>
<div id="result"></div>
</div>
</template>
<script>
import html2canvas from 'html2canvas'//古いと、文字のサイズがずれるので、 vue.blade で 読みコンで使う
export default {
data() {
return {
imgData:'',
message:'',
};
},
created () {
this.message = 'つけめんそばざるうどん恋をした夜はすべてがうまくいきそうで。';
},
watch: {
},
methods: {
generate(){
//まずはテキスト部分だけ生成させる
let vc = this;
html2canvas(document.querySelector("#text_body"),{
scale: 2 //文字がぼやけないように
}).then(function(canvas){
//まずは一旦テキストを画像に
var letter_body = document.querySelector("#letter_body");
letter_body.innerHTML = '';
letter_body.appendChild(canvas);
vc.letterHeight = document.getElementById('letter_body').offsetHeight;
//その後、メイン画像として生成
html2canvas(document.querySelector("#preview_inner"),{
scale: 2
}).then(function(canvas){
var result = document.querySelector("#result");
result.innerHTML = '';
result.appendChild(canvas);
// document.getElementById('preview').style.display = "none";
// document.getElementById('result').style.display = "none";
// 以下、サーバーに送る処理
// var dataURI = canvas.toDataURL('image/png');
// let dataform = new FormData();
// //
// const message_tmp = document.getElementsByName("message");
// dataform.append('id',vc.$route.params.id);
// dataform.append('body',message_tmp[0].value);
// dataform.append('img',dataURI);
//
// //サーバー側に画像を保存
// axios.post('/hoge/makeGcpOnly/', dataform).then(e => {
//
// vc.imgData = e.data;
// vc.dialogVisible = false;
// vc.message = '';
// vc.loading = false;
//
// }).catch((error) => {
// console.log(error);
// console.log("エラー");
// });
});
});
}
}
};
</script>
これで画像が生成される。