Web

データURIスキームにSVGを指定して動的に書き換えてみた

09_001_01
SI部のモグです。
 
業務でデータURIスキームを使った時に思い浮かび、データURIスキームにSVGファイルを指定して動的に書き換えてみました。
 
データURIスキームとは、HTMLのimgタグなどに直接データをbase64形式で記述することで、外部のファイルにアクセスせず表示させる事ができます。
コードの容量が若干増えますが、リクエストやファイル数を減らすメリットがあり、htmlファイル1つで完結させたいなどの特定状況下で需要があります。
 
SVGファイルはxmlで記述されたベクター画像です。
アイコン等に使われる事が多いです。
 
データURIスキームとSVGファイルは、いずれも近年のブラウザではほとんど対応されているため、これを組み合わせてJavaScriptで動的に書き換える事をやってみました。
 
以下ソースです。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <script>
    function changeIcon(){
    //SVGのXML
        var svg = 
        '<?xml version="1.0" encoding="UTF-8"?>'
        + '<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">'
        + '    <rect x="5" y="5" rx="10" ry="10" width="40" height="40" fill="green" />'
        + '    <g fill="white" font-size="25">'
        + '        <text x="13" y="35">い</text>'
        + '    </g>'
        + '    <circle cx="40" cy="10" r="8"  fill="red"/>'
        + '    <g fill="white" font-size="5">'
        + '        <text x="39" y="13">2</text>'
        + '    </g>'
        + '</svg>';

        //SVGをbase64に変換する
        var b64  = window.btoa( unescape(encodeURIComponent( svg )) ); 

        //idがimg1のタグのエレメント
        var img1 = document.getElementById("img1");

        //img1のsrcを書き換える
        img1.src = "data:image/svg+xml;charset=utf-8;base64,"+b64;
}
</script>
</head>

<body>
    <!-- クリックするとchangeIcon関数を呼ばれ画像が挿し変わります。srcには最初に表示される画像がbase64で書いてあります。 -->
    <img id="img1" onClick="changeIcon()" src="data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iNTAiIGhlaWdodD0iNTAiPg0KPCEtLeODmeODvOOCueOBrue3kemDqOWIhi0tPg0KICAgIDxyZWN0IHg9IjUiIHk9IjUiIHJ4PSIxMCIgcnk9IjEwIiB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIGZpbGw9ImdyZWVuIiAvPg0KPCEtLeS4reWkruOBriLjgYIiLS0+DQogICAgPGcgZmlsbD0id2hpdGUiIGZvbnQtc2l6ZT0iMjUiPg0KICAgICAgICA8dGV4dCB4PSIxMyIgeT0iMzUiPuOBgjwvdGV4dD4NCiAgICA8L2c+DQo8IS0t5Y+z5LiK44Gu6LWk5Li4LS0+DQogICAgPGNpcmNsZSBjeD0iNDAiIGN5PSIxMCIgcj0iOCIgIGZpbGw9InJlZCIvPg0KPCEtLei1pOS4uOWGheOBriIxIi0tPg0KICAgIDxnIGZpbGw9IndoaXRlIiBmb250LXNpemU9IjUiPg0KICAgICAgICA8dGV4dCB4PSIzOSIgeT0iMTMiPjE8L3RleHQ+DQogICAgPC9nPg0KPC9zdmc+DQo=">
</body>
</html>

まずこのhtmlの前にSVGファイルを準備します。

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
    <!--ベースの緑部分-->
    <rect x="5" y="5" rx="10" ry="10" width="40" height="40" fill="green" />
    <!--中央の"あ"-->
    <g fill="white" font-size="25">
        <text x="13" y="35">あ</text>
    </g>
    <!--右上の赤丸-->
    <circle cx="40" cy="10" r="8"  fill="red"/>
    <!--赤丸内の"1"-->
    <g fill="white" font-size="5">
        <text x="39" y="13">1</text>
    </g>
</svg>

次にこのSVGファイルをbase64に変換します。
“PD94bWwgdm~”のような長い文字列になります。
 
この文字列を上記HTMLのimgタグに記述します。

<img src="data:image/svg+xml;base64,[ココに書く]">

ちなみにSVGのMIMEタイプは「image/svg+xml」です。
これで上記のSVG画像が初期表示されます。(「あ」が出ます)
 
このimgタグにonClick=”changeIcon()”と指定してあるので、
「あ」のアイコンをクリックするとchangeIcon()が実行されます。
このchangeIcon関数では、
 

  1. SVGファイル用のxmlを新しく生成して、
  2. それをbase64に変換して、
  3. imgタグのsrcを書き換える

 
という処理をしています。
クリックすると画像が「い」になり数字が2になります。
 
これを利用してアニメーションGIFやswfバナーのようなものをインラインで実装できたり、動的なアイコンがベクター画像で作れたりできます。
と、強引にメリットを絞り出してみますが、こんなまどろっこしい事やるくらいならjavascriptで全部実装した方がシンプルですよね・・
 
ただ、部分的には使うケースが出てきそうそうな機能なので、忘れないようにここに書き記しておきます。