SlideShare a Scribd company logo
Inline SVG - トラブルとその対策
2013/10/12 第8回HTML5など勉強会 @kadoppe
自己紹介
● 名前
● 門脇 恒平 @kadoppe
● 職業
● ソフトウェアエンジニア
● 所属
● 株式会社シェアウィズ & HTML5-WEST.jp
本日のスライド
● SlideShare
● http://www.slideshare.net/kadoppe
アジェンダ
● SVGとInline SVG
● なぜInline SVGを使ったのか
● トラブルと対策
● 学んだこと・教訓
SVGとInline SVG
SVGとは
● S: Scalable(拡大可能な)
● V: Vector(ベクター形式の)
● G: Graphic(画像)
● 直訳すると「拡大可能なベクター画像」
特徴1: 拡大・縮小してもきれい
点で画像を表現 線で画像を表現
特徴2: XML形式のフォーマット
● XML要素で円や線などの形を表現
● テキストエディタで編集可能
Inline SVGとは
● HTML5 からの新機能
● HTMLドキュメントにSVGマークアップ
を埋め込み可能に
Inline SVGのサンプル
<html>
<body>
<h1>Inline SVGサンプル</h1>
<svg width=100 height=100>
<circle r=50 cx=50 cy=50 />
</svg>
</body>
</html>
Inline SVGのメリット
● 画像のルックアンドフィールをCSSで
変更可能
● 円の色、線の太さを変える、など
● 画像内の各要素に対するユーザ操作を
JavaScriptでハンドリング可能
● マウスクリック、ドラッグなどに対する処理
利用可能なブラウザ
ブラウザ 対応バージョン
Internet Explorer 9以降
Firefox 3.0以降
Chrome 4.0以降
Safari 3.2以降
iOS Safari 3.2以降
Android 3.0以降
JavaScriptライブラリ
● D3.js - http://d3js.org
● Webページでデータビジュアライゼーション
● Raphaël - http://raphaeljs.com
● Webページ上でベクター画像を動的に生成
WebにおけるSVGの活用事例
● 活用例1
● ロゴやアイコン画像
● 活用例2
● インタラクティブなWebアプリケーション
ロゴやアイコン画像
ロゴやアイコン画像
Webアプリケーション
無料学習サイト ShareWis http://share-wis.com
なぜInline SVGを
使ったのか
ShareWis開発前の要件
● GoogleマップのようなUI上に
コンテンツを配置
● マウス操作に応じて各コンテンツが
アニメーション
● iPadのSafariに対応
● 古いブラウザ(IE 8以下)は非対応
利用する技術の選択肢
● Flash
● Google Maps JavaScript API
(カスタムオーバレイ)
● Inline SVG
利用する技術の選択肢
● Flash
● Google Maps JavaScript API
(カスタムオーバレイ)
● Inline SVG
トラブルと対策
Inline SVGから始まる茨の道
やりたかったこと(1)
text要素に下線を引く
text-decoration属性
<svg witdh=100 height=100>
<text text-decoration=underline x=0 y=20>Hello World</text>
</svg>
下線が表示される
発生したトラブル
Firefoxで下線が
表示されない
原因調査
● Bugzilla@Mozillaにバグ報告あり
● Bug 317196 - Support the 'text-
decoration' property in SVG (underline,
etc.) - https://bugzilla.mozilla.org/show_bug.cgi?id=317196
● 報告日: 2005/11/20
● SVG Textのレンダリング方法の問題
対策1: line要素で下線を引く
● 手順
1. text要素の大きさ(高さと幅)をgetBBox()
メソッドを使って取得
2. 適切な座標にline要素を挿入
解説
var textElm = document.getElementById('text');
var box = textElm.getBBox();
alert(box.height); // text要素の高さ
alert(box.width); // text要素の幅
<svg>
<text x=0 y=20>Hello World</text>
<line x1=X1 y1=Y1 x2=X2 y2=Y2 />
</svg>
高さと幅をもとに
line要素の始点・終点を計算
Hello World
【朗報】
対策2: 新しいFirefoxをつかう
● Firefox 25
● 2013/10/29 リリース予定
● 待望のtext要素の下線表示に対応
やりたかったこと(2)
要素の大きさを取得する
getBBox()メソッド
var textElm = document.getElementById('text');
var box = textElm.getBBox();
alert(box.height); // text要素の高さ
alert(box.width); // text要素の幅
発生したトラブル
Firefoxで
NS_ERROR_FAILURE
NS_ERROR_FAILURE?
意味
「なんかエラー」
NS_ERROR_FAILURE?
23 /* Returned when a function fails */
24 ERROR(NS_ERROR_FAILURE, 0x80004005),
mozilla/xpcom/base/ErrorList.h
何らかの原因で関数の実行が失敗した時のエラー
原因調査
● Bugzilla@Mozillaにバグ報告あり
● Bug 612118 - SVGLocatable.getBBox()
fails unless the SVG element it is applied to
is attached and rendered - https://
bugzilla.mozilla.org/show_bug.cgi?id=612118
バグ再現方法
● 方法1
● ドキュメントにまだ追加されていない
要素に対してgetBBox()メソッドを呼び出す
● 方法2
● ドキュメントに追加されているが
display: none な要素に対して
getBBox()メソッドを呼び出す
対策1: try-catch文で囲む
try {
var textElm = document.getElementById('text');
var box = textElm.getBBox();
} catch (e) {
alert(e);
}
NS_ERROR_FAILUREはtry-catchで補足可能
対策2: displayプロパティを確認する
var textElm = document.getElementById('text');
if (getComputedStyle(textElm, null).display !== ‘none’) {
var box = textElm.getBBox();
}
getBBox()メソッドを呼び出す前に
display: noneでないことを確認
やりたかったこと(3)
テキストを折り返す
text要素の文字列を折り返す
これは折り返されたテキストです。ラーメ
ンが食べたい。無鉄砲のラーメンが食べた
いです。
横幅を指定してテキストを自動で折り返し
発生したトラブル
テキストが折り返されない
これは折り返されたテキストです。ラーメンが食べたい
原因調査
● SVGの仕様です
● SVGのtext要素はHTMLのdiv要素みたいに
自動で文字列を折り返してくれない
● textArea要素
● 自動折り返しに対応したtext要素
● まだどのブラウザも対応していない
対策: tspan要素を使う
<svg witdh=100 height=100>
<text>これは折り返されたテキストです。ラーメンが食べたい。</text>
</svg>
<svg witdh=100 height=100>
<text>
<tspan>これは折り返されたテキストです。</tspan>
<tspan>ラーメンが食べたい。</tspan>
</text>
</svg>
文字列を複数の要素に分割
詳しい手順
1.文字列を単語単位に分割
2.指定された幅を超えるまで
1単語ずつtspan要素に追加
3.超えたら末尾の単語を削除して
tspan要素の位置を調整
4.2に戻る
幅を超えたかどうかの判定
for (var i = 0; i < words.length; i++) {
tspanEl.textContent += word
if (tspanEl.getComputedTextLength() > width) {
// 超えた
} else {
// 超えてない
}
}
getComputedTextLength()で幅を取得
結果こうなる
<svg witdh=100 height=100>
<text>
<tspan x=0 dy=”18”>これは折り返された</tspan>
<tspan x=0 dy=”18”>テキストです。ラー</tspan>
<tspan x=0 dy=”18”>メンが食べたい。</tspan>
</text>
</svg>
やりたかったこと(4)
縁取り文字を表示する
縁取り文字
ラーメンが食べたいラーメンが食べたい
発生したトラブル
縁取り文字を簡単に
表示できない
原因調査
● text要素に縁取りを追加する
便利なプロパティが存在しない
方法1: text-shadow
<svg witdh=100 height=100>
<text>ラーメンが食べたい</text>
</svg>
text {
fill: white;
text-shadow: -1px -1px black,
1px -1px black,
-1px 1px black,
-1px -1px black;
}
・縁が汚い
・Firefoxでは縁が表示されない
方法2: text要素を重ねる
<svg witdh=100 height=100>
<text class=”outline”>ラーメンが食べたい</text>
<text class=”body”>ラーメンが食べたい</text>
</svg>
.outline {
stroke: black;
stroke-width: 3px;
}
.body {
fill: white;
}
text要素が2つあるのが
文書の意味的におかしい
● SVG Filter
● SVG画像に様々な効果を適用する機能
● ドロップシャドウ、色の変換など
● まだ試していないので実現できるか不明
方法3: SVG Filterを使う
やりたかったこと(5)
ズーム時に文字サイズを
固定する
ズームの仕組み
<svg witdh=100 height=100>
<g transform=”scale(倍率)”>
<circle />
<circle />
<circle />
<text />
<text />
</g>
</svg>
全体を囲むg要素のtransform属性を操作する
ズーム
発生したトラブル
ズーム時に文字サイズが
変化してしまう
テキストテキスト
テキスト
テキスト
OK
NGNG
原因調査
● SVGの仕様です
対策: 文字サイズを動的に変更
$elm.on(‘mousewheel’, function() {
// 略
var scale = 現在の倍率
var originalFontSize = 24;
var currentFontSize = originalFontSize / scale;
// 略 (text要素のfontサイズ変更処理)
}
問題点:text要素の数が多いと処理が重たくなる
対策: 文字サイズ変更を遅延
var timer = false;
$elm.on(‘mousewheel’, function() {
if (timer !== false) {
clearTimeout(timer);
}
timer = setTimeout(function() {
var scale = 現在の倍率
var originalFontSize = 24;
var currentFontSize = originalFontSize / unscale;
// 略 (text要素の文字サイズ変更処理)
}, 200);
}
マウスホイールイベントが連続して発生しているときは
文字サイズを変更しない
学んだこと
SVG Textには
トラブルがいっぱい
●SVGの仕様では(シンプルに)実現でき
ない表現がある
●ブラウザ間の差異が存在する
教訓
●SVGで(シンプル)に実現できないこと
はしない
●ブラウザ間の差異を許容する
そうしないと…
● コードが必要以上に複雑になる
● パフォーマンス低下・バグ発生の原因に
そんなInline SVGは
使っていて楽しい技術
みんなもっと
使って情報交換しよう
おしまい

More Related Content

PDF
Azure でサーバーレス、 Infrastructure as Code どうしてますか?
PDF
AWS Black Belt Online Seminar AWS Amplify
PPTX
[社内勉強会]ELBとALBと数万スパイク負荷テスト
PDF
20200219 AWS Black Belt Online Seminar オンプレミスとAWS間の冗長化接続
PDF
thymeleafさいしょの一歩
PDF
アジャイルジャーニー
PDF
SAP on Azure Cloud Workshop Material Japanese 20190221
PDF
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
Azure でサーバーレス、 Infrastructure as Code どうしてますか?
AWS Black Belt Online Seminar AWS Amplify
[社内勉強会]ELBとALBと数万スパイク負荷テスト
20200219 AWS Black Belt Online Seminar オンプレミスとAWS間の冗長化接続
thymeleafさいしょの一歩
アジャイルジャーニー
SAP on Azure Cloud Workshop Material Japanese 20190221
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)

What's hot (20)

PDF
iOSにおけるパフォーマンス計測
PDF
Black Belt Online Seminar AWS Amazon S3
PDF
AWS Expert Online appsyncを使ったServerlessアーキテクチャ
PDF
Amazon Game Tech Night #25 ゲーム業界向け機械学習最新状況アップデート
PDF
CEDEC2015_スマホゲーム開発を支えろ!〜汗と涙のQAエンジニアリング〜
PDF
メンバーのスキルアップ、どうしてる? − Java 100本ノックで新加入メンバーを鍛えてみた −
PDF
[AWSマイスターシリーズ] Amazon ElastiCache
PDF
俺のTerraform CI/CD ライフサイクル
PPTX
20220409 AWS BLEA 開発にあたって検討したこと
PDF
PCI DSSにおける認証認可 インフラ編
PDF
20200422 AWS Black Belt Online Seminar Amazon Elastic Container Service (Amaz...
PDF
20200212 AWS Black Belt Online Seminar AWS Systems Manager
PDF
Introduction to New CloudWatch Agent
PDF
AWSのセキュリティについて
PDF
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
PDF
デプロイメントパイプラインって何?
PDF
20200526 AWS Black Belt Online Seminar AWS X-Ray
PDF
20190814 AWS Black Belt Online Seminar AWS Serverless Application Model
PDF
[CTO Night & Day 2019] 高可用性アーキテクチャについて考える #ctonight
PDF
20200714 AWS Black Belt Online Seminar Amazon Neptune
iOSにおけるパフォーマンス計測
Black Belt Online Seminar AWS Amazon S3
AWS Expert Online appsyncを使ったServerlessアーキテクチャ
Amazon Game Tech Night #25 ゲーム業界向け機械学習最新状況アップデート
CEDEC2015_スマホゲーム開発を支えろ!〜汗と涙のQAエンジニアリング〜
メンバーのスキルアップ、どうしてる? − Java 100本ノックで新加入メンバーを鍛えてみた −
[AWSマイスターシリーズ] Amazon ElastiCache
俺のTerraform CI/CD ライフサイクル
20220409 AWS BLEA 開発にあたって検討したこと
PCI DSSにおける認証認可 インフラ編
20200422 AWS Black Belt Online Seminar Amazon Elastic Container Service (Amaz...
20200212 AWS Black Belt Online Seminar AWS Systems Manager
Introduction to New CloudWatch Agent
AWSのセキュリティについて
【BS3】Visual Studio 2022 と .NET 6 での Windows アプリ開発技術の紹介
デプロイメントパイプラインって何?
20200526 AWS Black Belt Online Seminar AWS X-Ray
20190814 AWS Black Belt Online Seminar AWS Serverless Application Model
[CTO Night & Day 2019] 高可用性アーキテクチャについて考える #ctonight
20200714 AWS Black Belt Online Seminar Amazon Neptune
Ad

Viewers also liked (15)

PDF
Firefox OSでSVGをつかってみた
PDF
SVG MANIAX - CSS Nite After dark7
PDF
[HTML5J 第47回HTML5とか勉強会] データ・ビジュアライゼーションの現況と実際
PDF
Html5j data visualization_and_d3
PDF
Pebble + JavaScriptでつくるスマートウォッチアプリ
PDF
Webでもできるデータビジュアライゼーション
PDF
WebSocketことはじめ
PDF
D3.js と SVG によるデータビジュアライゼーション
PDF
WebSocket + Node.jsでつくるチャットアプリ
PDF
AndroidでWebSocket
PDF
データをわかりやすく可視化する「データビジュアライゼーション」勉強会
PDF
SVG MANIAX Ver.2 - Mars vanilla
PDF
いまさら聞けない!?Backbone.js 超入門
PDF
SVGの基本&活用法。SVGのメリットと事例を基礎から学ぶ。
PDF
エンジニアとデザイナーとの距離
Firefox OSでSVGをつかってみた
SVG MANIAX - CSS Nite After dark7
[HTML5J 第47回HTML5とか勉強会] データ・ビジュアライゼーションの現況と実際
Html5j data visualization_and_d3
Pebble + JavaScriptでつくるスマートウォッチアプリ
Webでもできるデータビジュアライゼーション
WebSocketことはじめ
D3.js と SVG によるデータビジュアライゼーション
WebSocket + Node.jsでつくるチャットアプリ
AndroidでWebSocket
データをわかりやすく可視化する「データビジュアライゼーション」勉強会
SVG MANIAX Ver.2 - Mars vanilla
いまさら聞けない!?Backbone.js 超入門
SVGの基本&活用法。SVGのメリットと事例を基礎から学ぶ。
エンジニアとデザイナーとの距離
Ad

More from Kohei Kadowaki (9)

PDF
プログラマーのお仕事
PDF
5分でわかる?Backbone.js ことはじめ
PDF
SVGでつくるインタラクティブWebアプリケーション
PDF
UnityでつくるはじめてのPONG
PDF
インラインSVGをつかって地図っぽいものをつくってみる
PDF
ShareWisをFirefoxで動かすためのSVG的とりくみ
PDF
d3jsではじめるデータビジュアライゼーション入門
PDF
ゲーム開発初心者の僕がUnity + WebSocketで何か作ってみた
PDF
SocketStream入門
プログラマーのお仕事
5分でわかる?Backbone.js ことはじめ
SVGでつくるインタラクティブWebアプリケーション
UnityでつくるはじめてのPONG
インラインSVGをつかって地図っぽいものをつくってみる
ShareWisをFirefoxで動かすためのSVG的とりくみ
d3jsではじめるデータビジュアライゼーション入門
ゲーム開発初心者の僕がUnity + WebSocketで何か作ってみた
SocketStream入門

Inline SVG - トラブルとその対策