WebWedge.jpg

phpとかJSとか適当に書いています。

canvasで波の表現を作る

とりあえず波状のベジェ曲線を書いてみます。

var stageWidth = 500;
var stageHeight = 150;
var point_limit = 10;
var subpath = []; // サブパスの座標
var i = 0;
for(i=0; i<point_limit; i++) {
    subpath[i] = {
        x : stageWidth / point_limit * i,
        y : stageHeight / 2 + 50 * ((i%2==0) ? 1 : -1)
    }
}

var canvas = document.getElementById("wave_sample1");
var ctx = canvas.getContext('2d');
ctx.lineWidth = 1;
ctx.strokeStyle  = "#f00";
ctx.beginPath();
ctx.moveTo(0,stageHeight / 2);
for(i=0; i<subpath.length-1; i++) {
    ctx.quadraticCurveTo(
        subpath[i].x,
        subpath[i].y,
        (subpath[i+1].x + subpath[i].x) / 2,
        (subpath[i+1].y + subpath[i].y) / 2
    )
}

ctx.stroke();

波を描くには制御点と中継点の座標を確定するのが一見難しそうですが、quadraticCurveTo()で描かれるベジェ曲線は制御点が1点のみなので、制御点(n)と制御点(n+1)の平均値から求められる中間座標(n)の座標をつないでいくことで、滑らかなウェーブを描画することができます。

wave

SAMPE1の各点のY座標をランダムにしてみます。
ランダムでも曲線が滑らかにつながることが確認できます。


ランダム値をリロード

var stageWidth = 500;
var stageHeight = 150;
var point_limit = 10;
var subpath = []; // サブパスの座標

var i = 0;
for(i=0; i<point_limit; i++) {
    subpath[i] = {
        x : stageWidth / point_limit * i,
        y : stageHeight / 2 + (Math.random() * 45 + 5) * ((i%2==0) ? 1 : -1)
    }
}


var canvas = document.getElementById("wave_sample2");
var c = canvas.getContext('2d');
ctx.lineWidth = 1;
ctx.strokeStyle  = "#f00";
ctx.beginPath();
ctx.moveTo(0,stageHeight / 2);
for(i=0; i<subpath.length-1; i++) {
    ctx.quadraticCurveTo(
        subpath[i].x,
        subpath[i].y,
        (subpath[i+1].x + subpath[i].x) / 2,
        (subpath[i+1].y + subpath[i].y) / 2
    )
}

ctx.stroke();

さらにアニメーションさせても同様です。

var ctx;
var stageWidth = 500;
var stageHeight = 150;
var point_limit = 10;
var subpath = []; // サブパスの座標
var deg = 0;

function init() {

    var i = 0;
    for(i=0; i<point_limit; i++) {
        subpath[i] = {
            x : stageWidth / point_limit * i,
            y : Math.random() * 50 * ((i%2==0) ? 1 : -1),
            d : 0,
            c : (i%2==0) ? true : false
        }
    }
    var canvas = document.getElementById("wave_sample3");
    var c = canvas.getContext('2d');
    ctx = c;
    add();
}

function add() {

    ctx.lineWidth = 1;
    ctx.strokeStyle  = "#f00";
    ctx.beginPath();
    var rad = getRad(deg);
    ctx.moveTo(0,stageHeight / 2);
    for(i=0; i<subpath.length-1; i++) {
        var dx = subpath[i].x;
        var dy = Math.cos(rad) * subpath[i].y + stageHeight / 2;
        var dx2 = subpath[i+1].x;
        var dy2 = Math.cos(rad) * subpath[i+1].y + stageHeight / 2;
        var x = (dx2 + dx) / 2;
        var y = (dy2 + dy) / 2; ctx.quadraticCurveTo( dx, dy, x, y ) subpath[i].d += 10;            
    }
    ctx.stroke();
    setTimeout(reload, 100)
}

function reload() {
    deg += 10; if(deg >= 360) deg = 0;
    ctx.clearRect(0,0,500,150);
    add()
}

function getRad(num){
    return num * Math.PI / 180;
}

init();

Categories

Javascript, コーディングとか

COMMENTS

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です