manmanrai’s diary

新米フロントエンジニアの勉強記録ブログ

Canvasの応用(重なる複数の円形にアニメーションとリンク機能)part1

勉強する理由

少し遅いかもしれませんが、いま実案件で先方の要望のより、少し変わった円の上にさらに重なってる斜めの半円形二つ目を作ることになりました。しかも、その変わった形にリンクの機能とアニメーションをつけて欲しいと。

今回はどうしても逃げたくても逃げられない状況です。今まで自分は軽く円とか、四角を書いてみただけのCanvan赤ちゃんレベルなのです。この案件別の担当者やってもらえないのか心で叫んでましたが、実際担当を代わってもらうことはそんなに簡単なことではないので、やっぱり現実と向き合って、一から勉強し直します。

今回の課題

  1. 重なってる要素を順番通り出す
  2. よく見る円グラフみたいなアニメーションの出方
  3. リンクとして押せる、リンク先へ

さらにもう一回細かく分析してみると、

  1. 要素を重なる
  2. 要素を順番通り出す
  3. よく見る円グラフみたいなアニメーションの出方
  4. 要素順番通り出す(アニメーション付きで)
  5. リンクとして押せる、リンク先へ飛べせる

下準備

html

<canvas id="canvasspace" width="480" height="480"></canvas>

目標1.要素を重なる

複数の要素を用意する前に、Canvasの場所を確保します。

var canvasSpace = document.getElementById("canvasspace"),
    width = canvasSpace.width,
    height = canvasSpace.height,
    ctx = canvasSpace.getContext("2d");

円を描く関数を作成します。

function drawArc(x, y, r, color, startAngle, endAngle){
  var counterClockwise = false; 
  //counterClockwiseは逆時計回りです。今回は全部時計回りにします。
  ctx.fillStyle = color;
  //ctx.strokeStyle = color;今回輪郭書きません。

  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.arc(x, y, r, startAngle, endAngle, counterClockwise);
  ctx. fill();
  //ctx.stroke();今回輪郭書きません。
}

関数を使ってみます。

drawArc(240, 240, 200, #ddd, 0, 2 * Math.PI);

灰色の円が出ましたので、次はその円形の上にさらに円形を重ねます。

drawArc(240, 240, 200, "#ddd", 0, 2 * Math.PI); //先ほどの灰色の円
drawArc(240, 240, 100, "#aaa", 0, 2 * Math.PI); //追加した濃い灰色の円

先ほどの灰色の円の上に小さい濃い灰色の円が追加されました。
上記のコードを逆にしたら、濃い灰色の円が見えなくなりました。
というわけで重ね順は、書く順番と同じのようです。

一つ心配事がありまして、もし(アニメーション)出る順と重ね順とは逆だったら、重なられて見えなくなったらどうしましょう。
先ほどの休憩時間で解決策思い付きましたので、書きます。

中抜きすれば重なること心配いりません!

そこで新しい同心円を描く関数を作ってみました。

function drawDounts(x, y, r, color, startAngle, endAngle){
  var counterClockwise = false; //counterClockwiseは逆時計回りです。今回は全部時計回りにします。
  ctx.fillStyle = color;
  ctx.strokeStyle = color;

  ctx.beginPath();
  ctx.moveTo(x, y);
  ctx.arc(x, y, r, startAngle, endAngle, counterClockwise);
  ctx.arc(x, y, r / 2, startAngle, endAngle, "true");
  ctx. fill();
}

drawDounts(200, 200, 100, "pink",0 , 2 * Math.PI);

中抜きのポイントとしては、二つの円のパスの回り方向は逆じゃなければなりません。counterClockwiseはfalseとtrue、時計回りと逆時計回りです。

ここで新たな問題発見しました。もし、同心円じゃなかったら、どうなるんでしょうか。
単純に二番目の円の座標をずらしてみました。

  ctx.arc(x, y, r, startAngle, endAngle, counterClockwise);
  ctx.arc(x - 10, y - 10, r / 2, startAngle, endAngle, "true");

結果、ドーナツがドーナツじゃなくなりました。中抜きの部分に色付いた三角形が出てきました。まさかドーナツ(同心円)じゃないといけないのかと随分悩んだんですが、意外なところで答え見つけました。

それが、中心を移動するってことです。意外とシンプルです。
Canvasで図を描いてる時、よく使うmoveTo();関数です。

  ctx.arc(x, y, r, startAngle, endAngle, counterClockwise);
  ctx.moveTo(x - 10, y - 10);
  ctx.arc(x - 10, y - 10, r / 2, startAngle, endAngle, "true");

なんかネットでどんだけ探しても出てこなかったんですけど、もしかして自分だけ分からなかったのか。。反省します。

この部分の参考サイトはこちら:

qiita.com

devlabo.blogspot.jp

長くなりました。part2で続き書きます。