SVGでボタンの枠線アニメーション

一般的にボタンの枠線のアニメーションはCSSのborderを使う。
CSSだけで完結するので見やすく便利だが、角丸で2点から囲うようなアニメーションを作ろうと思ったらCSSでは難しそうなのでSVGでやってみた。

サンプル


なんで線を描くだけでSVGを使うかというと破線の間隔(stroke-dasharray)や開始位置(stroke-dashoffset)といった設定が可能な為だ。
SVGを背景にするとアニメーションの設定が出来ないのでインラインSVGにしたが、都度HTMLに挟み込むのは面倒なのでjavascriptで配置する事にした。
ここで難所が現れた何故か埋め込んでも現れないのだ、開発ツール上ではあるのに現れず、CSSも適応されていない。
javascriptで通常何か要素を作る時は「createElement」を使うが、svgのような名前空間を持つ要素を作成する場合は「createElementNS」を使うらしい。

var navs = document.body.querySelectorAll('a.anirect');
navs.forEach(function(nav) {
  var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
  rect.setAttribute("x", "0.5");
  rect.setAttribute("y", "0.5");
  rect.setAttribute("rx", "3");
  rect.setAttribute("ry", "3");
  rect.setAttribute("width", nav.clientWidth - 1);
  rect.setAttribute("height", nav.clientHeight - 1);
  var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
  svg.setAttribute("viewBox", "0 0 "+nav.clientWidth+" "+nav.clientHeight);
  svg.appendChild(rect);
  nav.appendChild(svg);
});

次にCSSですが98というのは要素の高さと幅の合計です。

a.anirect {
	color:#FFF;
	text-decoration: none;
	padding: 5px;
	font-size: 12px;
	display: block;
	position: relative;
}
a.anirect svg {
	position: absolute;
	top: 0;left: 0;
	display:block;
	pointer-events: none;
}
a.anirect svg rect {
	fill:none;
	stroke:#FFF;
	stroke-dasharray: 0 98;
	stroke-dashoffset: -40;
	stroke-width: 1;
	transition: stroke-dasharray 500ms 0s ease;
}
a.anirect:hover svg rect {
	stroke-dasharray: 98 0;
}

Tags: ,

トラックバック

コメントを書く