canvas
Version:
Canvas graphics API backed by Cairo
274 lines (237 loc) • 5.69 kB
JavaScript
'use strict';
/*!
* Canvas - Context2d
* Copyright (c) 2010 LearnBoost <tj@learnboost.com>
* MIT Licensed
*/
/**
* Module dependencies.
*/
const bindings = require('./bindings')
const parseFont = require('./parse-font')
const Context2d = module.exports = bindings.CanvasRenderingContext2d
const CanvasGradient = bindings.CanvasGradient
const CanvasPattern = bindings.CanvasPattern
const ImageData = bindings.ImageData
const DOMMatrix = require('./DOMMatrix').DOMMatrix
/**
* Text baselines.
*/
var baselines = ['alphabetic', 'top', 'bottom', 'middle', 'ideographic', 'hanging'];
/**
* Create a pattern from `Image` or `Canvas`.
*
* @param {Image|Canvas} image
* @param {String} repetition
* @return {CanvasPattern}
* @api public
*/
Context2d.prototype.createPattern = function(image, repetition){
return new CanvasPattern(image, repetition || 'repeat');
};
/**
* Create a linear gradient at the given point `(x0, y0)` and `(x1, y1)`.
*
* @param {Number} x0
* @param {Number} y0
* @param {Number} x1
* @param {Number} y1
* @return {CanvasGradient}
* @api public
*/
Context2d.prototype.createLinearGradient = function(x0, y0, x1, y1){
return new CanvasGradient(x0, y0, x1, y1);
};
/**
* Create a radial gradient at the given point `(x0, y0)` and `(x1, y1)`
* and radius `r0` and `r1`.
*
* @param {Number} x0
* @param {Number} y0
* @param {Number} r0
* @param {Number} x1
* @param {Number} y1
* @param {Number} r1
* @return {CanvasGradient}
* @api public
*/
Context2d.prototype.createRadialGradient = function(x0, y0, r0, x1, y1, r1){
return new CanvasGradient(x0, y0, r0, x1, y1, r1);
};
/**
* Reset transform matrix to identity, then apply the given args.
*
* @param {...}
* @api public
*/
Context2d.prototype.setTransform = function(){
this.resetTransform();
this.transform.apply(this, arguments);
};
Object.defineProperty(Context2d.prototype, 'currentTransform', {
get: function () {
var values = new Float64Array(6)
this._getMatrix(values)
return new DOMMatrix(values)
},
set: function (m) {
if (!(m instanceof DOMMatrix)) {
throw new TypeError('Expected DOMMatrix')
}
this.setTransform(m.a, m.b, m.c, m.d, m.e, m.f)
},
configurable: true
})
/**
* Set the fill style with the given css color string.
*
* @api public
*/
Context2d.prototype.__defineSetter__('fillStyle', function(val){
if (val instanceof CanvasGradient
|| val instanceof CanvasPattern) {
this.lastFillStyle = val;
this._setFillPattern(val);
} else {
this.lastFillStyle = undefined;
this._setFillColor(String(val));
}
});
/**
* Get previous fill style.
*
* @return {CanvasGradient|String}
* @api public
*/
Context2d.prototype.__defineGetter__('fillStyle', function(){
return this.lastFillStyle || this.fillColor;
});
/**
* Set the stroke style with the given css color string.
*
* @api public
*/
Context2d.prototype.__defineSetter__('strokeStyle', function(val){
if (val instanceof CanvasGradient
|| val instanceof CanvasPattern) {
this.lastStrokeStyle = val;
this._setStrokePattern(val);
} else {
this._setStrokeColor(String(val));
}
});
/**
* Get previous stroke style.
*
* @return {CanvasGradient|String}
* @api public
*/
Context2d.prototype.__defineGetter__('strokeStyle', function(){
return this.lastStrokeStyle || this.strokeColor;
});
/**
* Set font.
*
* @see exports.parseFont()
* @api public
*/
Context2d.prototype.__defineSetter__('font', function(val){
if (!val) return;
if ('string' == typeof val) {
var font;
if (font = parseFont(val)) {
this.lastFontString = val;
this._setFont(
font.weight
, font.style
, font.size
, font.unit
, font.family);
}
}
});
/**
* Get the current font.
*
* @api public
*/
Context2d.prototype.__defineGetter__('font', function(){
return this.lastFontString || '10px sans-serif';
});
/**
* Set text baseline.
*
* @api public
*/
Context2d.prototype.__defineSetter__('textBaseline', function(val){
if (!val) return;
var n = baselines.indexOf(val);
if (~n) {
this.lastBaseline = val;
this._setTextBaseline(n);
}
});
/**
* Get the current baseline setting.
*
* @api public
*/
Context2d.prototype.__defineGetter__('textBaseline', function(){
return this.lastBaseline || 'alphabetic';
});
/**
* Set text alignment.
*
* @api public
*/
Context2d.prototype.__defineSetter__('textAlign', function(val){
switch (val) {
case 'center':
this._setTextAlignment(0);
this.lastTextAlignment = val;
break;
case 'left':
case 'start':
this._setTextAlignment(-1);
this.lastTextAlignment = val;
break;
case 'right':
case 'end':
this._setTextAlignment(1);
this.lastTextAlignment = val;
break;
}
});
/**
* Get the current font.
*
* @see exports.parseFont()
* @api public
*/
Context2d.prototype.__defineGetter__('textAlign', function(){
return this.lastTextAlignment || 'start';
});
/**
* Create `ImageData` with the given dimensions or
* `ImageData` instance for dimensions.
*
* @param {Number|ImageData} width
* @param {Number} height
* @return {ImageData}
* @api public
*/
Context2d.prototype.createImageData = function (width, height) {
if (typeof width === 'object') {
height = width.height
width = width.width
}
var Bpp = this.canvas.stride / this.canvas.width;
var nBytes = Bpp * width * height
var arr;
if (this.pixelFormat === "RGB16_565") {
arr = new Uint16Array(nBytes / 2);
} else {
arr = new Uint8ClampedArray(nBytes);
}
return new ImageData(arr, width, height);
}