Snap.svg、すごいですよね。
あれでアニメーション作るとめちゃ楽しいですね。
さて、遊んでいる時に、困ったことがあり、数十分作業が止まったので、それの解決方法をメモしておきます。
環境
- Snap.svg 0.5.1 (読み込んで使用)
- Firefox 57.0.1 (表示用ブラウザ)
- InkScape 0.92 (パス作成用)
内側が思ったように塗り分けられなかった
問題のPath図形
問題のPath図形は以下の様なものです。長いので、以後省略
と書きます。
(パスが異常に長いのは、趣味垢用に作っていたものの流用なので許してください。)
m 208.90541,109.29049
a 2.776174,1.2825703 56.427847 0 1 0.17457,2.82556 2.776174,1.2825703 56.427847 0 1 -2.63953,-1.92948 2.776174,1.2825703 56.427847 0 1 -0.17457,-2.82557 2.776174,1.2825703 56.427847 0 1 2.63953,1.92949
z
m -7.6781,-9.03334
c -1.38619,7.72423 -0.87929,12.29629 2.92643,15.66947 3.63687,2.44904 6.89158,-0.27701 7.59069,-3.58952 l 7.31827,3.98818 -3.91191,-7.35347 c 4.18733,-0.94355 5.73619,-4.5737 3.68133,-7.54654 -3.13739,-3.778909 -8.23264,-4.527779 -15.63278,-3.116419 -0.0367,0.008 0.48808,-1.9531 0.48808,-1.9531 0.70114,-0.23214 2.17497,-0.7302 2.17431,-1.07625 -0.003,-0.31091 -2.15625,-0.73908 -2.15625,-0.73908 -0.4811,0.26621 -1.18982,1.43616 -1.95937,2.67939 -0.94574,-0.51419 -2.17534,-1.16488 -2.49479,-0.88413 -0.24015,0.24378 0.29808,1.47343 0.9046,2.45516 0,0 -2.71018,1.650499 -2.70297,1.926699 0.043,0.0607 0.41039,2.18349 0.72963,2.16888 0.32026,-0.006 0.9949,-1.77835 1.08578,-2.16491 0,0 2.00074,-0.47543 1.95888,-0.46435
z
m 10.86239,5.84155
a 2.7761738,1.2825702 34.267371 0 0 2.82323,0.20883 2.7761738,1.2825702 34.267371 0 0 -1.89732,-2.66272 2.7761738,1.2825702 34.267371 0 0 -2.82323,-0.20885 2.7761738,1.2825702 34.267371 0 0 1.89732,2.66274
z
InkScapeで以下のようなSVGファイルを作り、読み込みました。
sample_risou.html
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="420px" height="297px" style="background-color:#B2243C"> <path
id="path8443-6-3"
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.29069689;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
d="省略"
inkscape:connector-curvature="0"
inkscape:label="center_icon" /></svg>
うまく行かなかったソース
sample.html
<script src="./snap.svg.js"></script>
<svg id="p" version="1.1" xmlns="http://www.w3.org/2000/svg"
width="420px" height="297px"
style="background-color:#B2243C">
</svg>
このSVGに以下のようなソースでパス図形を表示させます。
sample.js
Snap("#p").path(省略).attr({
"fill":'#ffffff'
})
で、longpath
ですが、
これを作画してみると、以下のようになってしまいます。
穴が一つしか空いていません。
これは大きな問題です。
原因
InkScapeが生成したSVGファイルの、長ったらしいstyle属性の中身に原因がありました。
opacity:1;
fill:#ffffff;
fill-opacity:1;
fill-rule:evenodd;
stroke:none;
stroke-width:0.29069689;
stroke-linecap:round;
stroke-linejoin:miter;
stroke-miterlimit:4;
stroke-dasharray:none;
stroke-dashoffset:0;
stroke-opacity:1;
paint-order:fill markers stroke
多くは大したことのないデータですが、問題はこれの
fill-rule:evenodd;
です。
これをうまくいかなかったJavaScriptに、
sample.js
Snap("#p").path(省略).attr({
"fill":'#ffffff',
"fill-rule":"evenodd"
});
このようにいれてやると、思った通りに表示されました。
解説
そもそも、何故、一つのパス図形で、内側でくり抜かれるという表現ができるかというと、SVGが"内側"についてのルールを定めているからなんです。
そのルールを指定してあげるのが、このfill-rule
でした。
SVG仕様(日本語訳)の当該説明箇所
自動生成で過剰に生成される長いソースの中に、とても重要な情報が含まれていることもあるので注意しよう、という話でした。