液晶風の画面は決まった形をオン・オフするだけなので、canvas にコードで描くのは大変なだけで無駄が多い。かといってセグメントを1つ1つ画像にわけて座標指定で配置していくのも面倒くさい。

と考えていくと SVG を埋めこんで、SVG の要素を JS で操作するのが効率が良い。ワークフローとしては SVG の作成と JS の実装で綺麗に境界を作ることができる。

Inkscape


Inkscape の良いところは以下の点

  • XML エディタが UI と連動している
    • レイヤーやオブジェクトを選択すると該当箇所にエディタ上で跳べる
  • 構造をコントロールしやすい
    • 画像を編集するというより SVG の XML を編集するUIというイメージ

Inkscape でオブジェクトに名前をつけると、svg 上では inkscape:label 属性に入る。これを利用して JS から操作すれば Inkscape で保存した SVG をそのまま利用できる。

JSで扱う

Inkscape で保存した SVG をそのままファイルとして置いて、fetch() で取得し、HTML5 な HTML で特定の要素の innerHTML に入れてしまうのが手っ取りばやい。(XML の Processing Instruction については Chrome ではコメントに変換されるが、仕様上パースエラーなので消しておく)

名前空間の扱いが謎だが、querySelector() の場合以下のような形で指定することができる (つまり名前空間を扱わず、prefix も含めて属性名とする)

svg.querySelectorAll('g[inkscape\\:label="digits"] > g')

あとは適当に style.visibility を操作するだけなので省略

svg の HTML Living Standard 的解釈

svg 要素は HTML では SVG 2 で定義されると書いてある。つまり「HTML は SVG を知っている」。SVG 2 では HTML 内でも svg が使えることを考慮して書かれている。

SVG の仕様上、HTML 内では SVG の名前空間は HTML パーサによって与えられると書いてある。このため、HTML 内 svg 要素には xmlns は必要ない。 https://svgwg.org/svg2-draft/single-page.html#struct-Namespace

HTML LS

In HTML, the xmlns attribute has absolutely no effect. It is basically a talisman. It is allowed merely to make migration to and from XML mildly easier. When parsed by an HTML parser, the attribute ends up in no namespace, not the "http://www.w3.org/2000/xmlns/" namespace like namespace declaration attributes in XML do.

また https://html.spec.whatwg.org/#elements-2 に例示があるが、HTML としては xmlns は何の効果も埋み出さない。例えば svg 要素の中に xmlns:foo="foo" という宣言と共に <foo:bar /> というのがあっても、これは HTML パーサによって自動的に与えられる svg の名前空間に属し、foo:bar という要素名になる。

  1. トップ
  2. tech
  3. JS+SVGで液晶画面風の表示をつくる
▲ この日のエントリ