|
|
- /* 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;
- });
|