Blog
canvasのテスト
HTML5の目玉機能(?)、canvas要素とJavascriptでいろいろサンプル作成中。画面をマウスクリックでパーティクルが吸着するよ。
追記:ちょっと修正 (19:30)
Javascriptのソースはこんな感じ。
[sourcecode language=”javascript”]
const NUM = 500; //円の数
const WIDTH = 400; //画面の幅
const HEIGHT = 400; //画面の高さ
var speedX = new Array(NUM); //X方向のスピードの配列
var speedY = new Array(NUM); //Y方向のスピードの配列
var locX = new Array(NUM); //円の中心位置のX座標の配列
var locY = new Array(NUM); //円の中心位置のY座標の配列
var radius = new Array(NUM); //円の半径の配列
var r = new Array(NUM); //Red成分の配列
var g = new Array(NUM); //Green成分の配列
var b = new Array(NUM); //Blue成分の配列
var ctx; //描画コンテキスト
var mouseX, mouseY; //マウス座標
var mouseMoved = false; //マウスが移動しているか否か
var mouseDown = false; //マウスクリックしているか否か
//ばねのパラメーター
var stiffness = 0.03, damping = 0.99, mass = 10.0;
window.onload = function() {
setup();
};
function setup(){
var canvas = document.getElementById(‘tutorial’);
if (canvas.getContext){
ctx = canvas.getContext(‘2d’);
//イベントリスナー:マウス移動
canvas.onmousemove = mouseMoveListner;
canvas.onmousedown = mouseDownListner;
canvas.onmouseup = mouseUpListner;
//初期値を生成して配列に格納
for(var i = 0; i < NUM; i++){
locX[i] = WIDTH / 2;
locY[i] = HEIGHT / 2;
radius[i] = Math.random() * 6.0 + 2.0;
r[i] = Math.floor(Math.random() * 32);
g[i] = Math.floor(Math.random() * 64);
b[i] = Math.floor(Math.random() * 128);
}
//スピード初期化
randomVector();
//60fps
setInterval(update, 1000.0/60.0);
}
}
function update(){
//もしマウスクリックしていたらばねの動きでマウスに吸着
if(mouseDown){
for(var i = 0; i < NUM; i++){
var forceX = stiffness * (mouseX – locX[i]);
var accelerationX = forceX / mass;
speedX[i] = damping * (speedX[i] + accelerationX);
var forceY = stiffness * (mouseY – locY[i]);
var accelerationY = forceY / mass;
speedY[i] = damping * (speedY[i] + accelerationY);
}
}
//座標を更新
for(var i = 0; i < NUM; i++){
locX[i] += speedX[i];
locY[i] += speedY[i];
if(getLength(locX[i], locY[i], WIDTH/2 , HEIGHT/2) > WIDTH*0.75){
speedX[i] *= -1;
speedY[i] *= -1;
}
}
//drawを実行
draw();
}
function draw(){
//背景を描画
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "rgba(0,0,0,.1)";
ctx.fillRect(0, 0, WIDTH, HEIGHT);
//更新した座標で円を描く
ctx.globalCompositeOperation = "lighter";
for(var i = 0; i < NUM; i++){
ctx.beginPath();
ctx.fillStyle = ‘rgba(‘ + r[i] + ‘,’ + g[i] + ‘,’ + b[i] + ‘, 0.8)’;
ctx.arc(locX[i], locY[i], radius[i], 0, Math.PI*2.0, true);
ctx.fill();
}
}
function mouseMoveListner(e) {
//画面左上からのマウス座標取得
adjustXY(e);
//マウスを移動中に
mouseMoved = true;
}
function mouseDownListner(e) {
mouseDown = true;
}
function mouseUpListner(e) {
mouseDown = false;
randomVector();
}
//ランダムな方向にスピード設定
function randomVector(){
for(var i = 0; i < NUM; i++){
var length = Math.random() * 1.0 + 2.0;
var angle = Math.random() * Math.PI * 2.0;
speedX[i] = Math.cos(angle) * length;
speedY[i] = Math.sin(angle) * length;
}
}
//二点間の距離
function getLength(x1 , y1 , x2 , y2 ) {
var pointLength;
pointLength = Math.sqrt(Math.pow(x2 – x1 , 2 )+Math.pow(y2 – y1 , 2 ));
return pointLength;
}
//画面左上からのマウス座標を求める
function adjustXY(e) {
var rect = e.target.getBoundingClientRect();
mouseX = e.clientX – rect.left;
mouseY = e.clientY – rect.top;
}
[/sourcecode]