サイトトップ

Director Flash 書籍 業務内容 プロフィール

ROKUNANA WORKSHOP

JavaScriptインタラクティブアニメーション講座

ID: FR100802 Product: Flash CS4 and above Platform: All Version: 10 and above/ActionScript 3.0


01 Canvasを使ったオシロスコープ − sinカーブのアニメーション

サンプル001■Simple sin wave animation with Canvas

canvas要素を使う(「<canvas>要素で定めた領域に図形を描く」参照)。

<body onLoad="initialize()">
  <canvas id="myCanvas" width="240" height="180"></canvas>
</body>

getContext()メソッドで2Dコンテキストを得る。

var context2D;
var nWidth;
var nHeight;
function initialize() {
  var canvasElement = document.getElementById("myCanvas");
  context2D = canvasElement.getContext("2d");
  nWidth = canvasElement.width;
  nHeight = canvasElement.height;
  console.log(nWidth, nHeight);
}

<style type="text/css">
  canvas {background-color:black;}
</style>

Canvasに直線を描く。

2Dコンテキスト.beginPath();
2Dコンテキスト.strokeStyle = カラー;
2Dコンテキスト.moveTo(x座標, y座標);
2Dコンテキスト.lineTo(x座標, y座標);

図001■Canvasの垂直方向真ん中に水平線が引かれる
図001

  1. var context2D;
  2. var nWidth;
  3. var nHeight;
  4. var startX = 0;
  5. var startY;
  1. var radius = 70;
  2. var theta = 0;
  3. function initialize() {
  4.   var canvasElement = document.getElementById("myCanvas");
  5.   context2D = canvasElement.getContext("2d");
  6.   nWidth = canvasElement.width;
  7.   nHeight = canvasElement.height;
  8.   startY = nHeight / 2;
      start(startX, startY);
      drawWave(nWidth, startY);
  1. }
  2. function start(nX, nY) {
  3.   context2D.beginPath();
  4.   context2D.strokeStyle = "#00FF00";
  5.   context2D.moveTo(nX, nY);
  6. }
  1. function drawWave(nX, nY) {
  1.   context2D.lineTo(nX, nY);
  1.   context2D.stroke();
  2. }

Canvasにsinカーブを描く(「sinとcosは何する関数?」参照)。

図002■sinやcosはバネや波の動きを表す
図002

【波の動き】
y = 半径×sin(角度)
x = 等速(時間に比例)
*Wikipedia「Harmonic oscillator」より引用。

図003■Canvasにsinカーブが描かれる
図003

  1. var context2D;
  2. var nWidth;
  3. var nHeight;
  4. var startX = 0;
  5. var startY;
  1. var radius = 70;
  2. var theta = 0;
  3. function initialize() {
  4.   var canvasElement = document.getElementById("myCanvas");
  5.   context2D = canvasElement.getContext("2d");
  6.   nWidth = canvasElement.width;
  7.   nHeight = canvasElement.height;
  8.   startY = nHeight / 2;
      // start(startX, startY);
      // drawWave(nWidth, startY);

      drawWave();
  1. }
  2. function start(nX, nY) {
  3.   context2D.beginPath();
  4.   context2D.strokeStyle = "#00FF00";
  5.   context2D.moveTo(nX, nY);
  6. }
    // function drawWave(nX, nY) {
  1. function drawWave() {
  2.   var pitch = 1;
  3.   var angle = theta;
  4.   var nY = startY + Math.sin(angle) * radius;
  5.   start(startX, nY);
  6.   for (var nX = startX + pitch; nX < nWidth; nX += pitch) {
  7.     angle += 0.07;
  8.     nY = startY + Math.sin(angle) * radius;
  9.     context2D.lineTo(nX, nY);
  10.   }
  11.   context2D.stroke();
  12. }

window.requestAnimationFrame()メソッドで波を水平に動かす(コード001)。

  1. var endX;
  1. function initialize() {
  1.   requestAnimationFrame(moveWave);
  2. }
  1. function moveWave(timestamp) {
  2.   context2D.clearRect(0, 0, nWidth, nHeight);
  3.   drawWave();
  4.   requestAnimationFrame(moveWave);
  5.   theta -= 0.05;
  6.   if (theta < 0) {
  7.     theta += Math.PI * 2;
  8.   }
  9. }
コード001■Canvasに描くsinカーブをオシロスコープのようにアニメーションさせる
  1. var context2D;
  2. var nWidth;
  3. var nHeight;
  4. var startX = 0;
  5. var startY;
  6. var endX;
  7. var radius = 70;
  8. var theta = 0;
  9. function initialize() {
  10.   var canvasElement = document.getElementById("myCanvas");
  11.   context2D = canvasElement.getContext("2d");
  12.   nWidth = canvasElement.width;
  13.   nHeight = canvasElement.height;
  14.   startY = nHeight / 2;
  15.   requestAnimationFrame(moveWave);
  16. }
  17. function start(nX, nY) {
  18.   context2D.beginPath();
  19.   context2D.strokeStyle = "#00FF00";
  20.   context2D.moveTo(nX, nY);
  21. }
  22. function moveWave(timestamp) {
  23.   context2D.clearRect(0, 0, nWidth, nHeight);
  24.   drawWave();
  25.   requestAnimationFrame(moveWave);
  26.   theta -= 0.05;
  27.   if (theta < 0) {
  28.     theta += Math.PI * 2;
  29.   }
  30. }
  31. function drawWave() {
  32.   var pitch = 1;
  33.   var angle = theta;
  34.   var nY = startY + Math.sin(angle) * radius;
  35.   start(startX, nY);
  36.   for (var nX = startX + pitch; nX < nWidth; nX += pitch) {
  37.     angle += 0.07;
  38.     nY = startY + Math.sin(angle) * radius;
  39.     context2D.lineTo(nX, nY);
  40.   }
  41.   context2D.stroke();
  42. }

02 CreateJSで3次元座標を扱う

<script src="http://code.createjs.com/easeljs-0.8.0.min.js"></script>

02-01 星形を3次元空間で水平に回す

サンプル002■EaselJS 0.8.0: Rotating coordinates with the Matrix2D.transformPoint() method

gihyo.jp連載「HTML5のCanvasでつくるダイナミックな表現―CreateJSを使う」
第15回「Matrix2Dクラスで座標を回す
第16回「3次元空間で座標を回す
第17回「簡単なクラスを定義する

図004■頂点数および山と谷の半径で描く星形を定める
図004

【距離と角度から座標を求める】
x = 距離×cos角度
y = 距離×sin角度

図004-2■原点から距離が1で角度θのxy座標は(cosθ, sinθ)
図004-2

  1. function draw(points) {
  2.   var count = points.length;
  3.   var point = points[count - 1];
  4.   drawGraphics.clear()
  5.   .beginStroke("mediumblue")
  6.   .setStrokeStyle(3)
  7.   .moveTo(point.x, point.y);
  8.   for (var i = 0; i < count; i++) {
  9.     point = points[i];
  10.     drawGraphics.lineTo(point.x, point.y);
  11.   }
  12.   stage.update();
  13. }
  1. function createStarPoints(numVertices, longRadius, shortRadius) {
  2.   var starPoints = [];
  3.   var angle = Math.PI;
  4.   var theta = angle / numVertices;
  5.   angle /= -2;
  6.   for (var i = 0; i < numVertices; i++) {
  7.     starPoints.push(new createjs.Point(longRadius * Math.cos(angle), longRadius * Math.sin(angle)));
  8.     angle += theta;
  9.     starPoints.push(new createjs.Point(shortRadius * Math.cos(angle), shortRadius * Math.sin(angle)));
  10.     angle += theta;
  11.   }
  12.   return starPoints;
  13. }

図004-3■2次元平面に線で描かれた星形
図004-3

コード002■星形の頂点座標を直線で結んで描く
  1. var stage;
  2. var drawGraphics;
  3. var points;
  4. function initialize() {
  5.   var canvasElement = document.getElementById("myCanvas");
  6.   stage = new createjs.Stage(canvasElement);
  7.   drawGraphics = createGraphics(canvasElement.width / 2, canvasElement.height / 2);
  8.   points = createStarPoints(5, 65, 25);
  9.   draw(points);
  10. }
  11. function createGraphics(x, y) {
  12.   var drawShape = new createjs.Shape();
  13.   drawShape.x = x;
  14.   drawShape.y = y;
  15.   stage.addChild(drawShape);
  16.   return drawShape.graphics;
  17. }
  18. function draw(points) {
  19.   var count = points.length;
  20.   var point = points[count - 1];
  21.   drawGraphics.clear()
  22.   .beginStroke("mediumblue")
  23.   .setStrokeStyle(3)
  24.   .moveTo(point.x, point.y);
  25.   for (var i = 0; i < count; i++) {
  26.     point = points[i];
  27.     drawGraphics.lineTo(point.x, point.y);
  28.   }
  29.   stage.update();
  30. }
  31. function createStarPoints(numVertices, longRadius, shortRadius) {
  32.   var starPoints = [];
  33.   var angle = Math.PI;
  34.   var theta = angle / numVertices;
  35.   angle /= -2;
  36.   for (var i = 0; i < numVertices; i++) {
  37.     starPoints.push(new createjs.Point(longRadius * Math.cos(angle), longRadius * Math.sin(angle)));
  38.     angle += theta;
  39.     starPoints.push(new createjs.Point(shortRadius * Math.cos(angle), shortRadius * Math.sin(angle)));
  40.     angle += theta;
  41.   }
  42.   return starPoints;
  43. }

図005■直線で描く星形が回る
図004   図004

コード003■座標を回転して描く星形のアニメーション
  1. var stage;
  2. var drawGraphics;
  3. var points;
  4. var angle = Math.PI / 36;
  5. var matrix = new createjs.Matrix2D();
  6. function initialize() {
  7.   var canvasElement = document.getElementById("myCanvas");
  8.   stage = new createjs.Stage(canvasElement);
  9.   drawGraphics = createGraphics(canvasElement.width / 2, canvasElement.height / 2);
  10.   points = createStarPoints(5, 65, 25);
  11.   draw(points);
  12.   createjs.Ticker.addEventListener("tick", rotate);
  13. }
  14. function rotate(eventObject) {
  15.   var count = points.length;
      // matrix.identity().rotate(angle);
  16.   matrix.identity().rotate(angle / createjs.Matrix2D.DEG_TO_RAD);
  17.   for (var i = 0; i < count; i++) {
  18.     var point = points[i];
  19.     matrix.transformPoint(point.x, point.y, point);
  20.   }
  21.   draw(points);
  22. }
  23. function createGraphics(x, y) {
  24.   var drawShape = new createjs.Shape();
  25.   drawShape.x = x;
  26.   drawShape.y = y;
  27.   stage.addChild(drawShape);
  28.   return drawShape.graphics;
  29. }
  30. function draw(points) {
  31.   var count = points.length;
  32.   var point = points[count - 1];
  33.   drawGraphics.clear()
  34.   .beginStroke("mediumblue")
  35.   .setStrokeStyle(3)
  36.   .moveTo(point.x, point.y);
  37.   for (var i = 0; i < count; i++) {
  38.     point = points[i];
  39.     drawGraphics.lineTo(point.x, point.y);
  40.   }
  41.   stage.update();
  42. }
  43. function createStarPoints(numVertices, longRadius, shortRadius) {
  44.   var starPoints = [];
  45.   var angle = Math.PI;
  46.   var theta = angle / numVertices;
  47.   angle /= -2;
  48.   for (var i = 0; i < numVertices; i++) {
  49.     starPoints.push(new createjs.Point(longRadius * Math.cos(angle), longRadius * Math.sin(angle)));
  50.     angle += theta;
  51.     starPoints.push(new createjs.Point(shortRadius * Math.cos(angle), shortRadius * Math.sin(angle)));
  52.     angle += theta;
  53.   }
  54.   return starPoints;
  55. }

図005■遠近法が加わらない回る星のアニメーション
図005   図005

コード004■星形の3次元座標をy軸で回すアニメーション
  1. var stage;
  2. var drawGraphics;
  3. var points;
  4. var angle = Math.PI / 36;
  5. var matrix = new createjs.Matrix2D();
  6. var stageCenterX;
  7. var _point = new createjs.Point();
  8. function initialize() {
  9.   var canvasElement = document.getElementById("myCanvas");
  10.   stage = new createjs.Stage(canvasElement);
  11.   stageCenterX = canvasElement.width / 2;
  12.   drawGraphics = createGraphics(stageCenterX, canvasElement.height / 2);
  13.   points = createStarPoints(5, 65, 25);
  14.   draw(points);
  15.   createjs.Ticker.addEventListener("tick", rotate);
  16.   stage.addEventListener("stagemousemove", setAngle);
  17. }
  18. function setAngle(eventObject) {
  19.   var mouseX = eventObject.stageX;
  20.   angle = (mouseX - stageCenterX) * 1 / 300;
  21. }
  22. function rotate(eventObject) {
  23.   var count = points.length;
  24.   matrix.identity().rotate(angle / createjs.Matrix2D.DEG_TO_RAD);
  25.   for (var i = 0; i < count; i++) {
  26.     var point = points[i];
  27.     matrix.transformPoint(point.x, point.z, _point);
  28.     point.x = _point.x;
  29.     point.z = _point.y;
  30.   }
  31.   draw(points);
  32. }
  33. function createGraphics(x, y) {
  34.   var drawShape = new createjs.Shape();
  35.   drawShape.x = x;
  36.   drawShape.y = y;
  37.   stage.addChild(drawShape);
  38.   return drawShape.graphics;
  39. }
  40. function draw(points) {
  41.   var count = points.length;
  42.   var point = points[count - 1];
  43.   drawGraphics.clear()
  44.   .beginStroke("mediumblue")
  45.   .setStrokeStyle(3)
  46.   .moveTo(point.x, point.y);
  47.   for (var i = 0; i < count; i++) {
  48.     point = points[i];
  49.     drawGraphics.lineTo(point.x, point.y);
  50.   }
  51.   stage.update();
  52. }
  53. function createStarPoints(numVertices, longRadius, shortRadius) {
  54.   var starPoints = [];
  55.   var angle = Math.PI;
  56.   var theta = angle / numVertices;
  57.   angle /= -2;
  58.   for (var i = 0; i < numVertices; i++) {
  59.     starPoints.push(newPoint3D(longRadius * Math.cos(angle), longRadius * Math.sin(angle), 0));
  60.     angle += theta;
  61.     starPoints.push(newPoint3D(shortRadius * Math.cos(angle), shortRadius * Math.sin(angle), 0));
  62.     angle += theta;
  63.   }
  64.   return starPoints;
  65. }
  66. function newPoint3D(x, y, z) {
  67.   var point3D = {x:x, y:y, z:z};
  68.   return point3D;
  69. }

遠近法を投影する(図006)。

投影像の大きさ/オブジェクトの大きさ = 焦点距離 / (焦点距離 + z位置)
投影像の大きさ = オブジェクトの大きさ×焦点距離 / (焦点距離 + z位置)

透視投影比率 = 焦点距離 / (焦点距離 + z位置)

図006■z軸における焦点距離と視野角
図006

  1. function getProjetedPoint(focalLength, _point3D) {
  2.   var point2D = new createjs.Point();
  3.   var w = focalLength / (focalLength + _point3D.z);
  4.   point2D.x = _point3D.x * w;
  5.   point2D.y = _point3D.y * w;
  6.   return point2D;
  7. }

図007■遠近法が投影された回る星のアニメーション
図007   図007

コード005■星形の3次元座標に遠近法を加えてy軸で回すアニメーション
  1. var stage;
  2. var drawGraphics;
  3. var points;
  4. var angle = Math.PI / 36;
  5. var matrix = new createjs.Matrix2D();
  6. var stageCenterX;
  7. var _point = new createjs.Point();
  8. var points2D = [];
  9. var focalLength = 300;
  10. function initialize() {
  11.   var canvasElement = document.getElementById("myCanvas");
  12.   stage = new createjs.Stage(canvasElement);
  13.   stageCenterX = canvasElement.width / 2;
  14.   drawGraphics = createGraphics(stageCenterX, canvasElement.height / 2);
  15.   points = createStarPoints(5, 65, 25);
  16.   draw(points);
  17.   createjs.Ticker.addEventListener("tick", rotate);
  18.   stage.addEventListener("stagemousemove", setAngle);
  19. }
  20. function setAngle(eventObject) {
  21.   var mouseX = eventObject.stageX;
  22.   angle = (mouseX - stageCenterX) * 1 / 300;
  23. }
  24. function rotate(eventObject) {
  25.   var count = points.length;
  26.   points2D.length = 0;
  27.   matrix.identity().rotate(angle / createjs.Matrix2D.DEG_TO_RAD);
  28.   for (var i = 0; i < count; i++) {
  29.     var point = points[i];
  30.     matrix.transformPoint(point.x, point.z, _point);
  31.     point.x = _point.x;
  32.     point.z = _point.y;
  33.     points2D[i] = getProjetedPoint(focalLength, point);
  34.   }
  35.   draw(points2D);
  36. }
  37. function createGraphics(x, y) {
  38.   var drawShape = new createjs.Shape();
  39.   drawShape.x = x;
  40.   drawShape.y = y;
  41.   stage.addChild(drawShape);
  42.   return drawShape.graphics;
  43. }
  44. function draw(points) {
  45.   var count = points.length;
  46.   var point = points[count - 1];
  47.   drawGraphics.clear()
  48.   .beginStroke("mediumblue")
  49.   .setStrokeStyle(3)
  50.   .moveTo(point.x, point.y);
  51.   for (var i = 0; i < count; i++) {
  52.     point = points[i];
  53.     drawGraphics.lineTo(point.x, point.y);
  54.   }
  55.   stage.update();
  56. }
  57. function createStarPoints(numVertices, longRadius, shortRadius) {
  58.   var starPoints = [];
  59.   var angle = Math.PI;
  60.   var theta = angle / numVertices;
  61.   angle /= -2;
  62.   for (var i = 0; i < numVertices; i++) {
  63.     starPoints.push(newPoint3D(longRadius * Math.cos(angle), longRadius * Math.sin(angle), 0));
  64.     angle += theta;
  65.     starPoints.push(newPoint3D(shortRadius * Math.cos(angle), shortRadius * Math.sin(angle), 0));
  66.     angle += theta;
  67.   }
  68.   return starPoints;
  69. }
  70. function getProjetedPoint(focalLength, _point3D) {
  71.   var point2D = new createjs.Point();
  72.   var w = focalLength / (focalLength + _point3D.z);
  73.   point2D.x = _point3D.x * w;
  74.   point2D.y = _point3D.y * w;
  75.   return point2D;
  76. }
  77. function newPoint3D(x, y, z) {
  78.   var point3D = {x:x, y:y, z:z};
  79.   return point3D;
  80. }

02-02 インタラクティブに立方体を回す

サンプル003■EaselJS 0.8.0: Rotating a Cube around the X and Y axes

gihyo.jp連載「HTML5のCanvasでつくるダイナミックな表現―CreateJSを使う」
第20回「立方体のワイヤーフレームを水平に回す
第21回「水平に回す立方体の面を塗る
第22回「立方体の6面をx軸とy軸で回す

図008■立方体の原点を中心に置くと一辺の半分の長さで8頂点座標が決められる
図008

var cubePoints = [
  new Point3D(-halfEdge, -halfEdge, -halfEdge),
  new Point3D(halfEdge, -halfEdge, -halfEdge),
  new Point3D(halfEdge, halfEdge, -halfEdge),
  new Point3D(-halfEdge, halfEdge, -halfEdge),
  new Point3D(-halfEdge, -halfEdge, halfEdge),
  new Point3D(halfEdge, -halfEdge, halfEdge),
  new Point3D(halfEdge, halfEdge, halfEdge),
  new Point3D(-halfEdge, halfEdge, halfEdge)
];

【クラスの定義】
// コンストラクタ関数の定義
function クラス名([引数]) {
  // プロパティの設定
  this.プロパティ = 値;
}
// メソッドの定義
クラス名.prototype.メソッド名 = function([引数]) {
  // メソッドの処理
}
    // Face
  1. function Face(pos0, pos1, pos2, pos3) {
  2.   this.length = 4;
  3.   this[0] = pos0;
  4.   this[1] = pos1;
  5.   this[2] = pos2;
  6.   this[3] = pos3;
  7. }
  8. Face.prototype.getFacePoints = function (points) {
  9.   var faces = this.length;
  10.   var facePoints = [];
  11.   for (var i = 0; i < faces; i++) {
  12.     facePoints[i] = points[this[i]];
  13.   }
  14.   return facePoints;
  15. };
    // Point3D
  1. function Point3D(x, y, z) {
  2.   this.x = x;
  3.   this.y = y;
  4.   this.z = z;
  5. }
  6. Point3D.prototype.getProjetedPoint = function(focalLength) {
  7.   var point2D = new createjs.Point();
  8.   var w = focalLength / (focalLength + this.z);
  9.   point2D.x = this.x * w;
  10.   point2D.y = this.y * w;
  11.   return point2D;
  12. };

図009■立方体の8頂点にインデックスを与える
図009

コード006■ワイヤーフレームで描いた立方体の4面をマウスポインタの位置に応じて水平に回す
    // Point3D
  1. function Point3D(x, y, z) {
  2.   this.x = x;
  3.   this.y = y;
  4.   this.z = z;
  5. }
  6. Point3D.prototype.getProjetedPoint = function(focalLength) {
  7.   var point2D = new createjs.Point();
  8.   var w = focalLength / (focalLength + this.z);
  9.   point2D.x = this.x * w;
  10.   point2D.y = this.y * w;
  11.   return point2D;
  12. };
    // Face
  13. function Face(pos0, pos1, pos2, pos3) {
  14.   this.length = 4;
  15.   this[0] = pos0;
  16.   this[1] = pos1;
  17.   this[2] = pos2;
  18.   this[3] = pos3;
  19. }
  20. Face.prototype.getFacePoints = function (points) {
  21.   var faces = this.length;
  22.   var facePoints = [];
  23.   for (var i = 0; i < faces; i++) {
  24.     facePoints[i] = points[this[i]];
  25.   }
  26.   return facePoints;
  27. };

  28. var stage;
  29. var drawGraphics;
  30. var points;
  31. var angle = 0;
  32. var matrix = new createjs.Matrix2D();
  33. var stageCenterX;
  34. var _point = new createjs.Point();
  35. var points2D = [];
  36. var facesVertices;
  37. var focalLength = 300;
  38. function initialize() {
  39.   var canvasElement = document.getElementById("myCanvas");
  40.   stage = new createjs.Stage(canvasElement);
  41.   stageCenterX = canvasElement.width / 2;
  42.   drawGraphics = createGraphics(stageCenterX, canvasElement.height / 2);
  43.   points = createCubePoints(50);
  44.   facesVertices = getFacesVertices();
  45.   drawFaces(points, facesVertices);
  46.   createjs.Ticker.addEventListener("tick", rotate);
  47.   stage.addEventListener("stagemousemove", setAngle);
  48. }
  49. function setAngle(eventObject) {
  50.   var mouseX = eventObject.stageX;
  51.   angle = (mouseX - stageCenterX) * 1 / 300;
  52. }
  53. function rotate(eventObject) {
  54.   var count = points.length;
  55.   points2D.length = 0;
  56.   matrix.identity().rotate(angle);
  57.   for (var i = 0; i < count; i++) {
  58.     var point = points[i];
  59.     matrix.transformPoint(point.x, point.z, _point);
  60.     point.x = _point.x;
  61.     point.z = _point.y;
  62.     points2D[i] = point.getProjetedPoint(focalLength);
  63.   }
  64.   drawFaces(points2D, facesVertices);
  65. }
  66. function drawFaces(points, faces) {
  67.   var numFaces = faces.length;
  68.   drawGraphics.clear();
  69.   for (var i = 0; i < numFaces; i++) {
  70.     var face = faces[i];
  71.     var facePoints = face.getFacePoints(points);
  72.     draw(facePoints);
  73.   }
  74.   stage.update();
  75. }
  76. function draw(points) {
  77.   var count = points.length;
  78.   var point = points[count - 1];
  79.   drawGraphics
  80.   .beginStroke("mediumblue")
  81.   .setStrokeStyle(1)
  82.   .moveTo(point.x, point.y);
  83.   for (var i = 0; i < count; i++) {
  84.     point = points[i];
  85.     drawGraphics.lineTo(point.x, point.y);
  86.   }
  87. }
  88. function createGraphics(x, y) {
  89.   var drawShape = new createjs.Shape();
  90.   drawShape.x = x;
  91.   drawShape.y = y;
  92.   stage.addChild(drawShape);
  93.   return drawShape.graphics;
  94. }
  95. function createCubePoints(halfEdge) {
  96.   var cubePoints = [
  97.     new Point3D(-halfEdge, -halfEdge, -halfEdge),
  98.     new Point3D(halfEdge,  -halfEdge, -halfEdge),
  99.     new Point3D(halfEdge, halfEdge, -halfEdge),
  100.     new Point3D(-halfEdge, halfEdge, -halfEdge),
  101.     new Point3D(-halfEdge, -halfEdge, halfEdge),
  102.     new Point3D(halfEdge, -halfEdge, halfEdge),
  103.     new Point3D(halfEdge, halfEdge, halfEdge),
  104.     new Point3D(-halfEdge, halfEdge, halfEdge)
  105.   ];
  106.   return cubePoints;
  107. }
  108. function getFacesVertices() {
  109.   var vertices = [
  110.     new Face(0, 1, 2, 3),
  111.     new Face(1, 5, 6, 2),
  112.     new Face(4, 0, 3, 7),
  113.     new Face(5, 4, 7, 6)
  114.   ];
  115.   return vertices;
  116. }

図010■順序を考えずに塗ると面の重ね順が崩れる
図010左 図010右

コード007■水平に回す立方体の表向きの面だけを描く
    // Point3D
  1. function Point3D(x, y, z) {
  2.   this.x = x;
  3.   this.y = y;
  4.   this.z = z;
  5. }
  6. Point3D.prototype.getProjetedPoint = function(focalLength) {
  7.   var point2D = new createjs.Point();
  8.   var w = focalLength / (focalLength + this.z);
  9.   point2D.x = this.x * w;
  10.   point2D.y = this.y * w;
  11.   return point2D;
  12. };
    // Face
  13. function Face(pos0, pos1, pos2, pos3, color) {
  14.   this.length = 4;
  15.   this.color = color;
  16.   this[0] = pos0;
  17.   this[1] = pos1;
  18.   this[2] = pos2;
  19.   this[3] = pos3;
  20. }
  21. Face.prototype.getFacePoints = function (points) {
  22.   var faces = this.length;
  23.   var facePoints = [];
  24.   for (var i = 0; i < faces; i++) {
  25.     facePoints[i] = points[this[i]];
  26.   }
  27.   return facePoints;
  28. };
    // MathUtils
  29. var MathUtils = {};
  30. MathUtils.getRandomInt = function(min, max) {
  31.   if (min > max) {
  32.     var temp = min;
  33.     min = max;
  34.     max = temp;
  35.   }
  36.   var randomNumber = Math.random() * (max - min) + min;
  37.   return Math.floor(randomNumber);
  38. };
  39. MathUtils.subtractVectors = function(vector0, vector1) {
  40.   var vectorX = vector1.x - vector0.x;
  41.   var vectorY = vector1.y - vector0.y;
  42.   return new createjs.Point(vectorX, vectorY);
  43. };
  44. MathUtils.crossProduct2D = function(vector0, vector1) {
  45.   return vector0.x * vector1.y - vector0.y * vector1.x;
  46. }

  47. var stage;
  48. var drawGraphics;
  49. var points;
  50. var angle = 0;
  51. var matrix = new createjs.Matrix2D();
  52. var stageCenterX;
  53. var _point = new createjs.Point();
  54. var points2D = [];
  55. var facesVertices;
  56. var focalLength = 300;
  57. function initialize() {
  58.   var canvasElement = document.getElementById("myCanvas");
  59.   stage = new createjs.Stage(canvasElement);
  60.   stageCenterX = canvasElement.width / 2;
  61.   drawGraphics = createGraphics(stageCenterX, canvasElement.height / 2);
  62.   points = createCubePoints(50);
  63.   facesVertices = getFacesVertices();
  64.   drawFaces(points, facesVertices);
  65.   createjs.Ticker.addEventListener("tick", rotate);
  66.   stage.addEventListener("stagemousemove", setAngle);
  67. }
  68. function setAngle(eventObject) {
  69.   var mouseX = eventObject.stageX;
  70.   angle = (mouseX - stageCenterX) * 1 / 300;
  71. }
  72. function rotate(eventObject) {
  73.   var count = points.length;
  74.   points2D.length = 0;
  75.   matrix.identity().rotate(angle / createjs.Matrix2D.DEG_TO_RAD);
  76.   for (var i = 0; i < count; i++) {
  77.     var point = points[i];
  78.     matrix.transformPoint(point.x, point.z, _point);
  79.     point.x = _point.x;
  80.     point.z = _point.y;
  81.     points2D[i] = point.getProjetedPoint(focalLength);
  82.   }
  83.   drawFaces(points2D, facesVertices);
  84. }
  85. function drawFaces(points, faces) {
  86.   var numFaces = faces.length;
  87.   drawGraphics.clear();
  88.   for (var i = 0; i < numFaces; i++) {
  89.     var face = faces[i];
  90.     var facePoints = face.getFacePoints(points);
  91.     if (isFront(facePoints)) {
  92.       draw(facePoints, face.color);
  93.     }
  94.   }
  95.   stage.update();
  96. }
  97. function isFront(facePoints) {
  98.   var origin = facePoints[0];
  99.   var point0 = MathUtils.subtractVectors(origin, facePoints[1]);
  100.   var point1 = MathUtils.subtractVectors(origin, facePoints[2]);
  101.   return (0 <= MathUtils.crossProduct2D(point0, point1));
  102. }
  103. function draw(points, color) {
  104.   var count = points.length;
  105.   var point = points[count - 1];
  106.   drawGraphics
  107.   .beginFill(color)
  108.   .moveTo(point.x, point.y);
  109.   for (var i = 0; i < count; i++) {
  110.     point = points[i];
  111.     drawGraphics.lineTo(point.x, point.y);
  112.   }
  113. }
  114. function createGraphics(x, y) {
  115.   var drawShape = new createjs.Shape();
  116.   drawShape.x = x;
  117.   drawShape.y = y;
  118.   stage.addChild(drawShape);
  119.   return drawShape.graphics;
  120. }
  121. function createCubePoints(halfEdge) {
  122.   var cubePoints = [
  123.     new Point3D(-halfEdge, -halfEdge, -halfEdge),
  124.     new Point3D(halfEdge, -halfEdge, -halfEdge),
  125.     new Point3D(halfEdge, halfEdge, -halfEdge),
  126.     new Point3D(-halfEdge, halfEdge, -halfEdge),
  127.     new Point3D(-halfEdge, -halfEdge, halfEdge),
  128.     new Point3D(halfEdge, -halfEdge, halfEdge),
  129.     new Point3D(halfEdge, halfEdge, halfEdge),
  130.     new Point3D(-halfEdge, halfEdge, halfEdge)
  131.   ];
  132.   return cubePoints;
  133. }
  134. function getFacesVertices() {
  135.   var vertices = [
  136.     new Face(0, 1, 2, 3, getRandomColor()),
  137.     new Face(1, 5, 6, 2, getRandomColor()),
  138.     new Face(4, 0, 3, 7, getRandomColor()),
  139.     new Face(5, 4, 7, 6, getRandomColor())
  140.   ];
  141.   return vertices;
  142. }
  143. function getRandomColor() {
  144.   return createjs.Graphics.getRGB(Math.floor(MathUtils.getRandomInt(0, 0xFFFFFF)));
  145. }
【2次元ベクトルA(ax, ay)とB(bx, by)の外積】
A×B =axby - aybx
図011■2次元ベクトルの外積の正負は位置が右ネジか左ネジかで決まる
図011左 図011右

図012■3頂点から定めたふたつのベクトルの位置関係を予め決める
図012


図013■外積の正負から面の向きを調べて裏返った面は描かない
図013左
外積が正の面は描画する
図013右
外積が負の面は描画しない
    // MathUtils
  1. MathUtils.crossProduct2D = function(vector0, vector1) {
  2.   return vector0.x * vector1.y - vector0.y * vector1.x;
  3. }
  1. function drawFaces(points, faces) {
  2.   var numFaces = faces.length;
  3.   drawGraphics.clear();
  4.   for (var i = 0; i < numFaces; i++) {
  5.     var face = faces[i];
  6.     var facePoints = face.getFacePoints(points);
  7.     if (isFront(facePoints)) {
  8.       draw(facePoints, face.color);
  9.     }
  10.   }
  11.   stage.update();
  12. }
  13. function isFront(facePoints) {
  14.   var origin = facePoints[0];
  15.   var point0 = MathUtils.subtractVectors(origin, facePoints[1]);
  16.   var point1 = MathUtils.subtractVectors(origin, facePoints[2]);
  17.   return (0 <= MathUtils.crossProduct2D(point0, point1));
  18. }
図014■立方体がマウスポインタの位置に応じて上下左右に回る
図014左 図014右

コード008■マウスポインタの位置に応じて立方体をy軸およびx軸で回す
    // Point3D
  1. function Point3D(x, y, z) {
  2.   this.x = x;
  3.   this.y = y;
  4.   this.z = z;
  5. }
  6. Point3D._point = new createjs.Point();
  7. Point3D.prototype.getProjetedPoint = function(focalLength) {
  8.   var point2D = new createjs.Point();
  9.   var w = focalLength / (focalLength + this.z);
  10.   point2D.x = this.x * w;
  11.   point2D.y = this.y * w;
  12.   return point2D;
  13. };
  14. Point3D.prototype.rotatePoint = function(matrix, axis) {
  15.   if (axis == "y") {
  16.     matrix.transformPoint(this.x, this.z, Point3D._point);
  17.     this.x = Point3D._point.x;
  18.     this.z = Point3D._point.y;
  19.   } else if (axis == "x") {
  20.     matrix.transformPoint(this.z, this.y, Point3D._point);
  21.     this.z = Point3D._point.x;
  22.     this.y = Point3D._point.y;
  23.   }
  24. };
    // Face
  25. function Face(pos0, pos1, pos2, pos3, color) {
  26.   this.length = 4;
  27.   this.color = color;
  28.   this[0] = pos0;
  29.   this[1] = pos1;
  30.   this[2] = pos2;
  31.   this[3] = pos3;
  32. }
  33. Face.prototype.getFacePoints = function (points) {
  34.   var faces = this.length;
  35.   var facePoints = [];
  36.   for (var i = 0; i < faces; i++) {
  37.     facePoints[i] = points[this[i]];
  38.   }
  39.   return facePoints;
  40. };
    // MathUtils
  41. var MathUtils = {};
  42. MathUtils.getRandomInt = function(min, max) {
  43.   if (min > max) {
  44.     var temp = min;
  45.     min = max;
  46.     max = temp;
  47.   }
  48.   var randomNumber = Math.random() * (max - min) + min;
  49.   return Math.floor(randomNumber);
  50. };
  51. MathUtils.subtractVectors = function(vector0, vector1) {
  52.   var vectorX = vector1.x - vector0.x;
  53.   var vectorY = vector1.y - vector0.y;
  54.   return new createjs.Point(vectorX, vectorY);
  55. };
  56. MathUtils.crossProduct2D = function(vector0, vector1) {
  57.   return vector0.x * vector1.y - vector0.y * vector1.x;
  58. }

  59. var stage;
  60. var drawGraphics;
  61. var points;
  62. var angle = new createjs.Point();
  63. var matrixX = new createjs.Matrix2D();
  64. var matrixY = new createjs.Matrix2D();
  65. var stageCenter = new createjs.Point();
  66. var points2D = [];
  67. var facesVertices;
  68. var focalLength = 300;
  69. function initialize() {
  70.   var canvasElement = document.getElementById("myCanvas");
  71.   stage = new createjs.Stage(canvasElement);
  72.   stageCenter.x = canvasElement.width / 2;
  73.   stageCenter.y = canvasElement.height / 2;
  74.   drawGraphics = createGraphics(stageCenter.x, stageCenter.y);
  75.   points = createCubePoints(50);
  76.   facesVertices = getFacesVertices();
  77.   drawFaces(points, facesVertices);
  78.   createjs.Ticker.addEventListener("tick", rotate);
  79.   stage.addEventListener("stagemousemove", setAngle);
  80. }
  81. function setAngle(eventObject) {
  82.   var mouseX = eventObject.stageX;
  83.   var mouseY = eventObject.stageY;
  84.   angle.y = (mouseX - stageCenter.x) / 300;
  85.   angle.x = (mouseY - stageCenter.y) / -300;
  86. }
  87. function rotate(eventObject) {
  88.   var count = points.length;
  89.   points2D.length = 0;
  90.   matrixY.identity().rotate(angle.y / createjs.Matrix2D.DEG_TO_RAD);
  91.   matrixX.identity().rotate(angle.x / createjs.Matrix2D.DEG_TO_RAD);
  92.   for (var i = 0; i < count; i++) {
  93.     var point = points[i];
  94.     point.rotatePoint(matrixY, "y");
  95.     point.rotatePoint(matrixX, "x");
  96.     points2D[i] = point.getProjetedPoint(focalLength);
  97.   }
  98.   drawFaces(points2D, facesVertices);
  99. }
  100. function drawFaces(points, faces) {
  101.   var numFaces = faces.length;
  102.   drawGraphics.clear();
  103.   for (var i = 0; i < numFaces; i++) {
  104.     var face = faces[i];
  105.     var facePoints = face.getFacePoints(points);
  106.     if (isFront(facePoints)) {
  107.       draw(facePoints, face.color);
  108.     }
  109.   }
  110.   stage.update();
  111. }
  112. function isFront(facePoints) {
  113.   var origin = facePoints[0];
  114.   var point0 = MathUtils.subtractVectors(origin, facePoints[1]);
  115.   var point1 = MathUtils.subtractVectors(origin, facePoints[2]);
  116.   return (0 <= MathUtils.crossProduct2D(point0, point1));
  117. }
  118. function draw(points, color) {
  119.   var count = points.length;
  120.   var point = points[count - 1];
  121.   drawGraphics
  122.   .beginFill(color)
  123.   .moveTo(point.x, point.y);
  124.   for (var i = 0; i < count; i++) {
  125.     point = points[i];
  126.     drawGraphics.lineTo(point.x, point.y);
  127.   }
  128. }
  129. function createGraphics(x, y) {
  130.   var drawShape = new createjs.Shape();
  131.   drawShape.x = x;
  132.   drawShape.y = y;
  133.   stage.addChild(drawShape);
  134.   return drawShape.graphics;
  135. }
  136. function createCubePoints(halfEdge) {
  137.   var cubePoints = [
  138.     new Point3D(-halfEdge, -halfEdge, -halfEdge),
  139.     new Point3D(halfEdge, -halfEdge, -halfEdge),
  140.     new Point3D(halfEdge, halfEdge, -halfEdge),
  141.     new Point3D(-halfEdge, halfEdge, -halfEdge),
  142.     new Point3D(-halfEdge, -halfEdge, halfEdge),
  143.     new Point3D(halfEdge, -halfEdge, halfEdge),
  144.     new Point3D(halfEdge, halfEdge, halfEdge),
  145.     new Point3D(-halfEdge, halfEdge, halfEdge)
  146.   ];
  147.   return cubePoints;
  148. }
  149. function getFacesVertices() {
  150.   var vertices = [
  151.     new Face(0, 1, 2, 3, getRandomColor()),
  152.     new Face(1, 5, 6, 2, getRandomColor()),
  153.     new Face(4, 0, 3, 7, getRandomColor()),
  154.     new Face(4, 5, 1, 0, getRandomColor()),
  155.     new Face(6, 7, 3, 2, getRandomColor()),
  156.     new Face(5, 4, 7, 6, getRandomColor())
  157.   ];
  158.   return vertices;
  159. }
  160. function getRandomColor() {
  161.   return createjs.Graphics.getRGB(Math.floor(MathUtils.getRandomInt(0, 0xFFFFFF)));
  162. }

03 Away3Dを使ったインタラクティブな3次元表現

サンプル004■Away3D 14/11/05: Dealing with the mouse interactions

gihyo.jp連載「Away3D TypeScriptではじめる3次元表現」
第7回「回り込むカメラの真ん中にオブジェクトを捉える
第8回「オブジェクトの位置と大きさをランダムにする
第9回「回り込むマウスイベントを扱う」(予定)

<script src="lib/awayjs-core.min.js"></script>
<script src="lib/awayjs-display.min.js"></script>
<script src="lib/awayjs-renderergl.min.js"></script>
<script src="lib/awayjs-stagegl.min.js"></script>
<script src="lib/awayjs-methodmaterials.min.js"></script>
    【Away3Dで用意しなければならないもの】
  1. 舞台:Viewオブジェクトで3次元空間の表示領域を定める
  2. 照明:光源のオブジェクトで3次元空間を照らす
  3. 役者:物体のひながたからインスタンスをつくって3次元空間に加える

使うクラスは、予めrequire()メソッドで読込む。

  1. var View = require("awayjs-display/lib/containers/View");
  2. var DirectionalLight = require("awayjs-display/lib/entities/DirectionalLight");
  3. var StaticLightPicker = require("awayjs-display/lib/materials/lightpickers/StaticLightPicker");
  4. var PrimitiveCubePrefab = require("awayjs-display/lib/prefabs/PrimitiveCubePrefab");
  5. var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
  6. var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");

Viewオブジェクトで3次元空間の表示領域を定める。

  1. function initialize() {
  1.   view = createView(240, 180, 0x0);
  1. }
  2. function createView(width, height, backgroundColor) {
  3.   var defaultRenderer = new DefaultRenderer();
  4.   var view = new View(defaultRenderer);
  5.   view.width = width;
  6.   view.height = height;
  7.   view.backgroundColor = backgroundColor;
  8.   return view;
  9. }

平行光源のDirectionalLightオブジェクトで3次元空間を照らす。

図015■3次元表現で使われる光源の種類
図015
Tcpp's fileより引用

  1. function initialize() {
  2.   var directionalLight = createDirectionalLight(0.5, 0xFFFFFF);
  1. }
  1. function createDirectionalLight(ambient, color) {
  2.   var light = new DirectionalLight();
  3.   light.ambient = ambient;
  4.   light.color = color;
  5.   return light;
  6. }

直方体のひながたのPrimitiveCubePrefabクラスからインスタンスをつくって3次元空間に加える。

  1. function initialize() {
  2.   var directionalLight = createDirectionalLight(0.5, 0xFFFFFF);
  3.   view = createView(240, 180, 0x0);
  4.   cube = createCube(400, 400, 400, directionalLight);
  5.   view.scene.addChild(cube);
  1. }
  1. function createCube(width, height, depth, light) {
  2.   var material = new TriangleMethodMaterial();
  3.   var cube = new PrimitiveCubePrefab(width, height, depth, 1, 1, 1, false)
  4.   .getNewObject();
  5.   cube.material = material;
  6.   material.lightPicker = new StaticLightPicker([light]);
  7.   return cube;
  8. }

図016■白い立方体が正面向きで置かれる
図016

コード009■3次元空間の真ん中に立方体を置く
  1. var View = require("awayjs-display/lib/containers/View");
  2. var DirectionalLight = require("awayjs-display/lib/entities/DirectionalLight");
  3. var StaticLightPicker = require("awayjs-display/lib/materials/lightpickers/StaticLightPicker");
  4. var PrimitiveCubePrefab = require("awayjs-display/lib/prefabs/PrimitiveCubePrefab");
  5. var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
  6. var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
  7. var view;
  8. var cube;
  9. var timer;
  10. function initialize() {
  11.   var directionalLight = createDirectionalLight(0.5, 0xFFFFFF);
  12.   view = createView(240, 180, 0x0);
  13.   cube = createCube(400, 400, 400, directionalLight);
  14.   view.scene.addChild(cube);
  15.   view.render();
  16.   view.render();
  17. }
  18. function createView(width, height, backgroundColor) {
  19.   var defaultRenderer = new DefaultRenderer();
  20.   var view = new View(defaultRenderer);
  21.   view.width = width;
  22.   view.height = height;
  23.   view.backgroundColor = backgroundColor;
  24.   return view;
  25. }
  26. function createCube(width, height, depth, light) {
  27.   var material = new TriangleMethodMaterial();
  28.   var cube = new PrimitiveCubePrefab(width, height, depth, 1, 1, 1, false)
  29.   .getNewObject();
  30.   cube.material = material;
  31.   material.lightPicker = new StaticLightPicker([light]);
  32.   return cube;
  33. }
  34. function createDirectionalLight(ambient, color) {
  35.   var light = new DirectionalLight();
  36.   light.ambient = ambient;
  37.   light.color = color;
  38.   return light;
  39. }

AssetLibraryクラスでテクスチャを読込む(図017)。

図017■立方体の各面に貼るテクスチャ
図017

  1. var imageDiffuse = "assets/trinket_diffuse.jpg";
  1. function initialize() {
  1.   AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
  2.   AssetLibrary.load(new URLRequest(imageDiffuse));
  1. }
  1. function onResourceComplete(eventObject) {
  2.   var assets = eventObject.assets;
  3.   var material = cube.material;
  4.   material.texture = assets[0];
  5.   view.render();
  6. }

RequestAnimationFrameクラスを使ってオブジェクトをアニメーションさせる。

  1. function initialize() {
  1.   timer = new RequestAnimationFrame(rotate);
  2.   timer.start();
  1. }
  1. function rotate(timeStamp) {
  2.   cube.rotationX = (cube.rotationX + 1) % 360;
  3.   cube.rotationY = (cube.rotationY + 1) % 360;
  4.   view.render();
  5. }

図018■3次元空間の真ん中に置かれた立方体が上下左右に回る
図018

コード010■3次元空間の真ん中に立方体を置いて水平および垂直に回す
  1. var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
  2. var AssetLibrary = require("awayjs-core/lib/library/AssetLibrary");
  3. var URLRequest = require("awayjs-core/lib/net/URLRequest");
  4. var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
  5. var View = require("awayjs-display/lib/containers/View");
  6. var DirectionalLight = require("awayjs-display/lib/entities/DirectionalLight");
  7. var StaticLightPicker = require("awayjs-display/lib/materials/lightpickers/StaticLightPicker");
  8. var PrimitiveCubePrefab = require("awayjs-display/lib/prefabs/PrimitiveCubePrefab");
  9. var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
  10. var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
  11. var view;
  12. var cube;
  13. var imageDiffuse = "assets/trinket_diffuse.jpg";
  14. var timer;
  15. function initialize() {
  16.   var directionalLight = createDirectionalLight(0.5, 0xFFFFFF);
  17.   view = createView(240, 180, 0x0);
  18.   cube = createCube(400, 400, 400, directionalLight);
  19.   view.scene.addChild(cube);
  20.   AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
  21.   AssetLibrary.load(new URLRequest(imageDiffuse));
  22.   timer = new RequestAnimationFrame(rotate);
  23.   timer.start();
  24.   view.render();
  25. }
  26. function createView(width, height, backgroundColor) {
  27.   var defaultRenderer = new DefaultRenderer();
  28.   var view = new View(defaultRenderer);
  29.   view.width = width;
  30.   view.height = height;
  31.   view.backgroundColor = backgroundColor;
  32.   return view;
  33. }
  34. function createCube(width, height, depth, light) {
  35.   var material = new TriangleMethodMaterial();
  36.   var cube = new PrimitiveCubePrefab(width, height, depth, 1, 1, 1, false)
  37.   .getNewObject();
  38.   cube.material = material;
  39.   material.lightPicker = new StaticLightPicker([light]);
  40.   return cube;
  41. }
  42. function createDirectionalLight(ambient, color) {
  43.   var light = new DirectionalLight();
  44.   light.ambient = ambient;
  45.   light.color = color;
  46.   return light;
  47. }
  48. function onResourceComplete(eventObject) {
  49.   var assets = eventObject.assets;
  50.   var material = cube.material;
  51.   material.texture = assets[0];
  52.   view.render();
  53. }
  54. function rotate(timeStamp) {
  55.   cube.rotationX = (cube.rotationX + 1) % 360;
  56.   cube.rotationY = (cube.rotationY + 1) % 360;
  57.   view.render();
  58. }

オブジェクトの周囲をカメラで回り込む。

  1. function initialize() {
  1.   setCamera(view.camera, distance, angle);
  1. }
  1. function rotate(timeStamp) {
      // cube.rotationX = (cube.rotationX + 1) % 360;
      // cube.rotationY = (cube.rotationY + 1) % 360;
  2.   var camera = view.camera;
  3.   angle += timeStamp / 2000;
  4.   setCamera(camera, distance, angle);
  5.   view.render();
  6. }
  7. function setCamera(camera, distance, angle) {
  8.   camera.x = Math.cos(angle) * distance;
  9.   camera.z = Math.sin(angle) * distance;
  10.   camera.lookAt(ORIGIN);
  11. }

図019■真ん中に置いた立方体の周りをカメラが回る
図019

  1. function initialize() {
  1.   cloneMesh(cube, 5);
  1. }
  1. function cloneMesh(mesh, count) {
  2.   var scene = view.scene;
  3.   var distance = 1000;
  4.   var degrees = 360 / count;
  5.   for (var i = 0; i < count; i++) {
  6.     var clone = mesh.clone();
  7.     var rotationY = degrees * i;
  8.     var position = getPolarPosition(distance, rotationY);
  9.     clone.x = position.x;
  10.     clone.y = position.y;
  11.     clone.z = position.z;
  12.     clone.rotationY = rotationY;
  13.     scene.addChild(clone);
  14.   }
  15. }
  1. function getPolarPosition(distance, rotationY) {
  2.   var vector = new Vector3D(distance, 0, 0);
  3.   var matrix = new Matrix3D();
  4.   matrix.appendRotation(rotationY, Vector3D.Y_AXIS);
  5.   return matrix.transformVector(vector);
  6. }

図020■真ん中の箱を中心とした円周上に複数の箱が置かれた
図020

コード011■円軌道上に複数のオブジェクトを行列変換により配置してカメラで回り込む
  1. var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
  2. var Vector3D = require("awayjs-core/lib/geom/Vector3D");
  3. var Matrix3D = require("awayjs-core/lib/geom/Matrix3D");
  4. var AssetLibrary = require("awayjs-core/lib/library/AssetLibrary");
  5. var URLRequest = require("awayjs-core/lib/net/URLRequest");
  6. var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
  7. var View = require("awayjs-display/lib/containers/View");
  8. var DirectionalLight = require("awayjs-display/lib/entities/DirectionalLight");
  9. var StaticLightPicker = require("awayjs-display/lib/materials/lightpickers/StaticLightPicker");
  10. var PrimitiveCubePrefab = require("awayjs-display/lib/prefabs/PrimitiveCubePrefab");
  11. var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
  12. var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
  13. var view;
  14. var cube;
  15. var imageDiffuse = "assets/trinket_diffuse.jpg";
  16. var timer;
  17. var ORIGIN = new Vector3D();
  18. var angle = -Math.PI / 2;
  19. var distance = 1500;
  20. var stageWidth = 240;
  21. var stageHeight = 180;
  22. function initialize() {
  23.   var directionalLight = createDirectionalLight(0.5, 0xFFFFFF);
  24.   view = createView(stageWidth, stageHeight, 0x0);
  25.   cube = createCube(400, 400, 400, directionalLight);
  26.   setCamera(view.camera, distance, angle);
  27.   view.scene.addChild(cube);
  28.   cloneMesh(cube, 5);
  29.   AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
  30.   AssetLibrary.load(new URLRequest(imageDiffuse));
  31.   timer = new RequestAnimationFrame(rotate);
  32.   timer.start();
  33.   view.render();
  34. }
  35. function createView(width, height, backgroundColor) {
  36.   var defaultRenderer = new DefaultRenderer();
  37.   var view = new View(defaultRenderer);
  38.   view.width = width;
  39.   view.height = height;
  40.   view.backgroundColor = backgroundColor;
  41.   return view;
  42. }
  43. function createCube(width, height, depth, light) {
  44.   var material = new TriangleMethodMaterial();
  45.   var cube = new PrimitiveCubePrefab(width, height, depth, 1, 1, 1, false)
  46.   .getNewObject();
  47.   cube.material = material;
  48.   material.lightPicker = new StaticLightPicker([light]);
  49.   return cube;
  50. }
  51. function cloneMesh(mesh, count) {
  52.   var scene = view.scene;
  53.   var distance = 1000;
  54.   var degrees = 360 / count;
  55.   for (var i = 0; i < count; i++) {
  56.     var clone = mesh.clone();
  57.     var rotationY = degrees * i;
  58.     var position = getPolarPosition(distance, rotationY);
  59.     clone.x = position.x;
  60.     clone.y = position.y;
  61.     clone.z = position.z;
  62.     clone.rotationY = rotationY;
  63.     scene.addChild(clone);
  64.   }
  65. }
  66. function createDirectionalLight(ambient, color) {
  67.   var light = new DirectionalLight();
  68.   light.ambient = ambient;
  69.   light.color = color;
  70.   return light;
  71. }
  72. function onResourceComplete(eventObject) {
  73.   var assets = eventObject.assets;
  74.   var material = cube.material;
  75.   material.texture = assets[0];
  76.   view.render();
  77. }
  78. function rotate(timeStamp) {
  79.   var camera = view.camera;
  80.   angle += timeStamp / 2000;
  81.   setCamera(camera, distance, angle);
  82.   view.render();
  83. }
  84. function setCamera(camera, distance, angle) {
  85.   camera.x = Math.cos(angle) * distance;
  86.   camera.z = Math.sin(angle) * distance;
  87.   camera.lookAt(ORIGIN);
  88. }
  89. function getPolarPosition(distance, rotationY) {
  90.   var vector = new Vector3D(distance, 0, 0);
  91.   var matrix = new Matrix3D();
  92.   matrix.appendRotation(rotationY, Vector3D.Y_AXIS);
  93.   return matrix.transformVector(vector);
  94. }

オブジェクトの位置と大きさをランダムに定める。

  1. function cloneMesh(mesh, count) {
  2.   var scene = view.scene;
  3.   for (var i = 0; i < count; i++) {
  4.     var clone = mesh.clone();
  5.     var distance = getRandom(500, 1200);
  6.     var scale = getRandom(0.3, 0.5);
  7.     var rotationX = getRandom(-60, 60);
  8.     var rotationY = getRandom(-180, 180);
  9.     var position = getPolarPosition(distance, rotationX, rotationY);
  10.     clone.x = position.x;
  11.     clone.y = position.y;
  12.     clone.z = position.z;
  13.     setScale(clone, scale);
  14.     clone.rotationY = rotationY;
  15.     scene.addChild(clone);
  16.   }
  17. }
  18. function setScale(mesh, scale) {
  19.   mesh.transform.scale = new Vector3D(scale, scale, scale);
  20. }
  1. }
  2. function getRandom(min, max) {
  3.   var random = Math.random() * (max - min) + min;
  4.   return random;
  5. }

図021■周囲に置かれるオブジェクトの位置とサイズがランダムに定められた
図021

コード012■周囲に置くオブジェクトの位置と大きさをランダムに定める
  1. var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
  2. var Vector3D = require("awayjs-core/lib/geom/Vector3D");
  3. var Matrix3D = require("awayjs-core/lib/geom/Matrix3D");
  4. var AssetLibrary = require("awayjs-core/lib/library/AssetLibrary");
  5. var URLRequest = require("awayjs-core/lib/net/URLRequest");
  6. var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
  7. var View = require("awayjs-display/lib/containers/View");
  8. var DirectionalLight = require("awayjs-display/lib/entities/DirectionalLight");
  9. var StaticLightPicker = require("awayjs-display/lib/materials/lightpickers/StaticLightPicker");
  10. var PrimitiveCubePrefab = require("awayjs-display/lib/prefabs/PrimitiveCubePrefab");
  11. var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
  12. var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
  13. var view;
  14. var cube;
  15. var imageDiffuse = "assets/trinket_diffuse.jpg";
  16. var timer;
  17. var ORIGIN = new Vector3D();
  18. var angle = -Math.PI / 2;
  19. var distance = 1500;
  20. var stageWidth = 240;
  21. var stageHeight = 180;
  22. function initialize() {
  23.   var directionalLight = createDirectionalLight(0.5, 0xFFFFFF);
  24.   view = createView(stageWidth, stageHeight, 0x0);
  25.   cube = createCube(400, 400, 400, directionalLight);
  26.   setCamera(view.camera, distance, angle);
  27.   view.scene.addChild(cube);
  28.   cloneMesh(cube, 5);
  29.   AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
  30.   AssetLibrary.load(new URLRequest(imageDiffuse));
  31.   timer = new RequestAnimationFrame(rotate);
  32.   timer.start();
  33.   view.render();
  34. }
  35. function createView(width, height, backgroundColor) {
  36.   var defaultRenderer = new DefaultRenderer();
  37.   var view = new View(defaultRenderer);
  38.   view.width = width;
  39.   view.height = height;
  40.   view.backgroundColor = backgroundColor;
  41.   return view;
  42. }
  43. function createCube(width, height, depth, light) {
  44.   var material = new TriangleMethodMaterial();
  45.   var cube = new PrimitiveCubePrefab(width, height, depth, 1, 1, 1, false)
  46.   .getNewObject();
  47.   cube.material = material;
  48.   material.lightPicker = new StaticLightPicker([light]);
  49.   return cube;
  50. }
  51. function cloneMesh(mesh, count) {
  52.   var scene = view.scene;
  53.   for (var i = 0; i < count; i++) {
  54.     var clone = mesh.clone();
  55.     var distance = getRandom(500, 1200);
  56.     var scale = getRandom(0.3, 0.5);
  57.     var rotationX = getRandom(-60, 60);
  58.     var rotationY = getRandom(-180, 180);
  59.     var position = getPolarPosition(distance, rotationX, rotationY);
  60.     clone.x = position.x;
  61.     clone.y = position.y;
  62.     clone.z = position.z;
  63.     setScale(clone, scale);
  64.     clone.rotationY = rotationY;
  65.     scene.addChild(clone);
  66.   }
  67. }
  68. function setScale(mesh, scale) {
  69.   mesh.transform.scale = new Vector3D(scale, scale, scale);
  70. }
  71. function createDirectionalLight(ambient, color) {
  72.   var light = new DirectionalLight();
  73.   light.ambient = ambient;
  74.   light.color = color;
  75.   return light;
  76. }
  77. function onResourceComplete(eventObject) {
  78.   var assets = eventObject.assets;
  79.   var material = cube.material;
  80.   material.texture = assets[0];
  81.   view.render();
  82. }
  83. function rotate(timeStamp) {
  84.   var camera = view.camera;
  85.   angle += timeStamp / 2000;
  86.   setCamera(camera, distance, angle);
  87.   view.render();
  88. }
  89. function setCamera(camera, distance, angle) {
  90.   camera.x = Math.cos(angle) * distance;
  91.   camera.z = Math.sin(angle) * distance;
  92.   camera.lookAt(ORIGIN);
  93. }
  94. function getRandom(min, max) {
  95.   var random = Math.random() * (max - min) + min;
  96.   return random;
  97. }
  98. function getPolarPosition(distance, rotationX, rotationY) {
  99.   var vector = new Vector3D(distance, 0, 0);
  100.   var matrix = new Matrix3D();
  101.   matrix.appendRotation(rotationY, Vector3D.Y_AXIS);
  102.   matrix.appendRotation(rotationX, Vector3D.X_AXIS);
  103.   return matrix.transformVector(vector);
  104. }

オブジェクトのクリックでURLを開く。

  1. var urls = [
  2.   "http://gihyo.jp/design/serial/01/away3d-typescript",
  3.   "http://gihyo.jp/design/serial/01/createjs",
  4.   "http://typescript.away3d.com",
  5.   "https://developer.mozilla.org/ja/docs/Web/JavaScript",
  6.   "http://createjs.com/#!/Home"
  7. ];
  8. function initialize() {
  1.   cube.url = "http://fumiononaka.com";
  1.   cloneMesh(cube, urls);
  1. }
  1. function createCube(width, height, depth, light) {
  1.   cube.addEventListener(MouseEvent.CLICK, onClick);
  1. }
  2. function cloneMesh(mesh, urls) {
  1.   var count = urls.length;
  2.   for (var i = 0; i < count; i++) {
  1.     clone.url = urls[i];
  1.     clone.addEventListener(MouseEvent.CLICK, onClick);
  1.   }
  2. }
  3. function onClick(eventObject) {
  4.   var mesh = eventObject.object;
  5.   window.open(mesh.url);
  6. }

図022■立方体のオブジェクトをクリックするとそれぞれ異なるサイトが開く
図022

コード013■オブジェクトをクリックするとそれぞれに定められたURLが開く
  1. var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
  2. var Vector3D = require("awayjs-core/lib/geom/Vector3D");
  3. var Matrix3D = require("awayjs-core/lib/geom/Matrix3D");
  4. var AssetLibrary = require("awayjs-core/lib/library/AssetLibrary");
  5. var URLRequest = require("awayjs-core/lib/net/URLRequest");
  6. var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
  7. var View = require("awayjs-display/lib/containers/View");
  8. var DirectionalLight = require("awayjs-display/lib/entities/DirectionalLight");
  9. var MouseEvent = require("awayjs-display/lib/events/MouseEvent");
  10. var StaticLightPicker = require("awayjs-display/lib/materials/lightpickers/StaticLightPicker");
  11. var PrimitiveCubePrefab = require("awayjs-display/lib/prefabs/PrimitiveCubePrefab");
  12. var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
  13. var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
  14. var view;
  15. var cube;
  16. var imageDiffuse = "assets/trinket_diffuse.jpg";
  17. var timer;
  18. var ORIGIN = new Vector3D();
  19. var angle = -Math.PI / 2;
  20. var distance = 1500;
  21. var stageWidth = 240;
  22. var stageHeight = 180;
  23. var urls = [
  24.   "http://gihyo.jp/design/serial/01/away3d-typescript",
  25.   "http://gihyo.jp/design/serial/01/createjs",
  26.   "http://typescript.away3d.com",
  27.   "https://developer.mozilla.org/ja/docs/Web/JavaScript",
  28.   "http://createjs.com/#!/Home"
  29. ];
  30. function initialize() {
  31.   var directionalLight = createDirectionalLight(0.5, 0xFFFFFF);
  32.   view = createView(stageWidth, stageHeight, 0x0);
  33.   cube = createCube(400, 400, 400, directionalLight);
  34.   setCamera(view.camera, distance, angle);
  35.   cube.url = "http://fumiononaka.com";
  36.   view.scene.addChild(cube);
  37.   cloneMesh(cube, urls);
  38.   AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
  39.   AssetLibrary.load(new URLRequest(imageDiffuse));
  40.   timer = new RequestAnimationFrame(rotate);
  41.   timer.start();
  42.   view.render();
  43. }
  44. function createView(width, height, backgroundColor) {
  45.   var defaultRenderer = new DefaultRenderer();
  46.   var view = new View(defaultRenderer);
  47.   view.width = width;
  48.   view.height = height;
  49.   view.backgroundColor = backgroundColor;
  50.   return view;
  51. }
  52. function createCube(width, height, depth, light) {
  53.   var material = new TriangleMethodMaterial();
  54.   var cube = new PrimitiveCubePrefab(width, height, depth, 1, 1, 1, false)
  55.   .getNewObject();
  56.   cube.material = material;
  57.   cube.addEventListener(MouseEvent.CLICK, onClick);
  58.   material.lightPicker = new StaticLightPicker([light]);
  59.   return cube;
  60. }
  61. function cloneMesh(mesh, urls) {
  62.   var scene = view.scene;
  63.   var count = urls.length;
  64.   for (var i = 0; i < count; i++) {
  65.     var clone = mesh.clone();
  66.     var distance = getRandom(500, 1200);
  67.     var scale = getRandom(0.3, 0.5);
  68.     var rotationX = getRandom(-60, 60);
  69.     var rotationY = getRandom(-180, 180);
  70.     var position = getPolarPosition(distance, rotationX, rotationY);
  71.     clone.x = position.x;
  72.     clone.y = position.y;
  73.     clone.z = position.z;
  74.     clone.url = urls[i];
  75.     setScale(clone, scale);
  76.     clone.rotationY = rotationY;
  77.     clone.addEventListener(MouseEvent.CLICK, onClick);
  78.     scene.addChild(clone);
  79.   }
  80. }
  81. function onClick(eventObject) {
  82.   var mesh = eventObject.object;
  83.   window.open(mesh.url);
  84. }
  85. function setScale(mesh, scale) {
  86.   mesh.transform.scale = new Vector3D(scale, scale, scale);
  87. }
  88. function createDirectionalLight(ambient, color) {
  89.   var light = new DirectionalLight();
  90.   light.ambient = ambient;
  91.   light.color = color;
  92.   return light;
  93. }
  94. function onResourceComplete(eventObject) {
  95.   var assets = eventObject.assets;
  96.   var material = cube.material;
  97.   material.texture = assets[0];
  98.   view.render();
  99. }
  100. function rotate(timeStamp) {
  101.   var camera = view.camera;
  102.   angle += timeStamp / 2000;
  103.   setCamera(camera, distance, angle);
  104.   view.render();
  105. }
  106. function setCamera(camera, distance, angle) {
  107.   camera.x = Math.cos(angle) * distance;
  108.   camera.z = Math.sin(angle) * distance;
  109.   camera.lookAt(ORIGIN);
  110. }
  111. function getRandom(min, max) {
  112.   var random = Math.random() * (max - min) + min;
  113.   return random;
  114. }
  115. function getPolarPosition(distance, rotationX, rotationY) {
  116.   var vector = new Vector3D(distance, 0, 0);
  117.   var matrix = new Matrix3D();
  118.   matrix.appendRotation(rotationY, Vector3D.Y_AXIS);
  119.   matrix.appendRotation(rotationX, Vector3D.X_AXIS);
  120.   return matrix.transformVector(vector);
  121. }

ロールオーバーとロールアウトのインタラクションを加える。

  1. function createView(width, height, backgroundColor) {
  1.   view.forceMouseMove = true;
  1. }
  2. function createCube(width, height, depth, light) {
  1.   setScale(cube, 1);
  2.   setMouseListener(cube, onMouseOver, onMouseOut, onClick);
  3.   material.lightPicker = new StaticLightPicker([light]);
  4.   return cube;
  5. }
  6. function cloneMesh(mesh, urls) {
  1.   var count = urls.length;
  2.   for (var i = 0; i < count; i++) {
  1.     setScale(clone, scale);
  1.     setMouseListener(clone, onMouseOver, onMouseOut, onClick);
  1.   }
  2. }
  3. function setMouseListener(mesh, over, out, click) {
  4.   mesh.addEventListener(MouseEvent.MOUSE_OVER, over);
  5.   mesh.addEventListener(MouseEvent.MOUSE_OUT, out);
  6.   mesh.addEventListener(MouseEvent.CLICK, click);
  7. }
  8. function onMouseOver(eventObject) {
  9.   var mesh = eventObject.object;
  10.   changeScale(mesh, 1.5);
  11. }
  12. function onMouseOut(eventObject) {
  13.   var mesh = eventObject.object;
  14.   changeScale(mesh, 1);
  15. }
  1. function setScale(mesh, scale) {
  2.   mesh.scale = scale;
  3.   changeScale(mesh, 1);
  4. }
  5. function changeScale(mesh, scale) {
  6.   var _scale = mesh.scale * scale;
  7.   mesh.transform.scale = new Vector3D(_scale, _scale, _scale);
  8. }

図23■マウスポインタがロールオーバーすると立方体は大きくなる
図23左   図23右

コード014■ロールオーバーしたオブジェクトの大きさが変わる
  1. var LoaderEvent = require("awayjs-core/lib/events/LoaderEvent");
  2. var Vector3D = require("awayjs-core/lib/geom/Vector3D");
  3. var Matrix3D = require("awayjs-core/lib/geom/Matrix3D");
  4. var AssetLibrary = require("awayjs-core/lib/library/AssetLibrary");
  5. var URLRequest = require("awayjs-core/lib/net/URLRequest");
  6. var RequestAnimationFrame = require("awayjs-core/lib/utils/RequestAnimationFrame");
  7. var View = require("awayjs-display/lib/containers/View");
  8. var DirectionalLight = require("awayjs-display/lib/entities/DirectionalLight");
  9. var MouseEvent = require("awayjs-display/lib/events/MouseEvent"); //
  10. var StaticLightPicker = require("awayjs-display/lib/materials/lightpickers/StaticLightPicker");
  11. var PrimitiveCubePrefab = require("awayjs-display/lib/prefabs/PrimitiveCubePrefab");
  12. var DefaultRenderer = require("awayjs-renderergl/lib/DefaultRenderer");
  13. var TriangleMethodMaterial = require("awayjs-methodmaterials/lib/TriangleMethodMaterial");
  14. var view;
  15. var cube;
  16. var imageDiffuse = "assets/trinket_diffuse.jpg";
  17. var timer;
  18. var ORIGIN = new Vector3D();
  19. var angle = -Math.PI / 2;
  20. var distance = 1500;
  21. var stageWidth = 240;
  22. var stageHeight = 180;
  23. var urls = [
  24.   "http://gihyo.jp/design/serial/01/away3d-typescript",
  25.   "http://gihyo.jp/design/serial/01/createjs",
  26.   "http://typescript.away3d.com",
  27.   "https://developer.mozilla.org/ja/docs/Web/JavaScript",
  28.   "http://createjs.com/#!/Home"
  29. ];
  30. function initialize() {
  31.   var directionalLight = createDirectionalLight(0.5, 0xFFFFFF);
  32.   view = createView(stageWidth, stageHeight, 0x0);
  33.   cube = createCube(400, 400, 400, directionalLight);
  34.   setCamera(view.camera, distance, angle);
  35.   cube.url = "http://fumiononaka.com";
  36.   view.scene.addChild(cube);
  37.   cloneMesh(cube, urls);
  38.   AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
  39.   AssetLibrary.load(new URLRequest(imageDiffuse));
  40.   timer = new RequestAnimationFrame(rotate);
  41.   timer.start();
  42.   view.render();
  43. }
  44. function createView(width, height, backgroundColor) {
  45.   var defaultRenderer = new DefaultRenderer();
  46.   var view = new View(defaultRenderer);
  47.   view.width = width;
  48.   view.height = height;
  49.   view.backgroundColor = backgroundColor;
  50.   view.forceMouseMove = true;
  51.   return view;
  52. }
  53. function createCube(width, height, depth, light) {
  54.   var material = new TriangleMethodMaterial();
  55.   var cube = new PrimitiveCubePrefab(width, height, depth, 1, 1, 1, false)
  56.   .getNewObject();
  57.   cube.material = material;
  58.   setScale(cube, 1);
  59.   setMouseListener(cube, onMouseOver, onMouseOut, onClick);
  60.   material.lightPicker = new StaticLightPicker([light]);
  61.   return cube;
  62. }
  63. function cloneMesh(mesh, urls) {
  64.   var scene = view.scene;
  65.   var count = urls.length;
  66.   for (var i = 0; i < count; i++) {
  67.     var clone = mesh.clone();
  68.     var distance = getRandom(500, 1200);
  69.     var scale = getRandom(0.3, 0.5);
  70.     var rotationX = getRandom(-60, 60);
  71.     var rotationY = getRandom(-180, 180);
  72.     var position = getPolarPosition(distance, rotationX, rotationY);
  73.     clone.x = position.x;
  74.     clone.y = position.y;
  75.     clone.z = position.z;
  76.     clone.url = urls[i];
  77.     setScale(clone, scale);
  78.     clone.rotationY = rotationY;
  79.     setMouseListener(clone, onMouseOver, onMouseOut, onClick);
  80.     scene.addChild(clone);
  81.   }
  82. }
  83. function setMouseListener(mesh, over, out, click) {
  84.   mesh.addEventListener(MouseEvent.MOUSE_OVER, over);
  85.   mesh.addEventListener(MouseEvent.MOUSE_OUT, out);
  86.   mesh.addEventListener(MouseEvent.CLICK, click);
  87. }
  88. function onMouseOver(eventObject) {
  89.   var mesh = eventObject.object;
  90.   changeScale(mesh, 1.5);
  91. }
  92. function onMouseOut(eventObject) {
  93.   var mesh = eventObject.object;
  94.   changeScale(mesh, 1);
  95. }
  96. function onClick(eventObject) {
  97.   var mesh = eventObject.object;
  98.   window.open(mesh.url);
  99. }
  100. function setScale(mesh, scale) {
  101.   mesh.scale = scale;
  102.   changeScale(mesh, 1);
  103. }
  104. function changeScale(mesh, scale) {
  105.   var _scale = mesh.scale * scale;
  106.   mesh.transform.scale = new Vector3D(_scale, _scale, _scale);
  107. }
  108. function createDirectionalLight(ambient, color) {
  109.   var light = new DirectionalLight();
  110.   light.ambient = ambient;
  111.   light.color = color;
  112.   return light;
  113. }
  114. function onResourceComplete(eventObject) {
  115.   var assets = eventObject.assets;
  116.   var material = cube.material;
  117.   material.texture = assets[0];
  118.   view.render();
  119. }
  120. function rotate(timeStamp) {
  121.   var camera = view.camera;
  122.   angle += timeStamp / 2000;
  123.   setCamera(camera, distance, angle);
  124.   view.render();
  125. }
  126. function setCamera(camera, distance, angle) {
  127.   camera.x = Math.cos(angle) * distance;
  128.   camera.z = Math.sin(angle) * distance;
  129.   camera.lookAt(ORIGIN);
  130. }
  131. function getRandom(min, max) {
  132.   var random = Math.random() * (max - min) + min;
  133.   return random;
  134. }
  135. function getPolarPosition(distance, rotationX, rotationY) {
  136.   var vector = new Vector3D(distance, 0, 0);
  137.   var matrix = new Matrix3D();
  138.   matrix.appendRotation(rotationY, Vector3D.Y_AXIS);
  139.   matrix.appendRotation(rotationX, Vector3D.X_AXIS);
  140.   return matrix.transformVector(vector);
  141. }

Copyright © 2001-2015 Fumio Nonaka.  All rights reserved.