JSFiddle - React, Tailwind, and code Playground
by Bartosz Zieliński
HTML
<canvas width="2000" height="2000" id="c"></canvas>
JavaScript
// =========================================================================
function GRect(x, y, w, h) {
this._width = w;
this._height = h;
this._x = x;
this._y = y;
}
GRect.prototype._x = 0;
GRect.prototype._y = 0;
GRect.prototype._width = 0;
GRect.prototype._height = 0;
GRect.prototype.getX = function () {
return this._x;
}
GRect.prototype.getY = function () {
return this._y;
}
GRect.prototype.getWidth = function() {
return this._width;
}
GRect.prototype.getHeight = function() {
return this._height;
}
GRect.prototype.scaled = function (s) {
return new GRect(this._x*s, this._y*s, this._width*s, this._height*s);
}
GRect.prototype.toString = function () {
return "new GRect(" + this._x + "," + this._y + "," + this._width + "," + this._height + ")";
}
/**
* A class for merging or subtracting rectangles from it
* It was born here: https://jsfiddle.net/to267224/0uvfjo4p/121/
* @class
* @constructor
*/
function GAABBMerger() {
this._yStrips = [];
this._intervals = [];
}
/**
* @typedef Pair
* @type {[Number, Number]}
*/
/**
* @type {Array<Pair>}
* @private
*/
GAABBMerger.prototype._yStrips = null;
/**
* @type {Array<Array<Pair>>}
* @private
*/
GAABBMerger.prototype._intervals = null;
/**
* Sets whole structure to dirty
*/
GAABBMerger.prototype.reset = function () {
this._yStrips = [];
this._intervals = [];
}
/**
* Subtracts the rectangle from an array of clean rectangles
* @param {GRect} rect
*/
GAABBMerger.prototype.subtract = function (rect) {
if (!this._yStrips.length) {
return;
}
function cpy(arr2d) {
return arr2d.map(function (item) {
return [item[0], item[1]];
});
}
var x1 = rect.getX();
var x2 = rect.getX() + rect.getWidth();
var y1 = rect.getY();
var y2 = rect.getY() + rect.getHeight();
var locationY1 = this._locate(this._yStrips, y1);
// rectangle falls outside, at the end of all rects
if (locationY1.idx ===...