if (typeof(define) !== "function") {
var define = require("amdefine")(module);
}
define([
"odin/base/event_emitter",
"odin/base/device",
"odin/base/dom",
"odin/core/game/log",
"odin/core/game/config"
],
function(EventEmitter, Device, Dom, Log, Config) {
"use strict";
var addEvent = Dom.addEvent,
removeEvent = Dom.removeEvent,
addMeta = Dom.addMeta,
floor = Math.floor,
CANVAS_ID = 0,
SCALE_REG = /-scale\s *=\s*[.0-9]+/g,
VIEWPORT = "viewport",
VIEWPORT_WIDTH = "viewport-width",
VIEWPORT_HEIGHT = "viewport-height",
CANVAS_STYLE = [
"background: #000000;",
"position: absolute;",
"top: 50%;",
"left: 50%;",
"padding:0px;",
"margin: 0px;"
].join("\n");
addMeta(VIEWPORT, "viewport", "initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no");
addMeta(VIEWPORT_WIDTH, "viewport", "width=device-width");
addMeta(VIEWPORT_HEIGHT, "viewport", "height=device-height");
/**
* @class Canvas
* @extends EventEmitter
* @brief canvas helper
* @param Number width
* @param Number height
*/
function Canvas(opts) {
opts || (opts = {});
EventEmitter.call(this);
/**
* @property Number canvasId
* @memberof Canvas
*/
this.canvasId = ++CANVAS_ID;
/**
* @property Boolean fullScreen
* @memberof Canvas
*/
this.fullScreen = opts.fullScreen ? opts.fullScreen : (opts.width == undefined && opts.height == undefined) ? true : false;
/**
* @property String customCursor
* @memberof Canvas
*/
this.customCursor = opts.customCursor != undefined ? opts.customCursor : false;
/**
* @property Boolean hideMouse
* @memberof Canvas
*/
this.hideMouse = opts.hideMouse != undefined ? opts.hideMouse : false;
/**
* @property Number width
* @memberof Canvas
*/
this.width = opts.width !== undefined ? opts.width : window.innerWidth;
/**
* @property Number height
* @memberof Canvas
*/
this.height = opts.height !== undefined ? opts.height : window.innerHeight;
/**
* @property Number aspect
* @memberof Canvas
*/
this.aspect = this.width / this.height;
/**
* @property Number pixelWidth
* @memberof Canvas
*/
this.pixelWidth = this.width;
/**
* @property Number pixelHeight
* @memberof Canvas
*/
this.pixelHeight = this.height;
/**
* @property HTMLCanvasElement element
* @memberof Canvas
*/
this.element = undefined;
}
EventEmitter.extend(Canvas);
Canvas.prototype.init = function() {
if (this.element) this.destroy();
var element = document.createElement("canvas"),
style = element.style;
element.id = "canvas-" + this.canvasId;
style.cssText = CANVAS_STYLE;
style.cursor = this.customCursor ? "url(" + this.customCursor + ")" : this.hideMouse ? "none" : "default";
document.body.appendChild(element);
if (!Config.debug) {
element.oncontextmenu = function() {
return false;
};
}
addEvent(window, "resize orientationchange", this.handleResize, this);
element.requestPointerLock || (element.requestPointerLock = (
element.webkitRequestPointerLock ||
element.mozRequestPointerLock ||
element.oRequestPointerLock ||
element.msRequestPointerLock
));
element.exitPointerLock || (element.exitPointerLock = (
document.webkitExitPointerLock ||
document.mozExitPointerLock ||
document.oExitPointerLock ||
document.msExitPointerLock
));
element.requestFullscreen || (element.requestFullscreen = (
element.webkitRequestFullscreen ||
element.mozRequestFullscreen ||
element.oRequestFullscreen ||
element.msRequestFullscreen
));
element.exitFullscreen || (element.exitFullscreen = (
element.webkitExitFullscreen ||
element.mozExitFullscreen ||
element.oExitFullscreen ||
element.msExitFullscreen
));
this.element = element;
this.handleResize();
};
Canvas.prototype.clear = function() {
if (!this.element) return this;
removeEvent(window, "resize orientationchange", this.handleResize, this);
document.body.removeChild(this.element);
this.element = undefined;
return this;
};
/**
* @method setFullscreen
* @memberof Canvas
* @brief sets fullScreen boolean
* @param Number width
*/
Canvas.prototype.setFullscreen = function(value) {
if (!this.element || this.fullScreen === value) return this;
this.fullScreen = !! value;
this.handleResize();
return this;
};
/**
* @method setWidth
* @memberof Canvas
* @brief sets width and updates aspect
* @param Number width
*/
Canvas.prototype.setWidth = function(width) {
if (!this.element || this.width === width) return this;
this.width = width;
this.fullScreen = false;
this.aspect = this.width / this.height;
this.handleResize();
return this;
};
/**
* @method setHeight
* @memberof Canvas
* @brief sets height and updates aspect
* @param Number height
*/
Canvas.prototype.setHeight = function(height) {
if (!this.element || this.height === height) return this;
this.height = height;
this.fullScreen = false;
this.aspect = this.width / this.height;
this.handleResize();
return this;
};
/**
* @method style
* @memberof Canvas
* @brief sets style of html element
* @param String key
* @param String value
*/
Canvas.prototype.style = function(key, value) {
if (!this.element) return this;
this.element.style[key] = value;
return this;
};
/**
* @method setBackgroundColor
* @memberof Canvas
* @brief sets html background color
* @param String color
*/
Canvas.prototype.setBackgroundColor = function(color) {
if (!this.element) return this;
this.element.style.background = color;
return this;
};
Canvas.prototype.handleResize = function() {
var viewportScale = document.getElementById(VIEWPORT).getAttribute("content"),
w = window.innerWidth,
h = window.innerHeight,
aspect = w / h,
element = this.element,
style = element.style,
width, height;
if (this.fullScreen) {
width = w;
height = h;
} else {
if (aspect > this.aspect) {
width = h * this.aspect;
height = h;
} else {
width = w;
height = w / this.aspect;
}
}
this.pixelWidth = floor(width);
this.pixelHeight = floor(height);
element.width = width;
element.height = height;
style.marginLeft = -floor((width + 1) * 0.5) + "px";
style.marginTop = -floor((height + 1) * 0.5) + "px";
style.width = floor(width) + "px";
style.height = floor(height) + "px";
document.getElementById(VIEWPORT).setAttribute("content", viewportScale.replace(SCALE_REG, "-scale=" + Device.invPixelRatio));
document.getElementById(VIEWPORT_WIDTH).setAttribute("content", "width=" + w);
document.getElementById(VIEWPORT_HEIGHT).setAttribute("content", "height=" + h);
window.scrollTo(1, 1);
this.emit("resize");
};
return Canvas;
}
);