とりあえず波状のベジェ曲線を書いてみます。
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)の座標をつないでいくことで、滑らかなウェーブを描画することができます。
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();
COMMENTS