Skip to content

Commit

Permalink
fill optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
kicktheken committed Mar 20, 2013
1 parent 040bd44 commit 81f8501
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 34 deletions.
7 changes: 5 additions & 2 deletions client/js/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,15 @@ define(["action","pixel"], function Actions(Action,Pixel) {
fill: function(layer,color,x,y) {
var oldp = layer.buf.pixel(x,y);
var newp = layer.buf.pixel(x,y,color);
if (!newp.diffColor(oldp) || !layer.buf.isValid(newp)) {
if (!newp.diffColor(oldp) || !layer.buf.isValid(newp) || layer.buf.queue) {
return false;
}
var map;
var undo = function() {
layer.buf.fill(oldp,map);
if (layer.buf.queue) {
return false;
}
layer.buf.fillMap(oldp,map);
layer.refresh();
return true;
};
Expand Down
93 changes: 64 additions & 29 deletions client/js/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ define(["pixel","map"],function Canvas(Pixel,Map) {
b[3] = maxy;
}
}
this.dirty = true;
},
setDimensions: function(width,height) {
var canvas = document.createElement('canvas');
Expand All @@ -51,47 +52,81 @@ define(["pixel","map"],function Canvas(Pixel,Map) {
return p.x < this.canvas.width && p.x >= 0 &&
p.y < this.canvas.height && p.y >=0;
},
fill: function(pixel,map) {
if (typeof map === 'undefined') {
map = this.map = new Map();
this.fillColor(new Pixel(this.context,pixel.x,pixel.y),pixel);
var b = map.bounds;
this.updateBounds(b[0],b[1],b[2],b[3]);
delete this.map;
return map;
fill: function(pixel) {
if (!this.dirty) {
this.fillAll(pixel);
return;
}
var map = this.map = new Map();
this.queue = [pixel];
var oldpixel = new Pixel(this.context,pixel.x,pixel.y);
if (this.fillColor(oldpixel)) {
delete this.queue;
} else {
this.fillMap(map,pixel);
var _this = this, interval;
function fill() {
if (_this.fillColor(oldpixel)) {
delete _this.queue;
clearInterval(interval);
} else {
interval = setTimeout(fill,0);
}
}
interval = setTimeout(fill,0);
}
return map;
},
fillColor: function(oldp,newp) {
var queue = [newp], p, np;
while (queue.length > 0) {
p = queue.shift();
fillColor: function(oldp) {
var p, np, i = 0;
while (this.queue.length > 0 && i < 10000) {
p = this.queue.shift();
if (!oldp.diffColor(new Pixel(this.context,p.x,p.y))) {
p.draw(this.context);
this.map.set(p.x,p.y,true);
if (p.x < this.canvas.width-1) {
queue.push(new Pixel(p,p.x+1,p.y));
if (p.x < this.canvas.width-1 && typeof this.map.get(p.x+1,p.y) !== 'boolean') {
this.map.set(p.x+1,p.y,false);
this.queue.push(new Pixel(p,p.x+1,p.y));
}
if (p.y < this.canvas.height-1) {
queue.push(new Pixel(p,p.x,p.y+1));
if (p.y < this.canvas.height-1 && typeof this.map.get(p.x,p.y+1) !== 'boolean') {
this.map.set(p.x,p.y+1,false);
this.queue.push(new Pixel(p,p.x,p.y+1));
}
if (p.x > 0) {
queue.push(new Pixel(p,p.x-1,p.y));
if (p.x > 0 && typeof this.map.get(p.x-1,p.y) !== 'boolean') {
this.map.set(p.x-1,p.y,false);
this.queue.push(new Pixel(p,p.x-1,p.y));
}
if (p.y > 0) {
queue.push(new Pixel(p,p.x,p.y-1));
if (p.y > 0 && typeof this.map.get(p.x,p.y-1) !== 'boolean') {
this.map.set(p.x,p.y-1,false);
this.queue.push(new Pixel(p,p.x,p.y-1));
}
this.updateBounds(p.x,p.y,p.x,p.y);
}
i++;
}
return (this.queue.length === 0);
},
fillMap: function(m,pixel) {
fillMap: function(pixel,m) {
if (!m) {
this.fillAll(pixel);
return;
}
for (var y in m.map) {
for (var x in m.map[y]) {
this.context.putImageData(pixel.d,x,y);
if (m.map[y][x]) {
this.context.putImageData(pixel.d,x,y);
}
}
}
},
fillAll: function(pixel) {
if (pixel.d.data[3] === 0) {
this.clear();
} else {
this.context.fillStyle = pixel.toColorString();
this.context.fillRect(0,0,this.canvas.width,this.canvas.height);
this.updateBounds(0,0,this.canvas.width,this.canvas.height);
}
},
pixel: function(x,y,color) {
x += Math.ceil(this.canvas.width/2);
y += Math.ceil(this.canvas.height/2);
Expand Down Expand Up @@ -141,9 +176,6 @@ define(["pixel","map"],function Canvas(Pixel,Map) {
this.context.restore();
this.updateBounds(0,y,this.canvas.width,y+height);
},
loadData: function(data,x,y) {
this.context.putImageData(data,x,y);
},
viewable: function(width,height) {
var x = Math.ceil(width/2) - Math.ceil(this.canvas.width/2);
var y = Math.ceil(height/2) - Math.ceil(this.canvas.height/2);
Expand All @@ -169,21 +201,23 @@ define(["pixel","map"],function Canvas(Pixel,Map) {
clear: function() {
if (arguments.length === 4) {
var a = arguments;
if (a[0] === 0 && a[1] === 0 && a[2] === this.canvas.width && a[3] === this.canvas.height) {
this.dirty = false;
}
this.context.clearRect(a[0],a[1],a[2],a[3]);
} else {
this.dirty = false;
this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
}
},
reset: function() {
this.clear();
},
setCanvas: function(obj) {
this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
if (!obj.w || !obj.h) {
return;
}
this.bounds = [obj.x, obj.y, obj.x+obj.w, obj.y+obj.h];
this.context.drawImage(obj.img,obj.x,obj.y);
this.dirty = true;
},
toDataObject: function(local) {
var ret = {};
Expand Down Expand Up @@ -237,6 +271,7 @@ define(["pixel","map"],function Canvas(Pixel,Map) {
},
putData: function(data) {
this.context.putImageData(data,0,0);
this.dirty = true;
},
getData: function(width,height) {
return this.context.getImageData(0,0,this.canvas.width,this.canvas.height);
Expand Down
4 changes: 2 additions & 2 deletions client/js/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ define(["actions","layer","canvas"],function Engine(Actions, Layer, Canvas) {
context.textBaseline="top";
context.fillStyle = 'black';
context.shadowColor = 'white';
context.shadowBlur = 3;
context.shadowBlur = 10;
var hx = Math.ceil((cx - (v.x*size+dx))/size)+1;
var hy = Math.ceil((cy - (v.y*size+dy))/size)+1;
context.fillText(hx+","+hy,canvas.width-10,10);
Expand Down Expand Up @@ -644,7 +644,7 @@ define(["actions","layer","canvas"],function Engine(Actions, Layer, Canvas) {
}
var w = workspace.layers;
for (var i in w) {
if (typeof w[i] !== 'object' || !isInt(w[i].ox) || !isInt(w[i].oy)) {
if (typeof w[i] !== 'object') {
_this.deleteLocalWorkspace();
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion client/js/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ define(["canvas"], function Layer(Canvas) {
this.refresh();
},
resetWorkspace: function() {
this.buf.reset();
this.buf.clear();
this.refresh();
},
load: function(method,image) {
Expand Down

0 comments on commit 81f8501

Please sign in to comment.