not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

145 lines
5.4 KiB

/* Bucker mode will fill an area with a color */
define([], function() {
function initGui() {
PaintApp.elements.bucketButton = document.getElementById('bucket-button');
PaintApp.paletteModesButtons.push(PaintApp.elements.bucketButton);
PaintApp.elements.bucketButton.addEventListener('click', function() {
PaintApp.paletteRemoveActiveClass();
PaintApp.addActiveClassToElement(PaintApp.elements.bucketButton);
PaintApp.switchMode('Bucket');
});
}
//Floodfill functions
function floodfill(x, y, fillcolor, ctx, width, height, tolerance) {
var img = ctx.getImageData(0, 0, width, height);
var data = img.data;
var length = data.length;
var Q = [];
var i = (x + y * width) * 4;
var e = i,
w = i,
me, mw, w2 = width * 4;
var targetcolor = [
data[i],
data[i + 1],
data[i + 2],
data[i + 3]
];
var targettotal = data[i] + data[i + 1] + data[i + 2] + data[i + 3];
if (!pixelCompare(i, targetcolor, targettotal, fillcolor, data, length, tolerance)) {
return false;
}
Q.push(i);
while (Q.length) {
i = Q.pop();
if (pixelCompareAndSet(i, targetcolor, targettotal, fillcolor, data, length, tolerance)) {
e = i;
w = i;
mw = parseInt(i / w2) * w2;
me = mw + w2;
while (mw < (w -= 4) && pixelCompareAndSet(w, targetcolor, targettotal, fillcolor, data, length, tolerance));
while (me > (e += 4) && pixelCompareAndSet(e, targetcolor, targettotal, fillcolor, data, length, tolerance));
for (var j = w; j < e; j += 4) {
if (j - w2 >= 0 && pixelCompare(j - w2, targetcolor, targettotal, fillcolor, data, length, tolerance))
Q.push(j - w2);
if (j + w2 < length && pixelCompare(j + w2, targetcolor, targettotal, fillcolor, data, length, tolerance))
Q.push(j + w2);
}
}
}
ctx.putImageData(img, 0, 0);
}
//Floodfill functions
function pixelCompare(i, targetcolor, targettotal, fillcolor, data, length, tolerance) {
if (i < 0 || i >= length)
return false;
if (data[i + 3] === 0)
return true;
if (targetcolor[3] === fillcolor.a && targetcolor[0] === fillcolor.r && targetcolor[1] === fillcolor.g && targetcolor[2] === fillcolor.b)
return false;
if (targetcolor[3] === data[i + 3] && targetcolor[0] === data[i] && targetcolor[1] === data[i + 1] && targetcolor[2] === data[i + 2])
return true;
if (Math.abs(targetcolor[3] - data[i + 3]) <= 255 - tolerance && Math.abs(targetcolor[0] - data[i]) <= tolerance && Math.abs(targetcolor[1] - data[i + 1]) <= tolerance && Math.abs(targetcolor[2] - data[i + 2]) <= tolerance)
return true;
return false;
}
//Floodfill functions
function pixelCompareAndSet(i, targetcolor, targettotal, fillcolor, data, length, tolerance) {
if (pixelCompare(i, targetcolor, targettotal, fillcolor, data, length, tolerance)) {
data[i] = fillcolor.r;
data[i + 1] = fillcolor.g;
data[i + 2] = fillcolor.b;
data[i + 3] = 255;
return true;
}
return false;
}
var Bucket = {
initGui: initGui,
lock: false,
onMouseDown: function(event) {
if (PaintApp.modes.Bucket.lock) {
return;
}
var ctx = PaintApp.elements.canvas.getContext('2d');
/* Transformation of the color used inside the palette to match with the bucket fill functions prototypes */
var colorFillStrings = PaintApp.data.color.fill.slice(4, -1).split(',');
var colorFill = [
parseInt(colorFillStrings[0]),
parseInt(colorFillStrings[1]),
parseInt(colorFillStrings[2]),
0
];
var colorHex = colorFill.map(function(x) {
x = parseInt(x).toString(16);
return x.length == 1 ? '0' + x : x;
});
var fillColor = {
a: 1,
r: parseInt(colorFill[0]),
g: parseInt(colorFill[1]),
b: parseInt(colorFill[2])
};
/* Getting the clicked point */
var p = ctx.getImageData(event.point.x * window.devicePixelRatio, event.point.y * window.devicePixelRatio, 1, 1).data;
/* If the color of the point is too close to the required color we stop the process */
/* We can't do a strict equality because browsers will auto change a few colors and we cannot prevent it... */
if (Math.abs(p[0] - fillColor.r) <= 10 && Math.abs(p[1] - fillColor.g) <= 10 && Math.abs(p[2] - fillColor.b) <= 10) {
PaintApp.modes.Bucket.lock = false;
return;
}
/* Proceed with the bucket fill */
floodfill(parseInt(event.point.x * window.devicePixelRatio), parseInt(event.point.y * window.devicePixelRatio), fillColor, ctx, ctx.canvas.width, ctx.canvas.height, 5);
PaintApp.saveCanvas();
PaintApp.modes.Bucket.lock = false;
/* If inside a shared activity, send the new image to everyone */
if (PaintApp.data.isShared) {
try {
PaintApp.collaboration.sendMessage({
action: 'toDataURL',
data: {
width: PaintApp.elements.canvas.width / window.devicePixelRatio,
height: PaintApp.elements.canvas.height / window.devicePixelRatio,
src: PaintApp.collaboration.compress(PaintApp.elements.canvas.toDataURL())
}
})
} catch (e) {}
}
},
onMouseDrag: function(event) {},
onMouseUp: function(event) {}
};
return Bucket;
});