pixi-pixelate
Version:
draw proper pixelated graphic primitives for pixi.js (i.e., point, line, circle, ellipse, arc, and filled versions)
763 lines (692 loc) • 82.5 kB
JavaScript
'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var PIXI = require('pixi.js');
var Angle = require('yy-angle');
/**
* pixi-pixelate: a container to create proper pixelated graphics
*/
var Pixelate = function (_PIXI$Container) {
_inherits(Pixelate, _PIXI$Container);
function Pixelate() {
_classCallCheck(this, Pixelate);
var _this = _possibleConstructorReturn(this, (Pixelate.__proto__ || Object.getPrototypeOf(Pixelate)).call(this));
_this.cursor = { x: 0, y: 0 };
_this.tint = 0xffffff;
_this._lineStyle = { width: 1, tint: 0xffffff, alpha: 1, direction: 'up' };
_this.cache = [];
return _this;
}
/**
* clear all graphics
* @returns {Pixelate}
*/
_createClass(Pixelate, [{
key: 'clear',
value: function clear() {
while (this.children.length) {
this.cache.push(this.children.pop());
}
return this;
}
/**
* texture to use for sprites (defaults to PIXI.Texture.WHITE)
* @type {PIXI.Texture}
*/
}, {
key: 'getPoint',
/**
* creates or gets an old sprite
* @param {number} tint
* @param {number} alpha
* @private
*/
value: function getPoint(tint, alpha) {
var point = void 0;
if (this.cache.length) {
point = this.addChild(this.cache.pop());
} else {
point = this.addChild(new PIXI.Sprite(Pixelate.texture));
}
point.tint = typeof tint === 'undefined' ? this._lineStyle.tint : tint;
point.alpha = typeof alpha === 'undefined' ? this._lineStyle.alpha : alpha;
return point;
}
/**
* draw a list of points
* @param {(number[]|PIXI.Point[]|PIXI.PointLike[])} points
* @param {number} tint
* @param {number} alpha
*/
}, {
key: 'points',
value: function points(_points, tint, alpha) {
if (isNaN(_points[0])) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = _points[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var point = _step.value;
this.point(point.x, point.y, tint, alpha);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
} else {
for (var i = 0; i < _points.length; i += 2) {
this.point(_points[i], _points[i + 1], tint, alpha);
}
}
}
/**
* add a point using lineStyle or provided tint and alpha
* @param {number} x
* @param {number} y
* @param {number} [tint]
* @param {number} [alpha]
* @returns {Pixelate}
*/
}, {
key: 'point',
value: function point(x, y, tint, alpha) {
var point = this.getPoint(tint, alpha);
point.position.set(x, y);
point.width = point.height = 1;
return this;
}
/**
* if lineStyle.width > 1 then use this direction to place the next line; center=alternate up and down
* @typedef {string} LineDirection (up, center, down)
*/
/**
* set linestyle for pixelated layer
* NOTE: width only works for line() for now
* @param {number} width
* @param {number} [tint=0xffffff]
* @param {number} [alpha=1]
* @param {LineDirection} [direction=up] (up, center, down)
* @returns {Pixelate}
*/
}, {
key: 'lineStyle',
value: function lineStyle(width, tint, alpha, direction) {
this._lineStyle.width = width;
this._lineStyle.tint = typeof tint !== 'undefined' ? tint : 0xffffff;
this._lineStyle.alpha = typeof alpha !== 'undefined' ? alpha : 1;
this._lineStyle.direction = direction || 'up';
return this;
}
/**
* move cursor to this location
* @param {number} x
* @param {number} y
* @returns {Pixelate}
*/
}, {
key: 'moveTo',
value: function moveTo(x, y) {
this.cursor.x = x;
this.cursor.y = y;
return this;
}
/**
* draw a pixelated line between two points and move cursor to the second point
* @param {number} x0
* @param {number} y0
* @param {number} x1
* @param {number} y1
* @param {number} [tint]
* @param {number} [alpha]
* @param {number} [lineWidth]
* @param {LineDirection} [lineDirection]
* @returns {Pixelate}
*/
}, {
key: 'line',
value: function line(x0, y0, x1, y1, tint, alpha, lineWidth, lineDirection) {
lineWidth = typeof lineWidth === 'undefined' ? this._lineStyle.width : lineWidth;
lineDirection = lineDirection || this._lineStyle.direction;
if (lineWidth === 1) {
this.drawPoints(this.linePoints(x0, y0, x1, y1), tint, alpha);
} else {
var angle = Angle.angleTwoPoints(x0, y0, x1, y1) + Math.PI / 2 * (lineDirection === 'up' ? -1 : 1);
var cos = Math.cos(angle);
var sin = Math.sin(angle);
var points = [];
if (lineDirection === 'center') {
var half = lineWidth / 2;
points.push(x0 + Math.round(cos * half), y0 + Math.round(sin * half));
points.push(x1 + Math.round(cos * half), y1 + Math.round(sin * half));
points.push(x1 - Math.round(cos * half), y1 - Math.round(sin * half));
points.push(x0 - Math.round(cos * half), y0 - Math.round(sin * half));
} else {
points.push(x0, y0);
points.push(x0 + Math.round(cos * lineWidth), y0 + Math.round(sin * lineWidth));
points.push(x1 + Math.round(cos * lineWidth), y1 + Math.round(sin * lineWidth));
points.push(x1, y1);
}
this.polygonFill(points, tint, alpha, 1);
}
return this;
}
/**
* draw a pixelated line between two points and move cursor to the second point
* based on https://github.com/madbence/node-bresenham/blob/master/index.js
* @private
* @param {number} x0
* @param {number} y0
* @param {number} x1
* @param {number} y1
* @param {number[]} [points]
* @returns {number[]}
*/
}, {
key: 'linePoints',
value: function linePoints(x0, y0, x1, y1, points) {
points = points || [];
points.push([x0, y0]);
var dx = x1 - x0;
var dy = y1 - y0;
var adx = Math.abs(dx);
var ady = Math.abs(dy);
var eps = 0;
var sx = dx > 0 ? 1 : -1;
var sy = dy > 0 ? 1 : -1;
if (adx > ady) {
for (var x = x0, y = y0; sx < 0 ? x >= x1 : x <= x1; x += sx) {
points.push([x, y]);
eps += ady;
if (eps << 1 >= adx) {
y += sy;
eps -= adx;
}
}
} else {
for (var x = x0, y = y0; sy < 0 ? y >= y1 : y <= y1; y += sy) {
points.push([x, y]);
eps += adx;
if (eps << 1 >= ady) {
x += sx;
eps -= ady;
}
}
}
return points;
}
/**
* create a unique array
* from https://stackoverflow.com/a/9229821/1955997
* @private
* @param {Array} a
*/
}, {
key: 'hashUnique',
value: function hashUnique(a) {
var seen = {};
return a.filter(function (item) {
var key = item[0] + '.' + item[1];
return seen.hasOwnProperty(key) ? false : seen[key] = true;
});
}
/**
* draw a set of points, removing duplicates first
* @private
* @param {object[]}
*/
}, {
key: 'drawPoints',
value: function drawPoints(points, tint, alpha) {
points = this.hashUnique(points);
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = points[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var point = _step2.value;
this.point(point[0], point[1], tint, alpha);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
/**
* draw a pixelated line from the cursor position to this position
* @param {number} x
* @param {number} y
* @returns {Pixelate}
*/
}, {
key: 'lineTo',
value: function lineTo(x, y) {
this.drawPoints(this.linePoints(this.cursor.x, this.cursor.y, x, y));
this.cursor.x = x;
this.cursor.y = y;
return this;
}
/**
* draw a pixelated circle
* from https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
* @param {number} x0
* @param {number} y0
* @param {number} radius
* @param {number} [tint]
* @param {number} [alpha]
* @returns {Pixelate}
*/
}, {
key: 'circle',
value: function circle(x0, y0, radius, tint, alpha) {
var points = [];
var x = radius;
var y = 0;
var decisionOver2 = 1 - x; // Decision criterion divided by 2 evaluated at x=r, y=0
while (x >= y) {
points.push([x + x0, y + y0]);
points.push([y + x0, x + y0]);
points.push([-x + x0, y + y0]);
points.push([-y + x0, x + y0]);
points.push([-x + x0, -y + y0]);
points.push([-y + x0, -x + y0]);
points.push([x + x0, -y + y0]);
points.push([y + x0, -x + y0]);
y++;
if (decisionOver2 <= 0) {
decisionOver2 += 2 * y + 1; // Change in decision criterion for y -> y+1
} else {
x--;
decisionOver2 += 2 * (y - x) + 1; // Change for y -> y+1, x -> x-1
}
}
this.drawPoints(points, tint, alpha);
return this;
}
/**
* draw and fill circle
* @param {number} x center
* @param {number} y center
* @param {number} radius
* @param {number} tint
* @param {number} alpha
*/
}, {
key: 'circleFill',
value: function circleFill(x0, y0, radius, tint, alpha) {
var points = [];
var x = radius;
var y = 0;
var decisionOver2 = 1 - x; // Decision criterion divided by 2 evaluated at x=r, y=0
while (x >= y) {
this.rectPoints(-x + x0, y + y0, x * 2 + 1, 1, points);
this.rectPoints(-y + x0, x + y0, y * 2 + 1, 1, points);
this.rectPoints(-x + x0, -y + y0, x * 2 + 1, 1, points);
this.rectPoints(-y + x0, -x + y0, y * 2 + 1, 1, points);
y++;
if (decisionOver2 <= 0) {
decisionOver2 += 2 * y + 1; // Change in decision criterion for y -> y+1
} else {
x--;
decisionOver2 += 2 * (y - x) + 1; // Change for y -> y+1, x -> x-1
}
}
this.drawPoints(points, tint, alpha);
return this;
}
/**
* return an array of points for a rect
* @private
* @param {number} x0
* @param {number} y0
* @param {number} width
* @param {number} height
* @param {number[]} [points]
* @returns {object[]}
*/
}, {
key: 'rectPoints',
value: function rectPoints(x0, y0, width, height, points) {
points = points || [];
for (var y = y0; y < y0 + height; y++) {
for (var x = x0; x < x0 + width; x++) {
points.push([x, y]);
}
}
return points;
}
/**
* draw the outline of a rect
* @param {number} x
* @param {number} y
* @param {number} width
* @param {number} height
* @param {number} tint
* @param {number} alpha
* @return {Pixelate}
*/
}, {
key: 'rect',
value: function rect(x, y, width, height, tint, alpha) {
if (width === 1) {
var point = this.getPoint(tint, alpha);
point.position.set(x, y);
point.width = 1;
point.height = height;
} else if (height === 1) {
var _point = this.getPoint(tint, alpha);
_point.position.set(x, y);
_point.width = 1;
_point.height = 1;
} else {
var top = this.getPoint(tint, alpha);
top.position.set(x, y);
top.width = width + 1;
top.height = 1;
var bottom = this.getPoint(tint, alpha);
bottom.position.set(x, y + height);
bottom.width = width + 1;
bottom.height = 1;
var left = this.getPoint(tint, alpha);
left.position.set(x, y + 1);
left.width = 1;
left.height = height - 1;
var right = this.getPoint(tint, alpha);
right.position.set(x + width, y + 1);
right.width = 1;
right.height = height - 1;
}
return this;
}
/**
* draw and fill rectangle
* @param {number} x
* @param {number} y
* @param {number} width
* @param {number} height
* @param {number} [tint]
* @param {number} [alpha]
* @returns {Pixelate}
*/
}, {
key: 'rectFill',
value: function rectFill(x, y, width, height, tint, alpha) {
var point = this.getPoint(tint, alpha);
point.position.set(x, y);
point.width = width + 1;
point.height = height + 1;
return this;
}
/**
* draw a pixelated ellipse
* from http://cfetch.blogspot.tw/2014/01/wap-to-draw-ellipse-using-midpoint.html
* @param {number} xc center
* @param {number} yc center
* @param {number} rx - radius x-axis
* @param {number} ry - radius y-axis
* @param {number} tint
* @param {number} alpha
* @returns {Pixelate}
*/
}, {
key: 'ellipse',
value: function ellipse(xc, yc, rx, ry, tint, alpha) {
var points = [];
var x = 0,
y = ry;
var p = ry * ry - rx * rx * ry + rx * rx / 4;
while (2 * x * ry * ry < 2 * y * rx * rx) {
points.push([xc + x, yc - y]);
points.push([xc - x, yc + y]);
points.push([xc + x, yc + y]);
points.push([xc - x, yc - y]);
if (p < 0) {
x = x + 1;
p = p + 2 * ry * ry * x + ry * ry;
} else {
x = x + 1;
y = y - 1;
p = p + (2 * ry * ry * x + ry * ry) - 2 * rx * rx * y;
}
}
p = (x + 0.5) * (x + 0.5) * ry * ry + (y - 1) * (y - 1) * rx * rx - rx * rx * ry * ry;
while (y >= 0) {
points.push([xc + x, yc - y]);
points.push([xc - x, yc + y]);
points.push([xc + x, yc + y]);
points.push([xc - x, yc - y]);
if (p > 0) {
y = y - 1;
p = p - 2 * rx * rx * y + rx * rx;
} else {
y = y - 1;
x = x + 1;
p = p + 2 * ry * ry * x - 2 * rx * rx * y - rx * rx;
}
}
this.drawPoints(points, tint, alpha);
return this;
}
/**
* draw and fill ellipse
* @param {number} xc - x-center
* @param {number} yc - y-center
* @param {number} rx - radius x-axis
* @param {number} ry - radius y-axis
* @param {number} tint
* @returns {Pixelate}
*/
}, {
key: 'ellipseFill',
value: function ellipseFill(xc, yc, rx, ry, tint, alpha) {
var points = [];
var x = 0,
y = ry;
var p = ry * ry - rx * rx * ry + rx * rx / 4;
while (2 * x * ry * ry < 2 * y * rx * rx) {
this.rectPoints(xc - x, yc - y, x * 2 + 1, 1, points);
this.rectPoints(xc - x, yc + y, x * 2 + 1, 1, points);
if (p < 0) {
x = x + 1;
p = p + 2 * ry * ry * x + ry * ry;
} else {
x = x + 1;
y = y - 1;
p = p + (2 * ry * ry * x + ry * ry) - 2 * rx * rx * y;
}
}
p = (x + 0.5) * (x + 0.5) * ry * ry + (y - 1) * (y - 1) * rx * rx - rx * rx * ry * ry;
while (y >= 0) {
this.rectPoints(xc - x, yc - y, x * 2 + 1, 1, points);
this.rectPoints(xc - x, yc + y, x * 2 + 1, 1, points);
if (p > 0) {
y = y - 1;
p = p - 2 * rx * rx * y + rx * rx;
} else {
y = y - 1;
x = x + 1;
p = p + 2 * ry * ry * x - 2 * rx * rx * y - rx * rx;
}
}
this.drawPoints(points, tint, alpha);
return this;
}
/**
* draw a pixelated polygon
* @param {number[]} vertices
* @param {number} tint
* @param {number} alpha
* @returns {Pixelate}
*/
}, {
key: 'polygon',
value: function polygon(vertices, tint, alpha) {
var points = [];
for (var i = 2; i < vertices.length; i += 2) {
this.linePoints(vertices[i - 2], vertices[i - 1], vertices[i], vertices[i + 1], points);
}
if (vertices[vertices.length - 2] !== vertices[0] || vertices[vertices.length - 1] !== vertices[1]) {
this.linePoints(vertices[vertices.length - 2], vertices[vertices.length - 1], vertices[0], vertices[1], points);
}
this.drawPoints(points, tint, alpha);
}
/**
* draw and fill pixelated polygon
* @param {number[]} vertices
* @param {number} tint
* @param {number} alpha
* @returns {Pixelate}
*/
}, {
key: 'polygonFill',
value: function polygonFill(vertices, tint, alpha) {
function mod(n, m) {
return (n % m + m) % m;
}
var points = [];
var edges = [],
active = [];
var minY = Infinity,
maxY = 0;
for (var i = 0; i < vertices.length; i += 2) {
var p1 = { x: vertices[i], y: vertices[i + 1] };
var p2 = { x: vertices[mod(i + 2, vertices.length)], y: vertices[mod(i + 3, vertices.length)] };
if (p1.y - p2.y !== 0) {
var edge = {};
edge.p1 = p1;
edge.p2 = p2;
if (p1.y < p2.y) {
edge.minY = p1.y;
edge.minX = p1.x;
} else {
edge.minY = p2.y;
edge.minX = p2.x;
}
minY = edge.minY < minY ? edge.minY : minY;
edge.maxY = Math.max(p1.y, p2.y);
maxY = edge.maxY > maxY ? edge.maxY : maxY;
if (p1.x - p2.x === 0) {
edge.slope = Infinity;
edge.b = p1.x;
} else {
edge.slope = (p1.y - p2.y) / (p1.x - p2.x);
edge.b = p1.y - edge.slope * p1.x;
}
edges.push(edge);
}
}
edges.sort(function (a, b) {
return a.minY - b.minY;
});
for (var y = minY; y <= maxY; y++) {
for (var _i = 0; _i < edges.length; _i++) {
var _edge = edges[_i];
if (_edge.minY === y) {
active.push(_edge);
edges.splice(_i, 1);
_i--;
}
}
for (var _i2 = 0; _i2 < active.length; _i2++) {
var _edge2 = active[_i2];
if (_edge2.maxY < y) {
active.splice(_i2, 1);
_i2--;
} else {
if (_edge2.slope !== Infinity) {
_edge2.x = Math.round((y - _edge2.b) / _edge2.slope);
} else {
_edge2.x = _edge2.b;
}
}
}
if (active.length) {
active.sort(function (a, b) {
return a.x - b.x === 0 ? b.maxY - a.maxY : a.x - b.x;
});
var bit = true,
current = 1;
for (var x = active[0].x; x <= active[active.length - 1].x; x++) {
if (bit) {
points.push([x, y]);
}
if (active[current].x === x) {
if (active[current].maxY !== y) {
bit = !bit;
}
current++;
}
}
} else {
return this;
}
}
this.drawPoints(points, tint, alpha);
return this;
}
/**
* draw arc
* @param {number} x0 - x-start
* @param {number} y0 - y-start
* @param {number} radius - radius
* @param {number} start angle (radians)
* @param {number} end angle (radians)
* @param {number} tint
* @param {number} alpha
* @returns {Pixelate}
*/
}, {
key: 'arc',
value: function arc(x0, y0, radius, start, end, tint, alpha) {
var interval = Math.PI / radius / 4;
var points = [];
for (var i = start; i <= end; i += interval) {
points.push([Math.floor(x0 + Math.cos(i) * radius), Math.floor(y0 + Math.sin(i) * radius)]);
}
this.drawPoints(points, tint, alpha);
return this;
}
/**
* empties cache of old sprites
*/
}, {
key: 'flush',
value: function flush() {
this.cache = [];
}
}], [{
key: 'texture',
get: function get() {
return Pixelate._texture;
},
set: function set(value) {
Pixelate._texture = value;
}
}]);
return Pixelate;
}(PIXI.Container);
Pixelate._texture = PIXI.Texture.WHITE;
module.exports = Pixelate;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9waXhlbGF0ZS5qcyJdLCJuYW1lcyI6WyJQSVhJIiwicmVxdWlyZSIsIkFuZ2xlIiwiUGl4ZWxhdGUiLCJjdXJzb3IiLCJ4IiwieSIsInRpbnQiLCJfbGluZVN0eWxlIiwid2lkdGgiLCJhbHBoYSIsImRpcmVjdGlvbiIsImNhY2hlIiwiY2hpbGRyZW4iLCJsZW5ndGgiLCJwdXNoIiwicG9wIiwicG9pbnQiLCJhZGRDaGlsZCIsIlNwcml0ZSIsInRleHR1cmUiLCJwb2ludHMiLCJpc05hTiIsImkiLCJnZXRQb2ludCIsInBvc2l0aW9uIiwic2V0IiwiaGVpZ2h0IiwieDAiLCJ5MCIsIngxIiwieTEiLCJsaW5lV2lkdGgiLCJsaW5lRGlyZWN0aW9uIiwiZHJhd1BvaW50cyIsImxpbmVQb2ludHMiLCJhbmdsZSIsImFuZ2xlVHdvUG9pbnRzIiwiTWF0aCIsIlBJIiwiY29zIiwic2luIiwiaGFsZiIsInJvdW5kIiwicG9seWdvbkZpbGwiLCJkeCIsImR5IiwiYWR4IiwiYWJzIiwiYWR5IiwiZXBzIiwic3giLCJzeSIsImEiLCJzZWVuIiwiZmlsdGVyIiwiaXRlbSIsImtleSIsImhhc093blByb3BlcnR5IiwiaGFzaFVuaXF1ZSIsInJhZGl1cyIsImRlY2lzaW9uT3ZlcjIiLCJyZWN0UG9pbnRzIiwidG9wIiwiYm90dG9tIiwibGVmdCIsInJpZ2h0IiwieGMiLCJ5YyIsInJ4IiwicnkiLCJwIiwidmVydGljZXMiLCJtb2QiLCJuIiwibSIsImVkZ2VzIiwiYWN0aXZlIiwibWluWSIsIkluZmluaXR5IiwibWF4WSIsInAxIiwicDIiLCJlZGdlIiwibWluWCIsIm1heCIsInNsb3BlIiwiYiIsInNvcnQiLCJzcGxpY2UiLCJiaXQiLCJjdXJyZW50Iiwic3RhcnQiLCJlbmQiLCJpbnRlcnZhbCIsImZsb29yIiwiX3RleHR1cmUiLCJ2YWx1ZSIsIkNvbnRhaW5lciIsIlRleHR1cmUiLCJXSElURSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7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