LoginSignup
17
21

More than 5 years have passed since last update.

スクロールに合わせてパスを描く【SVG + JavaScript】

Last updated at Posted at 2017-02-01

某所で使ったのでメモ。

HTML上にSVGを描画し滑らかなアニメーションをさせるテクニックは最近よく見かけますね。
動くものがあると目を引きますし、なによりSVGだからクライアントの解像度に気を遣う必要がありません。

SVGをアニメーションさせる方法は解説されているサイトが沢山あります。
ここではSVGパスをスクロールに合わせて描画するサンプルを紹介。

まずはサンプルデモを。

デモ

パスの始点から終点まで、スクロールと一致するようになっています。

使うもの : jQuery
スクロールの値を取得するためにjQueryを使用。

html

<div id="stroke">
  <svg id='scroll-line'>
  </svg>
</div>

CSS

(※画面幅に関わらず真ん中に表示するようにしてるだけ)

div#stroke{
        width:100%;
        max-width:1920px;
        height:100%;
        position:relative;
        margin:0 auto;
        overflow:hidden;
}

svg#scroll-line{
        width:100%;
        height:100%;

        position:absolute;
        left:50%;
        margin-left:-960px;
}

JavaScript

//スクロール状態。0で一番上、1で一番下
var scrollPos = 0;
//スクロールできる = 画面から隠れてる範囲
var scrollRange;
var line;
var strokeLength;
var ankerPoint = [960, 0, 960, 950, 800, 950, 800, 850, 900, 850, 900, 2000];

//スクロールの値を取得
$(function() {
        $(window).scroll(function(){
                scrollRange = $(document.body).height() - $(this).outerHeight();
                scrollPos = $(this).scrollTop() / scrollRange;
                line.style.strokeDashoffset = strokeLength - strokeLength * scrollPos;
                line.style.visibility = 'visible';
        });
});

window.onload = function(){
        //パスを定義
        line = document.createElementNS("http://www.w3.org/2000/svg",'path');
        line.setAttribute('d', 'M 960, 0 L ' + ankerPoint.join(','));
        line.setAttribute('fill', 'none')
        line.setAttribute('stroke', '#00eeff');
        strokeLength = line.getTotalLength();
        line.style.strokeDasharray = strokeLength + ' ' + strokeLength;
        line.style.storkeDashoffset = strokeLength;
        line.style.visibility = 'hidden';
        $('#scroll-line').append(line);
}

配列ankerPointで、path要素のMコマンドで使うパスの数値を設定しています。
勿論、svgデータを別で用意しDOMから拾ったり、ベジェ曲線を描くのもアリ。

window.onload以下の

line.style.strokeDasharray = strokeLength + ' ' + strokeLength;
line.style.storkeDashoffset = strokeLength;

この辺りでパスの長さ(strokeLength)分画面から外に追い出しています。

line.style.strokeDashoffset = strokeLength - strokeLength * scrollPos;

上記でパスの長さにスクロール距離のパーセンテージ(scrollPos)をかけています。
一番下までスクロールされた(scrollPosが1になった)ところでstrokaDashoffsetが0になり、パス全体が描かれるというわけです。

うーん、jQuery苦手だなぁ...

17
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
21