boosh
Version:
spawn a window and draw stuff using the html5 canvas api"
208 lines (164 loc) • 4.35 kB
JavaScript
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var binding = require('bindings')('boosh');
var context2d = require('context2d');
var fs = require('fs');
var NativeWindow = binding.Window;
var AnimationFrame = require('animationframe');
var events = require('./lib/event');
function Window(options) {
options = options || {};
options.width = options.width || 640;
options.height = options.height || 480;
options.title = options.title || 'boosh!';
options.fullscreen = options.fullscreen || false;
EventEmitter.call(this);
this._window = new NativeWindow(options.width, options.height, options.title);
if (!this._window) {
return;
}
// Event dispatcher
this._window.eventHandler(function(raw) {
raw.target = this;
var objectType = raw.objectType || 'Event';
var ev = new (events[objectType])(raw.type, raw);
// window.on<event> handlers
var lower = raw.type.toLowerCase();
if (typeof this['on' + lower] === 'function') {
this[lower](ev);
}
this.emit(raw.type, ev);
if (raw.type === 'close' && !ev.defaultPrevented) {
this.close();
}
}.bind(this));
this.addEventListener = this.on;
this.removeEventListener = this.removeListener;
Object.defineProperty(this, 'title', {
set: function(v) {
title = v;
return this._window.setTitle(v);
},
get : function() {
return title;
},
configurable: false
});
var manager = new AnimationFrame(function() {
if (this.context && this.context.dirty) {
this._window.flush();
}
}.bind(this));
this.requestAnimationFrame = manager.requestAnimationFrame;
this.cancelAnimationFrame = manager.cancelAnimationFrame;
this.close = function() {
this._window.close();
delete this._window;
delete this.context;
manager.destroy();
};
}
util.inherits(Window, EventEmitter);
var windowPrototypeProperty = function(properties, get, set) {
if (!Array.isArray(properties)) {
properties = [properties];
}
var definition = {
configurable : false
};
if (get) {
definition.get = get;
}
if (set) {
definition.set = set;
}
properties.forEach(function(name) {
Object.defineProperty(Window.prototype, name, definition);
});
};
windowPrototypeProperty(['outerWidth', 'innerWidth'], function() {
var rect = this._window.getRect();
if (rect) {
return rect.width;
}
});
windowPrototypeProperty(['outerHeight', 'innerHeight'], function() {
var rect = this._window.getRect();
if (rect) {
return rect.height;
}
});
windowPrototypeProperty(['screenTop', 'screenX'], function() {
var rect = this._window.getRect();
if (rect) {
return rect.x;
}
},
function(v) {
var rect = this._window.getRect();
if (rect) {
this.moveTo(v, rect.y);
}
});
windowPrototypeProperty(['screenLeft', 'screenY'], function() {
var rect = this._window.getRect();
if (rect) {
return rect.y;
}
},
function(v) {
var rect = this._window.getRect();
if (rect) {
this.moveTo(rect.x, v);
}
});
Window.prototype.resizeTo = function(w, h) {
w = w || 0;
h = h || 0;
this._window.resizeTo(w, h);
};
Window.prototype.resizeBy = function(w, h) {
var rect = this._window.getRect();
if (rect) {
this.resizeTo(rect.width + w, rect.height + h);
}
};
Window.prototype.moveTo = function(x, y) {
x = x || 0;
y = y || 0;
this._window.moveTo(x, y);
};
Window.prototype.moveBy = function(x, y) {
var rect = this._window.getRect();
if (rect) {
this.moveTo(rect.x + x, rect.y + y);
}
};
Window.prototype.blur = Window.prototype.focus = function() {
throw new Error('DERP - stealing focus isn\'t cool');
}
Window.prototype.getContext = function(type) {
if (this.context) {
throw new Error('context already created');
}
if (type === '2d') {
this.context = context2d.createContext(this, this.width, this.height, binding.Context2D);
this._window.setContext2d(this.context);
return this.context;
}
this.context = this.canvas.getContext(type);
return this.context;
};
/*
options:
width : <int>
height: <int>
fullscreen: <int>
*/
module.exports.createWindow = function(options) {
var ret = new Window(options);
if (!ret) {
throw new Error('window could not be created');
}
return ret;
};