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>
これで画像が生成される。
