見出し画像

Canvas+JavaScriptで同心円上を等速円運動する円を描いた話

はじめに

JavaScriptとCanvasの練習がてら、同心円上を等速円運動する円を描いて遊びました。

具体的には下記を実装してみました。
・同心円上に小さい円を配置する
・小さい円を等速円運動させる

html

ヘッダー画像のページを作ります。
canvasが上下中央に配置されるように、body要素に高さを指定(横幅は勝手にされる)。flexを指定して子要素のcanvasが上下中央に来るようにしました。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Circle guruguruguru</title>
    <style>
        body{
            margin: 0px;
            padding: 0px;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }  
  </style>
</head>
<body>
    <canvas id="canvas"></canvas>    
    <script type="text/javascript" src="main.js"></script>
</body>
</html>

JavaScript

draw関数を10msecごとに描写(つまり100fpsで描写)しています。
draw関数を1回呼ぶごとに、drawCircle関数を13個呼んで、13個の小さい円が表示されるようにします。
小さい円は(x,y)座業を (x-r*sin(t), y-r*cos(t))のような形で指定することで、円運動をさせます。

"use strict";

// async/awaitでループ中にスリープしつつ
// draw関数を呼び出す
(async () => {
    let i = 3;
    while (true) {
        draw(i);
        await wait(10);	// 10ミリ秒ごとに描写
        i++;
    }
})();
function wait(msec) {
    return new Promise(resolve => setTimeout(resolve, msec));
}

// 動く円を描写
function drawCircle(ctx, i, j, h, w, r, cr, cg, cb, ca){
    ctx.beginPath();
    ctx.arc(h/2 - j*r*Math.sin(2*Math.PI/360 * i),
            w/2 - j*r*Math.cos(2*Math.PI/360 * i), 
            r,
            0,
            2*Math.PI);         // 円描写(x, y, r, start Rad,end Rad)
    ctx.fillStyle = "rgba("+cr+", "+cg+", "+cb+", "+ca+")" ;// 塗りつぶしの色
    ctx.fill() ;// 塗りつぶしを実行
}
// 頂点数vertices、頂点を(skip-1)個飛ばしで繋いだ図を描写する
function draw(i) {
    console.log(i);

    // パラメータ
    const height = 1000;
    const width  = 1000;
    const radius = Math.min(height, width)/2*0.03;

    // canvasのお作法
    const cvs = document.getElementById('canvas');  // canvas要素への参照の取得
    const ctx = canvas.getContext('2d');            // コンテキストの取得
    cvs.width = width;
    cvs.height = height;

    // 円を描写
    drawCircle(ctx, i*0.1,  0, height, width, radius,  44,  33, 222, 0.75);
    drawCircle(ctx, i*0.2,  2, height, width, radius,  54,  44, 222, 0.75);
    drawCircle(ctx, i*0.3,  4, height, width, radius,  65,  56, 222, 0.75);
    drawCircle(ctx, i*0.4,  6, height, width, radius,  75,  67, 222, 0.75);
    drawCircle(ctx, i*0.5,  8, height, width, radius,  86,  78, 222, 0.75);
    drawCircle(ctx, i*0.6, 10, height, width, radius,  96,  89, 222, 0.75);
    drawCircle(ctx, i*0.7, 12, height, width, radius, 107, 100, 222, 0.75);
    drawCircle(ctx, i*0.8, 14, height, width, radius, 117, 111, 222, 0.75);
    drawCircle(ctx, i*0.9, 16, height, width, radius, 128, 122, 222, 0.75);
    drawCircle(ctx, i*1.0, 18, height, width, radius, 138, 133, 222, 0.75);
    drawCircle(ctx, i*1.1, 20, height, width, radius, 149, 144, 222, 0.75);
    drawCircle(ctx, i*1.2, 22, height, width, radius, 159, 155, 222, 0.75);
    drawCircle(ctx, i*1.3, 24, height, width, radius, 170, 167, 222, 0.75);
}

この記事が気に入ったらサポートをしてみませんか?