GameRenderer.js 2.73 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
const BACKGROUND_COLOR = "#333",
  DEFAULT_GAZE_POINT_RADIUS = 15,
  DEFAULT_GAZE_POINT_COLOR = "#3f0d76",
  DEBUG_POSITION_OFFSET = 10,
  DEBUG_FONT = "16px ShareTech",
  DEBUG_COLOR = "#ffffff",
  MAX_GAZE_POINT_AGE = 1000;

var lastUpdate,
  lastDelta,
  fpsBuffer,
  gazePoints,
  version,
  debug,
  frameRate,
  canvas,
  context,
  loop;

function onTick() {
  setDelta();
  updateGazePoints();
  context.clearRect(0, 0, canvas.width, canvas.height);
  drawGazePoints();
  if (debug === true) {
    drawDebugInfo();
  }
  setUpdateTime();
}

function setUpdateTime() {
  lastUpdate = Date.now();
}

function setDelta() {
  lastDelta = Date.now() - lastUpdate;
}

function addGazePoint(point) {
  gazePoints.set(point.id, point);
}

function removeGazePoint(point) {
  gazePoints.delete(point.id);
}

function updateGazePoints() {
  let now = Date.now();
  for (let item of gazePoints) {
    let point = item[1];
    if (now - point.createdAt > MAX_GAZE_POINT_AGE) {
      removeGazePoint(point);
    }
  }
}

function drawGazePoints() {
  let now = Date.now();
  context.fillStyle = DEFAULT_GAZE_POINT_COLOR;
  for (let item of gazePoints) {
    let relativeAge = 1 - ((now - item[1].createdAt) /
      MAX_GAZE_POINT_AGE);
    context.save();
    context.globalAlpha = relativeAge;
    context.beginPath();
    context.ellipse(item[1].targetX, item[1].targetY,
      relativeAge * DEFAULT_GAZE_POINT_RADIUS, relativeAge *
      DEFAULT_GAZE_POINT_RADIUS, Math.PI / 4,
      0, 2 * Math.PI);
    context.fill();
    context.closePath();
    context.restore();
  }
}

function drawDebugInfo() {
  let fps = parseInt(1000 / lastDelta),
    averageFps;
  fpsBuffer.push(fps);
  if (fpsBuffer.length === frameRate) {
    averageFps = parseInt(fpsBuffer.reduce((a, b) => a + b, 0) / fpsBuffer.length);
    fpsBuffer.shift();
  }
  context.beginPath();
  context.font = DEBUG_FONT;
  context.fillStyle = DEBUG_COLOR;
  context.fillText(`${version} | ${averageFps}fps`, DEBUG_POSITION_OFFSET, canvas.height-DEBUG_POSITION_OFFSET);
  context.closePath();
}

class GameRenderer {

  constructor() {
    fpsBuffer = [];
    gazePoints = new Map();
  }

  start(options) {
    canvas = options.canvas;
    canvas.width = options.width;
    canvas.height = options.height;
    canvas.style.width = `${options.width}px`;
    canvas.style.height = `${options.height}px`;
    context = canvas.getContext("2d", { alpha: false });
    canvas.style.backgroundColor = BACKGROUND_COLOR;
    frameRate = options.frameRate;
    version = options.version;
    debug = options.debug;
    setUpdateTime();
    loop = setInterval(onTick, (1000 / frameRate));
  }

  addGazePoint(point) {
    addGazePoint(point);
  }

  removeGazePoint(point) {
    removeGazePoint(point);
  }

}

export default new GameRenderer();