add drawing methods to Ox.Image, allow for asynchronous image manipulation
This commit is contained in:
parent
b4dc9e15ba
commit
37f3bf8f51
1 changed files with 92 additions and 32 deletions
|
@ -180,6 +180,16 @@ Ox.load.Image = function(options, callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
drawCircle <f> Draws a circle
|
||||||
|
(point, radius, options) -> <o> The image object
|
||||||
|
point <[n]> Center (<code>[x, y]</code>)
|
||||||
|
radius <n> Radius in px
|
||||||
|
options <o> Options
|
||||||
|
color <s|'rgb(0, 0, 0)'> CSS color
|
||||||
|
fill <s|'rgba(0, 0, 0, 0)'> CSS color
|
||||||
|
width <n|1> Line width in px
|
||||||
|
@*/
|
||||||
that.drawCircle = function(point, radius, options) {
|
that.drawCircle = function(point, radius, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
that.context.strokeStyle = options.color || 'rgb(0, 0, 0)';
|
that.context.strokeStyle = options.color || 'rgb(0, 0, 0)';
|
||||||
|
@ -192,6 +202,14 @@ Ox.load.Image = function(options, callback) {
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
drawLine <f> Draws a line
|
||||||
|
(points, options) -> <o> The image object
|
||||||
|
points <[a]> End points (<code>[[x1, y1], [x2, y2]]</code>)
|
||||||
|
options <o> Options
|
||||||
|
color <s|'rgb(0, 0, 0)'> CSS color
|
||||||
|
width <n|1> Line width in px
|
||||||
|
@*/
|
||||||
that.drawLine = function(points, options, isPath) {
|
that.drawLine = function(points, options, isPath) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
that.context.strokeStyle = options.color || 'rgb(0, 0, 0)';
|
that.context.strokeStyle = options.color || 'rgb(0, 0, 0)';
|
||||||
|
@ -203,6 +221,15 @@ Ox.load.Image = function(options, callback) {
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
drawPath <f> Draws a path
|
||||||
|
(points, options) -> <o> The image object
|
||||||
|
points <[a]> Points (<code>[[x1, y2], [x2, y2], ...]</code>)
|
||||||
|
options <o> Options
|
||||||
|
color <s|'rgb(0, 0, 0)'> CSS color
|
||||||
|
fill <s|'rgba(0, 0, 0, 0)'> CSS color
|
||||||
|
width <n|1> Line width in px
|
||||||
|
@*/
|
||||||
that.drawPath = function(points, options) {
|
that.drawPath = function(points, options) {
|
||||||
var n = points.length;
|
var n = points.length;
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
@ -217,6 +244,16 @@ Ox.load.Image = function(options, callback) {
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
drawRectangle <f> Draws a rectangle
|
||||||
|
(point, size, options) -> <o> The image object
|
||||||
|
point <[n]> Top left corner (<code>[x, y]</code>)
|
||||||
|
size <[n]> Width and height in px (<code>[w, h]</code>)
|
||||||
|
options <o> Options
|
||||||
|
color <s|'rgb(0, 0, 0)'> CSS color
|
||||||
|
fill <s|'rgba(0, 0, 0, 0)'> CSS color
|
||||||
|
width <n|1> Line width in px
|
||||||
|
@*/
|
||||||
that.drawRectangle = function(point, size, options) {
|
that.drawRectangle = function(point, size, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
that.context.strokeStyle = options.color || 'rgb(0, 0, 0)';
|
that.context.strokeStyle = options.color || 'rgb(0, 0, 0)';
|
||||||
|
@ -227,6 +264,17 @@ Ox.load.Image = function(options, callback) {
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
drawText <f> Draws text
|
||||||
|
(text, point, options) -> <o> The image object
|
||||||
|
text <s> Text
|
||||||
|
point <[n]> Top left corner (<code>[x, y]</code>)
|
||||||
|
options <o> Options
|
||||||
|
color <s|'rgb(0, 0, 0)'> CSS color
|
||||||
|
font <s|'10px sans-serif'> CSS font
|
||||||
|
outline <s|'0px rgba(0, 0, 0, 0)'> CSS border
|
||||||
|
textAlign <n|'start'> CSS text-align
|
||||||
|
@*/
|
||||||
that.drawText = function(text, point, options) {
|
that.drawText = function(text, point, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var match = (
|
var match = (
|
||||||
|
@ -322,10 +370,9 @@ Ox.load.Image = function(options, callback) {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
b = 0;
|
b = 0;
|
||||||
that.forEach(function(rgba, xy) {
|
that.forEach(function(rgba, xy, index) {
|
||||||
// If alpha is not 255, the RGB values may not be preserved
|
// If alpha is not 255, the RGB values may not be preserved
|
||||||
if (rgba[3] == 255) {
|
if (rgba[3] == 255) {
|
||||||
var index = getIndex(xy);
|
|
||||||
Ox.loop(3, function(c) {
|
Ox.loop(3, function(c) {
|
||||||
// fixme: use: var data = that.context.imageData.data[i + c]
|
// fixme: use: var data = that.context.imageData.data[i + c]
|
||||||
var i = index + c;
|
var i = index + c;
|
||||||
|
@ -346,9 +393,10 @@ Ox.load.Image = function(options, callback) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}, function() {
|
||||||
|
that.context.putImageData(self.imageData, 0, 0);
|
||||||
|
callback(that);
|
||||||
});
|
});
|
||||||
that.context.putImageData(self.imageData, 0, 0);
|
|
||||||
callback(that);
|
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -376,9 +424,8 @@ Ox.load.Image = function(options, callback) {
|
||||||
return mode & 1 << b ? b : null;
|
return mode & 1 << b ? b : null;
|
||||||
}),
|
}),
|
||||||
done = 0, len = 4, str = '';
|
done = 0, len = 4, str = '';
|
||||||
that.forEach(function(rgba, xy) {
|
that.forEach(function(rgba, xy, index) {
|
||||||
if (rgba[3] == 255) {
|
if (rgba[3] == 255) {
|
||||||
var index = getIndex(xy);
|
|
||||||
Ox.loop(3, function(c) {
|
Ox.loop(3, function(c) {
|
||||||
var i = index + c;
|
var i = index + c;
|
||||||
Ox.forEach(bits, function(bit) {
|
Ox.forEach(bits, function(bit) {
|
||||||
|
@ -415,16 +462,18 @@ Ox.load.Image = function(options, callback) {
|
||||||
});
|
});
|
||||||
return done != 2;
|
return done != 2;
|
||||||
}
|
}
|
||||||
});
|
}, function() {
|
||||||
try {
|
try {
|
||||||
if (deflate) {
|
if (deflate) {
|
||||||
Ox.decodeDeflate(str, callback);
|
Ox.decodeDeflate(str, callback);
|
||||||
} else {
|
} else {
|
||||||
callback(Ox.decodeUTF8(str));
|
callback(Ox.decodeUTF8(str));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
error('decode');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
});
|
||||||
error('decode');
|
return that;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
|
@ -473,26 +522,40 @@ Ox.load.Image = function(options, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
forEach <f> Pixel-wise forEach function
|
forEach <f> Pixel-wise forEach loop
|
||||||
(fn) -> <o> The image object
|
(fn) -> <o> The image object
|
||||||
|
(fn, callback) -> <o> The image object
|
||||||
fn <f> Iterator function
|
fn <f> Iterator function
|
||||||
rgba <[n]> RGBA values
|
rgba <[n]> RGBA values
|
||||||
xy <[n]> XY coordinates
|
xy <[n]> XY coordinates
|
||||||
|
i <n> Pixel index
|
||||||
|
callback <f> Callback function (if present, forEach is async)
|
||||||
@*/
|
@*/
|
||||||
that.forEach = function(fn) {
|
that.forEach = function(fn, callback) {
|
||||||
Ox.loop(0, self.data.length, 4, function(i) {
|
var data = self.data;
|
||||||
|
Ox._loop(0, data.length, 4, function(i) {
|
||||||
return fn([
|
return fn([
|
||||||
self.data[i], self.data[i + 1],
|
data[i], data[i + 1], data[i + 2], data[i + 3]
|
||||||
self.data[i + 2], self.data[i + 3]
|
], getXY(i), i);
|
||||||
], getXY(i));
|
}, 10000, callback);
|
||||||
})
|
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
getSize <f> Returns width and height
|
||||||
|
() -> <o> Image size
|
||||||
|
width <n> Width in px
|
||||||
|
height <n> Height in px
|
||||||
|
@*/
|
||||||
that.getSize = function() {
|
that.getSize = function() {
|
||||||
return {width: self.width, height: self.height};
|
return {width: self.width, height: self.height};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*@
|
||||||
|
hue <f> Change the hue of the image
|
||||||
|
(val) -> <o> The image object
|
||||||
|
val <n> Hue, in degrees
|
||||||
|
@*/
|
||||||
that.hue = function(val) {
|
that.hue = function(val) {
|
||||||
return that.map(function(rgba) {
|
return that.map(function(rgba) {
|
||||||
var hsl = Ox.hsl([rgba[0], rgba[1], rgba[2]]), rgb;
|
var hsl = Ox.hsl([rgba[0], rgba[1], rgba[2]]), rgb;
|
||||||
|
@ -511,7 +574,6 @@ Ox.load.Image = function(options, callback) {
|
||||||
(imageData) -> <o> Image object with new image data
|
(imageData) -> <o> Image object with new image data
|
||||||
imageData <o> ImageData object
|
imageData <o> ImageData object
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
that.imageData = function() {
|
that.imageData = function() {
|
||||||
if (arguments.length == 0) {
|
if (arguments.length == 0) {
|
||||||
return self.imageData;
|
return self.imageData;
|
||||||
|
@ -545,18 +607,16 @@ Ox.load.Image = function(options, callback) {
|
||||||
fn <f> Iterator function
|
fn <f> Iterator function
|
||||||
rgba <[n]> RGBA values
|
rgba <[n]> RGBA values
|
||||||
xy <[n]> XY coordinates
|
xy <[n]> XY coordinates
|
||||||
|
i <n> Pixel index
|
||||||
@*/
|
@*/
|
||||||
that.map = function(fn) {
|
that.map = function(fn, callback) {
|
||||||
self.imageData = that.context.getImageData(0, 0, self.width, self.height);
|
self.imageData = that.context.getImageData(0, 0, self.width, self.height);
|
||||||
self.data = self.imageData.data;
|
self.data = self.imageData.data;
|
||||||
Ox.loop(0, self.data.length, 4, function(i) {
|
that.forEach(function(rgba, xy, i) {
|
||||||
fn([
|
fn(rgba, xy, i).forEach(function(val, c) {
|
||||||
self.data[i], self.data[i + 1],
|
|
||||||
self.data[i + 2], self.data[i + 3]
|
|
||||||
], getXY(i)).forEach(function(val, c) {
|
|
||||||
self.data[i + c] = val;
|
self.data[i + c] = val;
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
that.context.putImageData(self.imageData, 0, 0);
|
that.context.putImageData(self.imageData, 0, 0);
|
||||||
return that;
|
return that;
|
||||||
};
|
};
|
||||||
|
@ -650,7 +710,7 @@ Ox.load.Image = function(options, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
that.resize = function(width, height) {
|
that.resize = function(width, height) {
|
||||||
// fixme: may not work this way
|
// fixme: doesn't work this way
|
||||||
that.canvas.attr({
|
that.canvas.attr({
|
||||||
width: width,
|
width: width,
|
||||||
height: height
|
height: height
|
||||||
|
|
Loading…
Reference in a new issue