Skip to content

Instantly share code, notes, and snippets.

@kalley
Created February 7, 2014 18:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kalley/8868315 to your computer and use it in GitHub Desktop.
Save kalley/8868315 to your computer and use it in GitHub Desktop.
Simple wrapper around canvas
var Canvas = (function() {
var Canvas = function(id, width, height) {
this.el = id.nodeName ? id : document.getElementById(id);
this.context = this.el.getContext('2d');
this._events = {};
if ( width || height ) this.size(width, height);
},
proto = Canvas.prototype,
started = false,
extendProto = function(p, obj) {
if ( typeof obj[p] === 'function' ) {
proto[p] = function() {
var argsLength = arguments.length;
if ( started !== this ) this.start();
// if statements are much faster than switch statements in newer versions of Chrome
// and marginally slower in other browsers http://jsperf.com/if-switch-lookup-table
if ( argsLength === 0 ) { bufferContext[p]() };
if ( argsLength === 1 ) { bufferContext[p](arguments[0]) };
if ( argsLength === 2 ) { bufferContext[p](arguments[0], arguments[1]) };
if ( argsLength === 3 ) { bufferContext[p](arguments[0], arguments[1], arguments[2]) };
if ( argsLength === 4 ) { bufferContext[p](arguments[0], arguments[1], arguments[2], arguments[3]) };
if ( argsLength === 5 ) { bufferContext[p](arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]) };
if ( argsLength === 6 ) { bufferContext[p](arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]) };
if ( argsLength > 6 ) { bufferContext[p].apply(bufferContext, arguments) };
return this;
};
} else {
proto[p] = function(val) {
var match;
if ( ! val ) return bufferContext[p];
if ( started !== this ) this.start();
if ( typeof val === 'string' && ( match = val.match(/^([+-])=(.*)/) ) ) {
bufferContext[p] = ( match[1] + 1 ) * match[2] + bufferContext[p];
} else {
bufferContext[p] = val;
}
return this;
};
}
},
buffer = document.createElement('canvas'),
bufferContext = buffer.getContext('2d'),
img,
p;
// Add the context methods and properties as functions to the prototype
for ( p in bufferContext ) {
extendProto(p, bufferContext);
}
// Create a new canvas
Canvas.create = function(width, height) {
var canvas = new Canvas(document.createElement('canvas'));
return ( width || height ) ? canvas.size(width, height) : canvas;
};
// This basically allows for resetting the buffer canvas
// You should ever really have to use it, but it's here
proto.start = function() {
started = this;
buffer.width = this.el.width;
buffer.height = this.el.height;
return this;
};
// draw the buffer to the main canvas
proto.draw = function() {
started = false;
this.context.clearRect(0, 0, this.el.width, this.el.height);
this.context.drawImage(buffer, 0, 0);
return this;
};
proto.size = function(width, height) {
if ( arguments.length === 0 ) {
return { width: this.el.width, height: this.el.height };
}
this.el.width = width;
this.el.height = height;
return this;
};
// clear the whole thing
proto.clearAll = function() {
return this.clearRect(0, 0, this.el.width, this.el.height);
};
// fill the whole thing
proto.fillAll = function() {
return this.fillRect(0, 0, this.el.width, this.el.height);
};
// Event listener stuff
proto.on = function(eventName, fn) {
var existing = this._events[eventName],
rawEventName = eventName.split(/[.:]/)[0];
if ( ! existing ) {
this._events[eventName] = [];
existing = this._events[eventName];
}
existing.push(fn);
this.el.addEventListener(rawEventName, fn, false);
return this;
};
proto.off = function(eventName) {
var existing = this._events[eventName] || [],
rawEventName = eventName.split(/[.:]/)[0],
i = 0,
p,
l;
if ( eventName === rawEventName ) {
for ( p in this._events ) {
if ( p.match(new RegExp('^' + eventName + '[.:].*')) ) {
existing = existing.concat(this._events[p]);
}
}
}
for ( l = existing.length; i < l; ++i ) {
this.el.removeEventListener(rawEventName, existing[i]);
}
};
return Canvas;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment