【SVGタグ】lineタグでstroke-dasharrayとstroke-dashoffsetを使って線を動かす方法|アニメーションで動く線を描く実例

html-kv-prograshi(プロぐらし)-kv HTML
記事内に広告が含まれていることがあります。

SVGタグでlineタグを使うと軽量で縮小/拡大でギザギザにならないキレイな線を描くことができます。

lineタグには様々なCSSが用意されており、その中のdasharrayとstroke-dashoffsetを上手く使うことで線を動かすことができます。

ここでは、そもそもSVGタグのlineタグとは何か?やその使い方も含めて線の動かし方を解説しています。


lineタグとは何か?

lineタグはSVGタグの中で使うことで直線を描くことができます。水平や垂直だけでなく、斜めの線も描くことができます。

設定できる属性は比較的たくさんあります。


必須の属性(x1,y1,x2,y2, stroke)

その中でも必須なのが、始点を指定する(x1,y1)と終点を指定する(x2,y2)とstrokeです。

stroke属性は色を指定します。

lineタグで必須の属性
  • x1: 線の始点のX座標
  • y1: 線の始点のY座標
  • x2: 線の終点のX座標
  • y2: 線の終点のY座標
  • stroke: 線の色


例えば水平方向に直線を引きたければ、y1とy2が同じ値にします。

<svg width="200" height="100">
  <line x1="50" y1="20" x2="150" y2="20" stroke="red"/>
</svg>


stroke-width属性|線の太さ

stroke-width属性を使うことで線の太さを指定することができます。

例えば、stroke-widthを18にすると、線の太さが18pxになります。

<svg width="200" height="100">
  <line x1="50" y1="20" x2="150" y2="20" stroke="red" stroke-width="18"/>
</svg>


stroke-linecap|線の端の形状

stroke-linecap属性は線の端の形状を指定することができます。指定できる値は次の3つです。

  • butt (デフォルト): 線の終端でスパッと切れる。
  • round: 線の終端が丸くなる(太さ分だけ突き出る)。
  • square: 線の終端が四角くなる(太さ分だけ突き出る)。
<svg width="200" height="200">
  <line x1="20" y1="20" x2="150" y2="20" stroke="pink" stroke-width="18" stroke-linecap="butt"/>
  <line x1="20" y1="60" x2="150" y2="60" stroke="lime" stroke-width="18" stroke-linecap="round"/>
  <line x1="20" y1="100" x2="150" y2="100" stroke="lightblue" stroke-width="18" stroke-linecap="square"/>
</svg>


stroke-dasharray|破線

stroke-dasharray属性は破線(点線)にしたいときに使います。値は「線の長さ, 隙間の長さ」のペアで指定します。

例えば、5pxの線と10pxの隙間を交互に繰り返したい場合はstroke-dasharray="5, 10"とします。なお、値を一つの数値で記述した場合は線の長さと隙間の両方に指定した長さが適用されます。

省略した書き方

stroke-dasharray="5" は stroke-dasharray="5, 5" と同じ

<svg width="200" height="200">
  <line x1="20" y1="20" x2="150" y2="20" stroke="pink" stroke-width="18" stroke-linecap="butt" stroke-dasharray="5"/>
  <line x1="20" y1="60" x2="150" y2="60" stroke="orange" stroke-width="18" stroke-linecap="butt" stroke-dasharray="15, 5"/>
  <line x1="20" y1="100" x2="150" y2="100" stroke="lime" stroke-width="18" stroke-linecap="round" stroke-dasharray="5, 25"/>
  <line x1="20" y1="140" x2="150" y2="140" stroke="lightblue" stroke-width="18" stroke-linecap="square" stroke-dasharray="10, 30"/>
</svg>


※注意点|stroke-linecapで破線にならなくなる

stroke-linecap属性で、roundかsquareを指定している場合、破線で区切った両端に指定した図形の分太さが描かれます。

このため、stroke-dasharrayの隙間が狭いと両隣の線がくっついてしまい、破線になっていないように見えます。(実際は破線になっているのですが、くっついているだけです)

例えば、以下の3つの線は全てstroke-dasharray属性が指定してあります。

<svg width="200" height="200">
  <line x1="20" y1="60" x2="150" y2="60" stroke="orange" stroke-width="18" stroke-linecap="round" stroke-dasharray="5,5"/>
  <line x1="20" y1="100" x2="150" y2="100" stroke="lime" stroke-width="18" stroke-linecap="round" stroke-dasharray="5, 15"/>
  <line x1="20" y1="140" x2="150" y2="140" stroke="lightblue" stroke-width="18" stroke-linecap="round" stroke-dasharray="5, 25"/>
</svg>


stroke-dashoffset|破線の開始位置をずらす

stroke-dashoffsetは、stroke-dasharrayとセットで使います。

stroke-dasharrayでセットしたパターンがどこから始まるかを指定します。

例えば、stroke-dasharray=”40, 8″の場合、繰り返しパターンは48pxごとに繰り返されます。

これに、stroke-dashoffset=”10″をつけると、10pxずれて開始します。(破線全体が左に10px移動します)

例えば、上から順にstroke-dashoffsetなし、stroke-dashoffset=”10″、stroke-dashoffset=”30″とした場合以下のようになります。

<svg width="200" height="200">
  <line x1="20" y1="20" x2="200" y2="20" stroke="pink" stroke-width="18" stroke-linecap="butt" stroke-dasharray="40, 8"/>
  <line x1="20" y1="60" x2="200" y2="60" stroke="orange" stroke-width="18" stroke-linecap="butt" stroke-dasharray="40, 8" stroke-dashoffset="10" />
  <line x1="20" y1="100" x2="200" y2="100" stroke="lime" stroke-width="18" stroke-linecap="butt" stroke-dasharray="40, 8"  stroke-dashoffset="30"/>
</svg>



線を動かす方法|stroke-dasharrayとstroke-dashoffset

CSSのアニメーション(@keyframes)で「stroke-dasharray」と「stroke-dashoffset」を使うことで線をオシャレに動かすことができます。


波線を動かし続ける(左から右へ)

例えば、以下のように長さ250px、太さ4pxの赤い破線があるとします。破線の間隔は4pxです。

デフォルトのstroke-dashoffsetは0、すなわち、オフセットはしていない状態です。

<svg class="dash-move" width="300" height="60">
  <line class="red-line" x1="20" y1="30" x2="280" y2="30"
        stroke="red" stroke-width="4"
        stroke-dasharray="10, 10" stroke-dashoffset="0" />
</svg>


これを左から右に動かすには、パターン分の長さ(ここでは20px = 10px + 10px)分、右にずらし、それを繰り返します。

<svg class="dash-move" width="300" height="60">
  <line class="red-line" x1="20" y1="30" x2="280" y2="30"
        stroke="red" stroke-width="4"
        stroke-dasharray="10, 10" stroke-dashoffset="0" />
</svg>

<style>
  .red-line {
    animation: dashMove 0.5s linear infinite;
  }
  @keyframes dashMove {
    from {
      stroke-dashoffset: 0;
    }
    to {
      stroke-dashoffset: -20;
    }
  }
</style>

@keyframesのfromは0%のときのCSS、toは100%のときのCSSを指定しています。

fromつまり0%(開始)では「stroke-dashoffset: 0;」なので、オフセットはありません。

toつまり100%(終了)では「stroke-dashoffset: -20;」なので、右に20pxオフセットします。

これを、0.5秒間隔でlinearな動きで無限に繰り返します(infinite)


波線を動かし続ける(右から左へ)

なお、アニメーションでオフセットさせる方向を左方向「stroke-dashoffset: 20;」にすると、反対向きに動き続ける破線になります。

<svg class="dash-move" width="300" height="60">
  <line class="red-line" x1="20" y1="30" x2="280" y2="30"
        stroke="red" stroke-width="4"
        stroke-dasharray="10, 10" stroke-dashoffset="0" />
</svg>

<style>
  .red-line {
    animation: dashMove 0.5s linear infinite;
  }
  @keyframes dashMove {
    from {
      stroke-dashoffset: 0;
    }
    to {
      stroke-dashoffset: 20;
    }
  }
</style>


左から右に動く線

プログレスバーのように左から右に動く線を描くのも簡単です。

例えば以下のように、長さ260px、幅4pxの青い線があるとします。

デフォルトでは「stroke-dasharray=”260″ stroke-dashoffset=”260″」とし、破線の長さ260pxつまり、x1, x2で指定した線の長さと同じにしています。

<svg class="draw-line" width="300" height="60">
  <line class="blue-line" x1="20" y1="30" x2="280" y2="30"
        stroke="blue" stroke-width="4"
        stroke-dasharray="260" />
</svg>


この要素に対してアニメーションで初期値を「stroke-dashoffset: 260;」にすると、破線の長さと同じ260px分だけ左側にシフトするので見えない状態になります。

これが、終了時に「stroke-dashoffset: 0;」すなわち、線が元のように全て表示されている状態にします。

<svg class="draw-line" width="300" height="60">
  <line class="blue-line" x1="20" y1="30" x2="280" y2="30"
        stroke="blue" stroke-width="4"
        stroke-dasharray="260" stroke-dashoffset="260" />
</svg>

<style>

  .blue-line {
    animation: drawLine 4s ease forwards infinite;
  }
  @keyframes drawLine {
    from {
      stroke-dashoffset: 260;
    }
    to {
      stroke-dashoffset: 0;
    }
  }
</style>


ポイントは「stroke-dasharray」と「stroke-dashoffset」を線の長さと同じpxに設定することです。


右から左に動く線

上記のコードで、初期値from(0%)の「stroke-dashoffset」の値を「-260」にすると、初期状態で右側に線の長さ分シフトしていることになります。

これが、to(100%)になったときに「stroke-dashoffset: 0;」になるので、右から左に動く線になります。

<svg class="draw-line" width="300" height="60">
  <line class="blue-line" x1="20" y1="30" x2="280" y2="30"
        stroke="blue" stroke-width="4"
        stroke-dasharray="260" stroke-dashoffset="260" />
</svg>

<style>

  .blue-line {
    animation: drawLine 4s ease forwards infinite;
  }
  @keyframes drawLine {
    from {
      stroke-dashoffset: -260;
    }
    to {
      stroke-dashoffset: 0;
    }
  }
</style>



左から右に動き、スーッと消えていく線

左から右に動き、そのままスーッと消えていく線をつくることもできます。

0%の初期状態で「stroke-dashoffset: 260;」として、線が左方向に全て隠れた状態にします。

50%で「stroke-dashoffset: 0;」とし、線が全て表示された状態にします。

100%で「stroke-dashoffset: -260」とすることで、線が右方向にシフトした状態になります。

少しオシャレに下にグレーの線を引いて動かすと以下のようになります。

<svg class="line-anim" width="300" height="60" xmlns="http://www.w3.org/2000/svg">
  <!-- グレーの背景線 -->
  <line x1="20" y1="30" x2="280" y2="30"
        stroke="#ccc" stroke-width="4" />

  <!-- アニメーションする線 -->
  <line class="anim-line" x1="20" y1="30" x2="280" y2="30"
        stroke="orange" stroke-width="4"
        stroke-dasharray="260" stroke-dashoffset="260" />
</svg>

<style>
  .anim-line {
    animation: drawAndErase 6s ease forwards infinite;
  }

  @keyframes drawAndErase {
    0% {
      stroke-dashoffset: 260; /* 全部隠れてる */
    }
    50% {
      stroke-dashoffset: 0;   /* 全部描かれた状態 */
    }
    100% {
      stroke-dashoffset: -260; /* 右方向に消える */
    }
  }
</style>


まとめ

SVGタグのlineタグでstroke-dasharrayとstroke-dashoffsetを使うと、プログレスバーや動き続ける破線をとても簡単に作ることができます。

ぜひ試してみて下さい!

タイトルとURLをコピーしました