Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした