c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

js Canvasにて六角形のタイル

初めてHTML5 Canvas APIを使ってみたよ…。
[SpinorNetwork http://spinornetwork.heroku.com/ ]のロゴを表すコードです。
[Processing http://processing.org/ ]に似せてる。本体は最後尾あたり、setup()とdraw()の定義、line244 - line255です。
requestAnimationFrame()に対応してれば其れを、無ければ傲慢なsetInterval()にてアニメーションしてる。SpinorNetwork_logotype_416x101.pngを拾ってきて

<canvas class="barnner"></canvas>

に向けて以下のjsを貼れば、キミもSpinorNetworkだ!

/**
 * @fileOverview Crain's SpinorNetrork Canvas barnner.
 * Drawing like Processing.
 * @author ne_Sachirou http://c4se.tk/profile/ne.html
 * @version 2012/02/16
 * @license MIT License
 */

(function () {

/**@constant*/
var LOGOTYPE = new Image(),
    ROOT3 = Math.sqrt(3);
var canvas = document.getElementsByClassName('barnner')[0],
    context = canvas.getContext('2d'),
    sqrt = Math.sqrt,
    pow = Math.pow,
    ceil = Math.ceil,
    hexagonTiles = [],
    width = 0,
    height = 0,
    fill = null, // {String} fillStyle color
    stroke = null, // {String} strokeStyle color
    alpha = 1, // {Number} globalAlpha
    strokeWidth = 1, // {Number} lineWidth
    strokeCap = 'butt', // {'butt'|'round'|'square'} lineCap
    strokeJoin = 'miter', // {'round'|'bevel'|'miter'} lineJoin
    mouseX = 0,
    mouseY = 0,
    pmouseX = 0, // previous mouseX
    pmouseY = 0; // previous mouseY

LOGOTYPE.src = '/images/SpinorNetwork_logotype_416x101.png';


/**
 * Set global mouseX, mouseY, pmouseX, pmouseY variable.
 * @param {MouseEvent} evt MouseMoveEvent Object
 */
function getMousePoint (evt) {
  var rect;

  pmouseX = mouseX;
  pmouseY = mouseY;
  if (evt.offsetX) {
    mouseX = evt.offsetX;
    mouseY = evt.offsetY;
  } else if (evt.layerX) {
    mouseX = evt.layerX;
    mouseY = evt.layerY;
  } else {
    rect = evt.target.getBoundingClientRect();
    mouseX = evt.clientX - rect.left;
    mouseY = evt.clientY - rect.top;
  }
}
canvas.addEventListener('mousemove', getMousePoint, false);
canvas.addEventListener('mouseout', function (evt) {
  pmouseX = mouseX;
  pmouseY = mouseY;
}, false);


/**
 * Set Canvas context properties by global Processing like variables.
 */
function adjustEnvironment () {
  if (fill) {context.fillStyle = fill;}
  if (stroke) {context.strokeStyle = stroke;}
  if (alpha < 0) {alpha = 0;}
  context.globalAlpha = alpha - 0;
  if (strokeWidth < 0) {strokeWidth = 0;}
  context.lineWidth = strokeWidth - 0;
  context.lineCap = strokeCap || 'butt';
  context.lineJoin = strokeJoin || 'miter';
}


/**
 * @param {Function} callbask
 * @return {Function} Stop animation function.
 */
function _animate (callback) {
  var timerID,
      stop,
      requestAnimationFrame,
      cancelRequestAnimationFrame;

  function animationFun () {
    adjustEnvironment();
    context.clearRect(0, 0, width, height);
    callback();
  }

  if (window.RequestAnimationFrame) {
    requestAnimationFrame = window.requestAnimationFrame;
    cancelRequestAnimationFrame = window.cancelRequestAnimationFrame;
  } else if (window.mozrequestAnimationFrame) {
    requestAnimationFrame = window.mozRequestAnimationFrame;
    cancelRequestAnimationFrame = window.mozCancelRequestAnimationFrame;
  } else if (window.msRequestAnimationFrame) {
    requestAnimationFrame = window.msRequestAnimationFrame;
    cancelRequestAnimationFrame = window.msCancelRequestAnimationFrame;
  } else if (window.webkitRequestAnimationFrame) {
    requestAnimationFrame = window.webkitRequestAnimationFrame;
    cancelRequestAnimationFrame = window.webkitCancelRequestAnimationFrame;
  }

  if (requestAnimationFrame) {
    timerID = requestAnimationFrame(animationFun);
    stop = function () {
      cancelRequestAnimationFrame(timerID);
    };
  } else {
    timerID = setInterval(animationFun, 16);
    stop = function () {
      clearInterval(timerID);
    };
  }
  return stop;
}


/**
 * @param {Number} w
 * @param {Number} h
 */
function size (w, h) {
  canvas.width = w;
  canvas.height = h;
  width = w;
  height = h;
}


function drawBackground () {
  context.globalAlpha = 0;
  // some will be written in futute
  context.globalAlpha = 1;
}


function drawLogotype () {
  adjustEnvironment();
  context.drawImage(LOGOTYPE, 8, 8, width - 8, height - 8);
}


/**
 * @param {Number} x
 * @param {Number} y
 * @param {number} radius
 */
function drawHexagon (x, y, radius) {
  context.beginPath();
  context.moveTo(x, y + radius / 2);
  context.lineTo(x, y + radius * 1.5);
  context.lineTo(x + radius * ROOT3 / 2, y + radius * 2);
  context.lineTo(x + radius * ROOT3, y + radius * 1.5);
  context.lineTo(x + radius * ROOT3, y + radius / 2);
  context.lineTo(x + radius * ROOT3 / 2, y);
  context.lineTo(x, y + radius / 2);
  context.closePath();
  adjustEnvironment();
  if (stroke) {
    context.stroke();
  }
  if (fill) {
    context.fill();
  }
}


/**
 * @param {Number} x
 * @param {Number} y
 * @param {Number} radius
 * @return {Boolean}
 */
function isMouseInHexagon (x, y, radius) {
  return sqrt(pow(x + radius * ROOT3 / 2 - mouseX, 2) + pow(y + radius - mouseY, 2)) < radius;
}


/**
 * @param {Number} radius
 * @param {Array} tiles ({String} color, {Number} alpha)[]
 */
function drawHexagonTile (radius, tiles) {
  /**@constant*/
  var GRID_X = radius * ROOT3 / 2,
      GRID_Y = radius * 1.5;
  var tile,
      x = -GRID_X,
      y = -GRID_Y,
      countX = 0,
      countY = 0;

  while (y <= height) {
    while (x <= width) {
      tile = tiles[countX][countY];
      if (tile[1] > 0) {
        tiles[countX][countY][1] = tile[1] - 0.01;
      }
      if (pmouseX !== mouseX && pmouseY !== mouseY &&
          isMouseInHexagon(x, y, radius)) {
        tiles[countX][countY][1] = 1;
      }
      tile = tiles[countX][countY];
      fill = tile[0];
      stroke = tile[0];
      alpha = tile[1];
      drawHexagon(x, y, radius);
      countX += 1;
      x += GRID_X * 2;
    }
    countX = 0;
    countY += 1;
    x = countY % 2 ? 0 : -GRID_X;
    y += GRID_Y;
  }
}


/**
 * Initialize global hexagonTile Array.
 * @param {Number} radius
 */
function initHexagonTiles (radius) {
  var numX = ceil(width / (radius * ROOT3) + 0.5),
      numY = ceil(height / (radius * 1.5)),
      countX = 0,
      countY = 0;

  for (countX = 0; countX <= numX; countX += 1) {
    hexagonTiles[countX] = [];
    for(countY = 0; countY <= numY; countY += 1) {
      hexagonTiles[countX][countY] = ['white', 0];
    }
  }
}


function setup () {
  size(432, 117);
  initHexagonTiles(16);
}


function draw () {
  drawBackground();
  drawHexagonTile(16, hexagonTiles);
  alpha = 1;
  drawLogotype();
}


setup();
_animate(draw);

}());