#はじめに
はじめまして、最近A-Frameがマイブームです。
むちゃくちゃ簡単に3D、VRが出来ることに感動するのですが、
如何せん日本語の表示が未対応なのがつらいところです。
現状は2つほど表示する方法がありますが、どちらも十全ではないので、
別の方法をjavascriptで実装してみました。
#既存の方法
既存の方法は以下の2つとその欠点
- フォントデータを変換して使う
- 欠点:あらかじめ使用する文字すべてを準備する必要がある。
- HTML Shaderを使う
- 欠点:透過できない。htmlのbackgroundを透明にすると、3D空間ではなくcanvasを透過してしまう。(demo参照)
別の方法
ざっくりした方法
- 対象の日本語テキストを生成したcanvasに描画
- canvas情報をbase64に変換
- src=base64のa-imageを挿入
コード
今回の方法と、参考にHTMLShaderを使った方法を実装
ざっくり実装なのでいろいろ適当
<html>
<head>
<meta charset="utf-8"/>
<title>aframeMultiByte</title>
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<script src="./js/aframe-html-shader.min.js"></script>
<script src="./js/html2canvas.min.js"></script>
<style>
.target{
width:500px;
height:100px;
font-size:20pt;
background:rgba(0,0,0,0);
}
</style>
</head>
<body>
<div id="target1" class="target">
<p>旧.こんにちは世界(HTML Shader)🌝</p>
</div>
<a-scene vr-mode-ui="enabled: true" style="position:fixed;top:0;">
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
<a-plane position="-1.5 2 -1" width="2" height="0.5" material="shader:html;target: #target1;"></a-plane>
<a-entity mb-text position="1.5 1.5 -1" data-text="新.こんにちは世界(script)🌝"></a-entity>
</a-scene>
</body>
<script>
function aframeMutlByte(){
document.querySelectorAll('[mb-text]:empty').forEach(mb_text=>{
console.log(mb_text.dataset.text)
const text =mb_text.dataset.text
const text_cnt = text.length
const width = text_cnt*1.4
const height= 1.6
let cvs = document.createElement('canvas')
let ctx = cvs.getContext('2d')
cvs.width = width*100
cvs.height = height*100
ctx.fillStyle = "rgb(0, 0, 0)"
ctx.font = '100pt Arial'
ctx.fillText(text,0,125)
const base64 = cvs.toDataURL("image/png")
mb_text.innerHTML=`<a-image scale="${(width)/10} ${height/10} 1" src="${base64}"></a-image>`
})
}
aframeMutlByte()
</script>
</html>
結果
日本語だけでなく顔文字も透過した状態で表示される。
最後に
作りこめば、フォントの指定とか、改行とかオプションをいろいろ実装できそう。
ざっくり作ったので、VR端末での動作確認などは要検証
追記(2020-07-18)
VRモードの設定つけ忘れてたのでコード修正
一応Android9のChrome、iOS13のsafari、OculusQuestで大丈夫だったので、
おおよそ使えそう。
#参考サイト
A-Frame: Hello WebVR
A-Frameで日本語を表示したい
A-FrameとHTML Shaderで美しい日本語テキストを表示する方法