HTMLのCanvasで、ブラーなボールの描写。
jsdo.itにサンプルがたくさんあって助かりました。
今回は、以下のプログラムを参考にしました。
今回作ったのはこんな感じです。
うーんあんまりヌルヌル動くわけではない・・。
以下、ソースです。
HTMLのソース(index.html)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<title>Canvas sample 05 draw circle.</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<link rel="stylesheet" type="text/css" href="style.css"/>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="wrapper">
<canvas id="myCanvas" width="500" height="400"></canvas>
<p>Source code is <a href = "src.zip">Here.</a></p>
<p>AS3 version: <a href="http://wonderfl.net/c/75fv">マウスから逃げる - wonderfl build flash online</a></p>
</div>
</body>
</html>
JavaScriptのソース(script.js)
var MARGIN = 100;
var NUM_CIRCLE = 50;
var RADIUS = 30;
var PADDING = 50;
var width;
var height;
var context;
var mouxeX;
var mouseY;
var start;
var func;
window.onload = function()
{
var canvas = document.getElementById('myCanvas');
if (! canvas || ! canvas.getContext ) {return false;}
else
{
width = canvas.width;
height = canvas.height;
context = canvas.getContext('2d');
// 背景を黒にする。
context.beginPath();
context.fillStyle = "#000000";
context.fillRect(0,0,width, height);
// circleの初期化
var prev = new Circle(((width-PADDING*2)*Math.random() + PADDING)|0, ((height-PADDING*2)*Math.random() + PADDING)|0);
start = prev;
var i = 0;
var c;
while(++i <= NUM_CIRCLE)
{
c = new Circle((width*Math.random())|0, (height*Math.random())|0);
prev.next=c;
prev=c;
}
// マウス座標を取得する準備
mouseX = mouseY = 0;
canvas.onmousemove = function(e){
var stageW = document.documentElement.clientWidth;
if(e) {
mouseX = e.pageX;
mouseY = e.pageY;
}
else {
mouseX = event.x + document.body.scrollLeft;
mouseY = event.y + document.body.scrollTop;
}
mouseY -= MARGIN;
if(width < stageW ){ mouseX -= ((stageW - width)*0.5|0);}
};
// レンダリング開始
func = setInterval("onFrame()", 30);
}
}
function onFrame()
{
context.globalCompositeOperation = "source-over";
context.beginPath();
context.fillStyle = "rgba(0,0,0,1)";
context.fillRect(0,0,width, height);
context.globalCompositeOperation = "lighter";
// 各circleの座標更新
var c = start;
while(true)
{
c.update(mouseX, mouseY);
c = c.next;
c.update(mouseX, mouseY);
c = c.next;
c.update(mouseX, mouseY);
c = c.next;
c.update(mouseX, mouseY);
c = c.next;
c.update(mouseX, mouseY);
c = c.next;
c.update(mouseX, mouseY);
c = c.next;
c.update(mouseX, mouseY);
c = c.next;
c.update(mouseX, mouseY);
c = c.next;
c.update(mouseX, mouseY);
c = c.next;
c.update(mouseX, mouseY);
c = c.next;
if(c == null) break;
}
}
var Circle = function(x, y)
{
this.fx = x;
this.fy = y;
this.x = x;
this.y = y;
this.next = null;
this.cR = 255* Math.random() | 0;
this.cG = 255;
this.cB = 255* Math.random() | 0;
}
Circle.prototype.update = function(mX, mY)
{
var theta = Math.atan2(this.y - mY, this.x - mX);
var d = 1000 / Math.sqrt((mX - this.x)*(mX - this.x) + (mY - this.y)*(mY - this.y));
this.x += d * Math.cos(theta) + (this.fx - this.x) * 0.1;
this.y += d * Math.sin(theta) + (this.fy - this.y) * 0.1;
var edgecolor1 = "rgba(" + this.cR + "," + this.cG + "," + this.cB + ",0.93)";
var edgecolor2 = "rgba(" + this.cR + "," + this.cG + "," + this.cB + ",0.6)";
var edgecolor3 = "rgba(" + this.cR + "," + this.cG + "," + this.cB + ",0.1)";
var edgecolor4 = "rgba(" + this.cR + "," + this.cG + "," + this.cB + ",0)";
var gradblur = context.createRadialGradient(this.x, this.y, 0, this.x, this.y, RADIUS);
gradblur.addColorStop(0,edgecolor1);
gradblur.addColorStop(0.4,edgecolor1);
gradblur.addColorStop(0.7,edgecolor2);
gradblur.addColorStop(0.9,edgecolor3);
gradblur.addColorStop(1,edgecolor4);
context.beginPath();
context.fillStyle = gradblur;
context.arc(this.x, this.y, RADIUS, 0, Math.PI*2, false);
context.fill();
}
CSSのソース(style.css)
*{
margin:0;
padding:0;
border: none;
text-decoration:none;
list-style:none;
font-size:100%;
font-style:normal;
font-weight:normal;
}
a:link
{
text-decoration:underline;
color: #289000;
}
a:visited
{
text-decoration:underline;
color: #599000;
}
a:hover
{
text-decoration:underline;
color: #982000;
}
a:active
{
text-decoration:underline;
color: #599000;
}
body {
text-align:left;
background-color:#ffffff;
}
#wrapper {
font-size:14px;
color: #555555;
width: 500px;
height:500px;
margin-top:100px;
margin-left : auto;
margin-right : auto ;
}
#myCanvas {
margin-top:5px;
background-color: #DDDDDD;
border: 1px solid #777777;
}
