2012年9月28日金曜日

svgでサイズ可変な矢印グラフィックを作る

svgのサイズ可変性を使って勝手にサイズの変わる矢印グラフィックを作ってみた.
実用性が有るかさっぱり分からないけれど,テクニック的にはかなり苦労しているので公開.なんかの役に立つといいなぁ.
9/29修正

なお,環境によって動作しないかも知れないので,動作検証を兼ねたサンプルを載せておこう.

  • object要素



  • img要素



  • background-image
  a
  a
  a

方針
  • 以前公開した「サイズ不定のsvgで右辺下辺を基準とした描画を行う 」のテクニックを使って右側の矢じりを描画するまではそれほど問題ない.
  • 常に矢じりを左(右)端に配置するために,symbol要素にpreserveAspectRatio="xMinYMid meet"を設定する.こうすることで画像の大きさにかかわらず図形の描画位置が固定される.
  • 問題となるのが,線の部分.矢じりの大きさが変化するので、描画の基準点を定めるのが困難なのだ.今回この部分はmask要素で解決することとした.左端から右端まで線を引き,mask要素で矢じりの部分を隠してしまえば良い.
  • ただ,この部分においてmask要素のwidth属性の値が100%だと上手く行かないことが判明した.どうやらmask要素の下のsvg要素がmask要素の範囲外となってしまうと,正しく動作しないようだ.よってmask要素の範囲を拡大して問題を解決した.どうやらx属性とy属性が未設定だったので動作が怪しくなっていたようだ
他のスタイルの矢印についても大体同じパターンで実装できるはず.
    <?xml version="1.0" standalone="no"?>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
     <defs>
      <!--画像サイズに応じ,端っこでリサイズされるようにアスペクト比設定を施す-->
      <symbol id="arrowHead" viewBox="0 0 10 10" preserveAspectRatio="xMinYMid meet">
       <polygon points="0,5 10,0 10,10" stroke-width="0"/>
      </symbol>
      <!--下のマスクで利用する矩形-->
      <symbol id="arrowArea" viewBox="0 0 10 10" preserveAspectRatio="xMinYMid meet">
       <rect width="10" height="10"/>
      </symbol>
      <!--矢じりの部分の線を透明にするマスク-->
      <mask id="arrowAreaMask" maskUnits="userSpaceOnUse" x="0" y="0" width="100%" height="100%">
       <rect width="100%" height="100%" fill="white"/>
       <use xlink:href="#arrowArea" x="0" y="0" width="100%" height="100%"/>
       <svg x="100%" width="100%" height="100%" overflow="visible">
        <use xlink:href="#arrowArea" x="0" y="0" width="100%" height="100%" transform="scale(-1,1)"/>
       </svg>
      </mask>
     </defs>
     <g>
      <!--線の部分-->
      <rect x="0" y="30%" height="40%" width="200%" mask="url(#arrowAreaMask)"/>
      <!--矢じりの左-->
      <use xlink:href="#arrowHead" x="0" y="0" width="100%" height="100%"/>
      <!--矢じりの右-->
      <svg x="100%" width="100%" height="100%" overflow="visible">
       <use xlink:href="#arrowHead" x="0" y="0" width="100%" height="100%" transform="scale(-1,1)"/>
      </svg>
     </g>
    </svg>

    0 件のコメント:

    コメントを投稿