[fabricJS] MSA + FFA

by tinyhustlee

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.min.js"></script>
<p>Drawing: <input type="checkbox" id="drawing" checked></p>
<p>
  Simplification: <input type="number" id="sim" min="0" max="10" step="0.1" value="1.5">
  Smoothing: <input type="checkbox" id="smooth">
</p>
<canvas id="c" width="400" height="300"></canvas>

CSS

canvas {
  border: 1px solid;
}

JavaScript

document.getElementById("drawing").onchange = function () {
	canvas.isDrawingMode = this.checked;	
};

document.getElementById("sim").onchange = function () {
	dp_eps = this.value;
};

document.getElementById("smooth").onchange = function () {
	smoothingEnabled = this.checked;	
};

console.clear();

var canvas = new fabric.Canvas("c", {renderOnAddRemove:false});
var dp_eps = 1.5;
var smoothingEnabled = false;

canvas.freeDrawingBrush.width = 25;
canvas.freeDrawingBrush.color = "red";
canvas.isDrawingMode = true;

canvas.on({
	"mouse:down": function (e) {
  	this.isDrawingMode && this.clear();
  },
  "path:created": function (e) {
  	redraw(e.path);
  }
});

function redraw (path) {
	//create virtual canvas
	var c = document.createElement("canvas");
  var ctx = c.getContext("2d");
  var pathAsImage = new Image();
	
  //on image load
	pathAsImage.onload = function () {
  	//draw image to virtual canvas
    c.width = this.width;
    c.height = this.height;
    ctx.drawImage(this, 0, 0);
    //get pixel data
    var imgData = ctx.getImageData(0, 0, c.width, c.height);
    var pxData = imgData.data;    
    //create binary image (only black (path) and white pixel (holes), no transparency)
    makeBW(ctx, imgData);
    // colors used for floodfill (input path is black, so we add this here)
    var colors = [0];
    var group = new fabric.Group();
    // loop over all pixels in the image
    for (var y=0, maxY=c.height-1; y<maxY; y++) {
    	for (var x=0, maxX=c.width-1; x<maxX; x++) {
      	//
        var pos = c.getPixelPosition(x, y);        
        // if pixel has been floodfilled already, move on
        if (colors.indexOf(pxData[pos]) >= 0) continue;
        // default fill = black
        var fill = 0;
        // create new color until it's one that is not already in use
        while (colors.indexOf(fill) >= 0) {
        	fill = Math.floor(Math.random()*256);
        }
        // floodfill with new color
        applyFloodFill(ctx, imgData, x, y,...