要旨
html2canvasは複数のtext-shadowを指定すると正常に読み込まないバグを抱えています。それを強引に解決できたのでやり方の解説とバグ回避用のJavaScriptを公開しています。コピペしてご利用ください。
目次
背景
html2canvasはNiklas von Hertzenが開発しているjavascriptライブラリで主にスクリーンショット機能を目的に使用されています。
私はCSSで字幕を作成するアプリケーション(自作)の開発に用いたのですが、
text-shadow
の値を最初の一つしか読み込まないバグ仕様にぶつかりました。
アプリケーションの仕様上、妥協するわけには行かなかったので、
text-shadow
の値の数だけ要素を動的に生成して重ねることで強引に突破しました。
3年経っても誰も書かなかったので就活アピールも兼ねて書いていきます。text-shadowの値をRGB->HEXして","でsplitして配列のlength分だけfor文で要素を生成して対象の要素のCSSを完コピさせた上で対象の要素の上にかぶせることでできたんだけど、この手法思いつくまでにクソほど時間かかった。ってかもっとスマートに書きてぇのにこれしかアルゴリズム思いつかんかった。
— LOVESANA (らぶさな) (@LovesanaCSS) July 7, 2019
初Qiitaカキコなのでお手柔らかにお願いします。(
ご指摘や改善点は歓迎です!
問題点の整理
環境
- 使用ライブラリ
- html2canvas 0.4.1
- 動作確認済ブラウザ
- Safari バージョン14.1.2 (14611.3.10.1.7)
- Google Chrome バージョン: 104.0.5112.79(Official Build)
- 実行環境
- MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)
- macOS Mojave 10.14.6(18G8022)
- MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)
発生している問題
text-shadow
の値が先頭の一つしか読み込まれません。
詳細は下記のデモで確認してください。
デモンストレーション(CodePen)
やかましいほどtext-shadow
の値をつけてみましたが、
生成された<img>
は先頭のREbeccapurple
しか読み込まれていません。
See the Pen html2canvas_text-shadowBUG_demo.html by LOVESANA (@lovesana) on CodePen.
解決策のアルゴリズム
html2canvasをいじって機能を追加する
しんどい
text-shadowの値の数だけ要素を生成して重ねる(イメージ図)
See the Pen html2canvas_text-shadowBUG_imaging by LOVESANA (@lovesana) on CodePen.
いけそう、作ろう。つくっていく
まずはtext-shadow
の値を抽出してHEXに変換して配列に入れる
See the Pen Untitled by LOVESANA (@lovesana) on CodePen.
できたっぽいです。正常に一般名からHEXに変換できてますね。
次にtext-shadow
の値の数だけダミーを生成する。
See the Pen html2canvas_text-shadowBUG_1 by LOVESANA (@lovesana) on CodePen.
ちゃんと色ごとに分離してくれました。(クロマトグラフィーみたい)
生成画像も全色を拾えていますね。
最後にダミーを重ね合わせて・・・
See the Pen html2canvas_text-shadowBUG_2 by LOVESANA (@lovesana) on CodePen.
できました!
html2canvasは領域外にfixedするなどして描画領域外に配置された要素を正常に画像化できないのでダミー元のターゲットに重ねるなど工夫が必要になります。どうしても重ねたくない場合は画像化した瞬間にダミー要素を削除するなどの工夫で対策してください。
配布ver.コピペしてどうぞ!
See the Pen html2canvas_text-shadowFixedBUG_demo.html by LOVESANA (@lovesana) on CodePen.