概要
タイトルから何を言っているんだ?と思われる方が多数だと思われるので、簡単にやりたいことを書きます。
個人備忘録です。
やりたいこと
Nuxt.jsで構築した画面の一部を画像にしてTwitterで投稿しようとしています。
そのときに、html2canvasを使って、特定のhtml要素をcanvasに変換し、
その後、imageファイルをしてサーバーに転送、twitterに投稿する文を添えてtwitterに投稿します。
ただここで問題になるのが、canvasにする要素に外部から取得した画像(ここではFirebase Storage)を含む場合に、
CORSが邪魔をしてきたりするので、そのときの戦闘風景が以下説明となります。
TL;DR
methods: [
async drawCanvas () {
await html2canvas(document.getElementById("target"), {
canvas: document.getElementById("result"),
width: '100%',
height: '100%',
letterRendering: 1,
useCORS: true, // CORSを有効化
})
},
async tweet() {
var canvas = document.getElementById("result")
var base64URL = canvas.toDataURL('image/jpeg').replace(/^.*,/, '')
res = await this.$axios.post(process.env.TWEET_URL, {
content: hogehoge,
image: base64URL
})
},
],
useCORS
を付ければいいいようです。
使用技術
- Firebase
- Nuxt.js ->
2.2.0
- html2canvas ->
1.0.0-alpha.12
- npm firebase/app ->
0.3.4
説明
状況
id="target"
をimageにしてcanvasに描画しようとしています。
target
内のimgにはこれからローカルの画像をアップロードしようとしています。
<template>
<div id="target">
<div class="image_display">
<img
:v-if="object.imageURL"
:src="object.imageURL"
@click="removeImage"
></img>
<v-icon
v-else
>edit</v-icon>
<input
type="file"
@change="onFilePicked"
>
</div>
</div>
<canvas id="result"></canvas>
</template>
<script>
export default {
data () {
return {
object: {
imageURL: ""
}
}
}
}
</script>
やったこと
【失敗談】 allowTaintを使用する
html2canvasのオプションに allowTaint
があり、これを使用するとcanvasに描画したimageに外部から取得したimageも描画されるようになります。
html2canvas(document.getElementById("target"), {
canvas: document.getElementById("result"),
width: '100%',
height: '100%',
allowTaint: true
})
何がだめなのか?
アップロードする時に、 document.getElementById("result").toDataURL('image/jpeg')
をすると
Tainted canvases may not be exported
というエラーが出てしまいます。これは、「canvas内に不純物が入っているためエクスポートできないですよ」と怒られるわけです。
FirebaseにCORS設定
ではどうするかというと、firebase storageの画像に許可をもらいます。
普通に「firebase storage download」とかで検索すると公式のページがトップに表示されます。
ここにも記載があるとおり、CORSの設定が必要になるので設定します。
[
{
"origin": ["*"],
"responseHeader": ["*"],
"method": ["GET"],
"maxAgeSeconds": 86400
}
]
【Point】
- ファイル名は何でもいい
- 適宜CORSの設定
# firebaseにCORS設定
$ gsutil cors set cors.json gs://project-name.appspot.com/
# 設定内容の確認
$ gsutil cors get gs://project-name.appspot.com/
html2canvasをCORSを使って表示する
<script>
...
html2canvas(document.getElementById('target'), {
canvas: document.getElementById('result'),
width: '100%',
height: '100%',
useCORS: true
}
...
</script>
参考文献