HTMLのCanvasを利用してキラキラさせてみました。
こんな感じになりました。
処理が重いのでマシンスペックが低い場合は注意してください。。
Canvasを2つ用意して、片方は「display:none;」にして見えなくしています。
以下、ソースです。
HTMLのソース(index.html)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<title>Canvas sample 01 Simple 3D Pixels with KIRAKIRA !.</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">
<p>Source code is <a href = "src.zip">Here.</a></p>
<p>AS3 version: <a href="http://wonderfl.net/c/rwYK">キラキラPixel3D! - wonderfl build flash online</a></p>
<canvas id="sCanvas" width="300" height="200"></canvas>
<canvas id="mainCanvas" width="600" height="400"></canvas>
</div>
</body>
</html>
JavaScriptのソース(script.js)
// 計算用の定数
var N_POINT=3000;
var RADIUS = 100;
var RADIAN = Math.PI / 180;
var FOCUS = 280;
var A1 = 4.5;
var A2 = 1/4.5;
// 変数
var center_x;
var center_y;
var points;
var bmpd;
var bmpdArray;
var theta;
var i, j, p, xx, yy, zz, scale;
var mainCanvas;
var mainContext;
var sCanvas;
var sContext;
var mainWidth;
var mainHeight;
var sWidth;
var sHeight;
window.onload = function()
{
mainCanvas = document.getElementById('mainCanvas');
sCanvas = document.getElementById('sCanvas');
if (! mainCanvas || ! mainCanvas.getContext || ! sCanvas || ! sCanvas.getContext) {return false;}
else
{
mainWidth = mainCanvas.width;
mainHeight = mainCanvas.height;
sWidth = sCanvas.width;
sHeight = sCanvas.height;
center_x = (mainWidth * 0.5) | 0;
center_y = (mainHeight * 0.5) | 0;
theta = 0;
points = [];
// contextの初期化
mainContext = mainCanvas.getContext('2d');
sContext = sCanvas.getContext('2d');
// 3Dポイントの初期化
var theta1, theta2;
for(i=0; i < N_POINT; i++)
{
theta1=360 * Math.random() * RADIAN;
theta2=(180 * Math.random() - 90) * RADIAN;
xx = RADIUS * Math.cos(theta2) * Math.sin(theta1);
yy = RADIUS * Math.sin(theta2);
zz = RADIUS * Math.cos(theta2) * Math.cos(theta1);
points[i]=new Point3D(xx, yy, zz, "#00FF00");
}
// レンダリング開始
setInterval("onFrame()", 30);
}
}
function onFrame()
{
mainContext.globalCompositeOperation = "source-over";
mainContext.fillStyle = "#000000";
mainContext.fillRect(0,0,mainWidth, mainHeight);
mainContext.globalCompositeOperation = "lighter";
bmpd = mainContext.getImageData(0, 0, mainWidth, mainHeight);
bmpdArray = bmpd.data;
for(i=0 ; i < N_POINT; i++)
{
p=points[i];
// 回転行列で回転 (x軸回転とy軸回転の積を展開したもの)
xx=p.x * Math.cos(theta * RADIAN) + p.y * Math.sin(theta * RADIAN) * Math.sin(theta * RADIAN) - p.z * Math.sin(theta * RADIAN) * Math.cos(theta * RADIAN);
yy=p.y * Math.cos(theta * RADIAN) + p.z * Math.sin(theta * RADIAN);
zz=p.x * Math.sin(theta * RADIAN) - p.y * Math.sin(theta * RADIAN) * Math.cos(theta * RADIAN) + p.z * Math.cos(theta * RADIAN) * Math.cos(theta * RADIAN);
scale = FOCUS * 1.5 / (FOCUS - zz);
xx = ((xx * scale)|0) + center_x;
yy = ((yy * scale)|0) * (-1) + center_y;
// 範囲内なら点を打つ
if (xx >= 0 && yy >= 0 && xx < mainWidth && yy < mainHeight)
{
j = (yy * mainWidth + xx)*4;
bmpdArray[j] = p.cR;
bmpdArray[j + 1] = 255;
bmpdArray[j + 2] = p.cB;
bmpdArray[j + 3] = 255;
}
}
mainContext.putImageData(bmpd,0,0);
theta ++;
// キラキラ用のCanvas作成
sContext.fillStyle = "#000000";
sContext.fillRect(0,0,sWidth, sHeight);
sContext.scale(A2,A2);
sContext.drawImage(mainCanvas, 0, 0);
sContext.scale(A1,A1);
// キラキラ
mainContext.scale(A1,A1);
mainContext.drawImage(sCanvas, 0, 0);
mainContext.scale(A2,A2);
}
function Point3D(x, y, z, color)
{
this.x = x;
this.y = y;
this.z = z;
this.cR = Math.random() * 255;
this.cB = Math.random() * 255;
}
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: 600px;
height:500px;
margin-top:100px;
margin-left : auto;
margin-right : auto ;
}
#mainCanvas {
margin-top:5px;
border: 1px solid #777777;
}
#sCanvas {
display:none;
}
