この記事はRiot.js Advent Calendar 2016の14日目の記事です。
昨日に続いて記事を書かせていただきます!
先日Riot.jsでSVG画像を生成するコードを書いていたのですが、その時ハマった時のお話です。
<svg-cross></svg-cross>
<script src="https://cdnjs.cloudflare.com/ajax/libs/riot/2.6.7/riot+compiler.js"></script>
<script type="riot/tag">
<svg-cross>
<svg width="100" height="100" version="1.1" viewbox="0 0 100 100">
<line x1="0" y1="50.5" x2="100" y2="50.5" stroke="gray"/>
<line x1="50.5" y1="0" x2="50.5" y2="100" stroke="gray"/>
<line each={l in lines} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2} stroke={l.color} stroke-dasharray="2,2"/>
</svg>
this.lines = [
{
x1: 10.5,
y1: 10.5,
x2: 90.5,
y2: 90.5,
color: 'red',
},
{
x1: 90.5,
y1: 10.5,
x2: 10.5,
y2: 90.5,
color: 'blue',
},
];
</svg-cross>
</script>
<script>
riot.mount('svg-cross');
</script>
見た目上はまったく問題ないんですがコンソールログを見たら大量のエラーが…
riot+compiler.js:1994 Error: <line> attribute x1: Expected length, "{l.x1}".
setInnerHTML @ riot+compiler.js:1994
_mkdom @ riot+compiler.js:996
Tag @ riot+compiler.js:1497
mountTo @ riot+compiler.js:2454
pushTags @ riot+compiler.js:2597
each @ riot+compiler.js:1959
pushTags @ riot+compiler.js:2601
riot.mount @ riot+compiler.js:2652
(anonymous) @ riot+compiler.js:3537
done @ riot+compiler.js:3453
compileTag @ riot+compiler.js:3460
compileScripts @ riot+compiler.js:3471
(anonymous) @ riot+compiler.js:3524
riot.mount @ riot+compiler.js:3537
(anonymous) @ svg.html:36
riot+compiler.js:1994 Error: <line> attribute y1: Expected length, "{l.y1}".
setInnerHTML @ riot+compiler.js:1994
_mkdom @ riot+compiler.js:996
Tag @ riot+compiler.js:1497
mountTo @ riot+compiler.js:2454
pushTags @ riot+compiler.js:2597
each @ riot+compiler.js:1959
pushTags @ riot+compiler.js:2601
riot.mount @ riot+compiler.js:2652
(anonymous) @ riot+compiler.js:3537
done @ riot+compiler.js:3453
compileTag @ riot+compiler.js:3460
compileScripts @ riot+compiler.js:3471
(anonymous) @ riot+compiler.js:3524
riot.mount @ riot+compiler.js:3537
(anonymous) @ svg.html:36
riot+compiler.js:1994
...
lineの座標指定属性に設定したテンプレート変数用の{}
がうまくパースできなくて怒られているみたい?(マジックナンバーでは問題なし)
別に表示上は問題ないのですが、コンソールログが出続けるのは気持ち悪い!(SPAにした日にはガンガンコンソールログが蓄積されていきますしね。。)
いろいろ調べていたら解決策っぽいのが…?
SVG tries to render before RiotJS replaces variables
明確な原因までは書かれていませんでしたが、x1,x2,y1,y2の属性名にそれぞれriot-
を付けてあげればいいみたいですね。
- <line each={l in lines} x1={l.x1} y1={l.y1} x2={l.x2} y2={l.y2} stroke={l.color}/>
+ <line each={l in lines} riot-x1={l.x1} riot-y1={l.y1} riot-x2={l.x2} riot-y2={l.y2} stroke={l.color}/>
ちなみに<line>
以外ですと、<text>
のx,yでも発生しました。
はー、すっきりした。。。
しかしRiot.jsでSVGを扱えるのはありがたいですね。図やグラフもサクサク描けそうです。