LoginSignup
9
6

More than 5 years have passed since last update.

Riot.jsでSVGを描画しようとしたら小一時間程ハマった話

Posted at

この記事はRiot.js Advent Calendar 2016の14日目の記事です。
昨日に続いて記事を書かせていただきます!

先日Riot.jsでSVG画像を生成するコードを書いていたのですが、その時ハマった時のお話です。

以下のコードを実行するとこのような画像が描画されます。
cross.png

svg.html
<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を扱えるのはありがたいですね。図やグラフもサクサク描けそうです。

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6