UNPKG

obelisk-browserify

Version:

Browserify-compatible fork of obelisk.js, hopefully temporary

233 lines (197 loc) 6.89 kB
/*global obelisk:true*/ /* * BitmapData */ (function (obelisk) { "use strict"; var BitmapData, p; BitmapData = function (w, h, useDefaultCanvas) { this.initialize(w, h, useDefaultCanvas); }; p = BitmapData.prototype; // public property p.imageData = null; p.canvas = null; p.context = null; // constructor p.initialize = function (w, h, useDefaultCanvas) { if (w === undefined || h === undefined) { throw new Error("BitmapData width or height is missing"); } if (useDefaultCanvas) { this.canvas = obelisk.CanvasManager.getDefaultCanvas(); } else { this.canvas = obelisk.CanvasManager.getNewCanvas(); } this.canvas.setAttribute('width', w); this.canvas.setAttribute('height', h); this.context = this.canvas.getContext('2d'); this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); this.imageData = this.context.createImageData(w, h); return this; }; p.setPixel = function (posX, posY, color) { var index = (posY * this.imageData.width + posX) * 4; this.setPixelByIndex(index, color); }; p.setPixelByIndex = function (index, color) { var pixels = this.imageData.data; pixels[index] = (color >>> 16) & 0xFF; pixels[index + 1] = (color >>> 8) & 0xFF; pixels[index + 2] = (color >>> 0) & 0xFF; pixels[index + 3] = (color >>> 24) & 0xFF; }; p.checkPixelAvailable = function (x, y) { var index = (y * this.imageData.width + x) * 4; return this.imageData.data[index + 3] === 0; }; p.floodFill = function (posX, posY, color) { if (((color >>> 24) & 0xFF) === 0x00) { // transparent flood fill return; } var x = posX, y = posY, stack = [], nowCol = [], prevCol = [], col, row, matchFlag, w = this.imageData.width, h = this.imageData.height, i, j; // bound reach if (x < 0 || y < 0 || x >= w || y >= h) { return; } // first point check fail if (!this.checkPixelAvailable(x, y)) { throw new Error("Start point for flood fill is already filled"); } // left side flood fill for (col = x; col >= 0; col -= 1) { // top side for (row = y; row >= 0; row -= 1) { if (this.checkPixelAvailable(col, row)) { // available pixel stack.push((row * w + col) * 4); nowCol.push(row); } else { // unavailable pixel if (!(row === y && this.checkPixelAvailable(col + 1, row - 1))) { break; } // let's continue to check more data in this column } } // top side for (row = y; row < h; row += 1) { if (this.checkPixelAvailable(col, row)) { // available pixel stack.push((row * w + col) * 4); nowCol.push(row); } else { // unavailable pixel if (!(row === y && this.checkPixelAvailable(col + 1, row + 1))) { break; } // let's continue to check more data in this column } } // compare with previous column // for first column // the given point should be inside the container if (col === x) { prevCol = nowCol.concat(); } matchFlag = false; for (i = 0; i < prevCol.length; i += 1) { for (j = 0; j < prevCol.length; j += 1) { if (nowCol[j] === prevCol[i]) { matchFlag = true; y = prevCol[i]; break; } } if (matchFlag) { break; } } if (matchFlag) { prevCol = nowCol.concat(); nowCol = []; } else { // bound reach break; } } // reset start point x = posX; y = posY; prevCol = []; nowCol = []; // right side flood fill for (col = x; col < w; col += 1) { // top side for (row = y; row >= 0; row -= 1) { if (this.checkPixelAvailable(col, row)) { // available pixel stack.push((row * w + col) * 4); nowCol.push(row); } else { // unavailable pixel if (!(row === y && this.checkPixelAvailable(col - 1, row - 1))) { break; } // let's continue to check more data in this column } } // top side for (row = y; row < h; row += 1) { if (this.checkPixelAvailable(col, row)) { // available pixel stack.push((row * w + col) * 4); nowCol.push(row); } else { // unavailable pixel if (!(row === y && this.checkPixelAvailable(col - 1, row + 1))) { break; } // let's continue to check more data in this column } } // compare with previous column // for first column // the given point should be inside the container if (col === x) { prevCol = nowCol.concat(); } matchFlag = false; for (i = 0; i < prevCol.length; i += 1) { for (j = 0; j < prevCol.length; j += 1) { if (nowCol[j] === prevCol[i]) { matchFlag = true; y = prevCol[i]; break; } } if (matchFlag) { break; } } if (matchFlag) { prevCol = nowCol.concat(); nowCol = []; } else { // bound reach break; } } // fill image data for (i = 0; i < stack.length; i += 1) { this.setPixelByIndex(stack[i], color); } }; p.toString = function () { return "[BitmapData]"; }; obelisk.BitmapData = BitmapData; }(obelisk));