9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

地図の吹き出し線がうにょーって伸びるアニメーション

Last updated at Posted at 2015-11-27

Google マップでフッタに表示した画像をホバーすると、うにょーって吹き出し線が伸びていくの知ってます?
それに近いものをやってみたくて作ってみました。

これです。

popup.gif

地図には、オープンソースの地図ライブラリ Leaflet を使います。
Leaflet は Facebook とか Evernote とかメジャー Web サービスに使われてたりします。
見たことないですか?

スクリーンショット 2015-11-27 23.png

話が逸れました。

本題に入りましょう。
吹き出しからでる線をうにょーってマーカーまで引っ張るアニメーションを SVG で作ります。直線が伸びるだけだから簡単なはず。

既存の吹き出し線

スクリーンショット 2015-11-27 23.07.23.png

Leaflet の標準の吹き出しはこんな感じ。
吹き出し線のコンテナは以下の HTML で構成されてました。

<div class="leaflet-popup-tip-container">
  <div class="leaflet-popup-tip"></div>
</div>

leaflet-popup-tip が実際に白い吹き出し線の部分。
正方形の白い <div>transform: rotate(45deg); で 45度回転させて、吹き出し線を表現してるようです。

うにょーって伸びる吹き出し線

<div class="leaflet-popup-tip"></div> を消して、そこに <svg><path> を突っこんでみる。
その際に線が伸びるアニメーションも追加。
SVG の部分は D3 で実装しました。

// 吹き出しの表示イベント
map.on('popupopen', function (e) {
  // 吹き出し線コンテナ DIV に SVG を配置
  var svg = d3.select(".leaflet-popup-tip-container").append("svg")
    .attr({
      class: 'leaflet-popup-tip-svg',
      width: 2,
      height: 100,
  });
  // 吹き出し線グラフィックの作成
  var c1 = [1, 0];
  var c2 = [1, 91];
  var carray = [c1, c2];
  var line = d3.svg.line()
    .x(function(d) {return d[0];})
    .y(function(d) {return d[1];});
  var path = svg.append('path')
    .attr({
      'class': 'leaflet-popup-tip-path',
      'd': line(carray), // SVG 描画範囲での線の頂点座標
      'stroke': 'rgba(255,100,0,0.8)', // 線の色
      'stroke-width': 2, // 線の太さ
      'stroke-dashoffset': 91 // 点線の開始位置 = 線の全長
    })
    .style("stroke-dasharray", "91") // 点線の長さ = 線の全長
    .style("stroke-linecap", "round");
  // アニメーションの実行
  path.transition().delay(300).duration(1000).attr('stroke-dashoffset', 0); 
});

線が伸びるアニメーションは以下の2つで実現されます。

  • stroke-dasharray(点線の長さ): 線の全長と一緒にすると実線になる
  • stroke-dashoffset(点線の開始位置): 線の全長と一緒にすると線がすべてしまわれた状態になり、0 にするとすべてが表示された状態になる

吹き出しが消えると SVG 要素も消え、再び表示されたら同じように SVG 要素が作られ、アニメーションが実行されます。

// 吹き出しを閉じたら SVG 要素を削除
map.on('popupclose', function (e) {
  e.popup._tipContainer.children[1].remove();
});

細かい動きやロジックは、デモソースをご覧ください。

9
7
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
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?