mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Issue #146 : Move line creation utils to PixelUtils
This commit is contained in:
parent
20b7eb2a3c
commit
00f0debf12
@ -82,103 +82,4 @@
|
||||
|
||||
ns.BaseTool.prototype.releaseToolAt = function (col, row, frame, overlay, event) {};
|
||||
|
||||
/**
|
||||
* Bresenham line algorithm: Get an array of pixels from
|
||||
* start and end coordinates.
|
||||
*
|
||||
* http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
|
||||
* http://stackoverflow.com/questions/4672279/bresenham-algorithm-in-javascript
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ns.BaseTool.prototype.getLinePixels_ = function (x0, x1, y0, y1) {
|
||||
x1 = pskl.utils.normalize(x1, 0);
|
||||
y1 = pskl.utils.normalize(y1, 0);
|
||||
|
||||
var pixels = [];
|
||||
var dx = Math.abs(x1 - x0);
|
||||
var dy = Math.abs(y1 - y0);
|
||||
|
||||
var sx = (x0 < x1) ? 1 : -1;
|
||||
var sy = (y0 < y1) ? 1 : -1;
|
||||
var err = dx - dy;
|
||||
while (true) {
|
||||
// Do what you need to for this
|
||||
pixels.push({'col': x0, 'row': y0});
|
||||
|
||||
if ((x0 == x1) && (y0 == y1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
var e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if (e2 < dx) {
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
|
||||
return pixels;
|
||||
};
|
||||
|
||||
var dist = function (x0, x1, y0, y1) {
|
||||
var dx = Math.abs(x1 - x0);
|
||||
var dy = Math.abs(y1 - y0);
|
||||
return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
||||
};
|
||||
|
||||
var MAX_STEP = 5;
|
||||
ns.BaseTool.prototype.getUniformLinePixels_ = function (x0, x1, y0, y1) {
|
||||
var pixels = [];
|
||||
|
||||
x1 = pskl.utils.normalize(x1, 0);
|
||||
y1 = pskl.utils.normalize(y1, 0);
|
||||
|
||||
var dx = Math.abs(x1 - x0);
|
||||
var dy = Math.abs(y1 - y0);
|
||||
|
||||
var ratio = Math.max(dx, dy) / Math.min(dx, dy);
|
||||
// in pixel art, lines should use uniform number of pixels for each step
|
||||
var pixelStep = Math.round(ratio);
|
||||
// invalid step, bail out
|
||||
if (pixelStep === 0 || isNaN(pixelStep)) {
|
||||
return pixels;
|
||||
}
|
||||
// the tool should make it easy to draw straight lines
|
||||
if (pixelStep > MAX_STEP && pixelStep < MAX_STEP * 2) {
|
||||
pixelStep = MAX_STEP;
|
||||
} else if (pixelStep >= MAX_STEP * 2) {
|
||||
pixelStep = Infinity;
|
||||
}
|
||||
|
||||
var sx = (x0 < x1) ? 1 : -1;
|
||||
var sy = (y0 < y1) ? 1 : -1;
|
||||
|
||||
var x = x0;
|
||||
var y = y0;
|
||||
var maxDistance = dist(x0, x1, y0, y1);
|
||||
|
||||
var i = 0;
|
||||
while (true) {
|
||||
i++;
|
||||
|
||||
pixels.push({'col': x, 'row': y});
|
||||
if (dist(x0, x, y0, y) >= maxDistance) {
|
||||
break;
|
||||
}
|
||||
|
||||
var isAtStep = i % pixelStep === 0;
|
||||
if (dx >= dy || isAtStep) {
|
||||
x += sx;
|
||||
}
|
||||
if (dy >= dx || isAtStep) {
|
||||
y += sy;
|
||||
}
|
||||
}
|
||||
|
||||
return pixels;
|
||||
};
|
||||
})();
|
||||
|
@ -63,7 +63,7 @@
|
||||
// The pen movement is too fast for the mousemove frequency, there is a gap between the
|
||||
// current point and the previously drawn one.
|
||||
// We fill the gap by calculating missing dots (simple linear interpolation) and draw them.
|
||||
var interpolatedPixels = this.getLinePixels_(col, this.previousCol, row, this.previousRow);
|
||||
var interpolatedPixels = pskl.PixelUtils.getLinePixels(col, this.previousCol, row, this.previousRow);
|
||||
for (var i = 0, l = interpolatedPixels.length ; i < l ; i++) {
|
||||
var coords = interpolatedPixels[i];
|
||||
this.applyToolAt(coords.col, coords.row, frame, overlay, event);
|
||||
|
@ -92,9 +92,9 @@
|
||||
ns.Stroke.prototype.draw_ = function (col, row, color, targetFrame, penSize, isStraight) {
|
||||
var linePixels;
|
||||
if (isStraight) {
|
||||
linePixels = this.getUniformLinePixels_(this.startCol, col, this.startRow, row);
|
||||
linePixels = pskl.PixelUtils.getUniformLinePixels(this.startCol, col, this.startRow, row);
|
||||
} else {
|
||||
linePixels = this.getLinePixels_(col, this.startCol, row, this.startRow);
|
||||
linePixels = pskl.PixelUtils.getLinePixels(col, this.startCol, row, this.startRow);
|
||||
}
|
||||
|
||||
pskl.PixelUtils.resizePixels(linePixels, penSize).forEach(function (point) {
|
||||
|
@ -55,7 +55,7 @@
|
||||
* @private
|
||||
*/
|
||||
ns.LassoSelect.prototype.getLassoPixels_ = function () {
|
||||
var line = this.getLinePixels_(this.previousCol, this.startCol, this.previousRow, this.startRow);
|
||||
var line = pskl.PixelUtils.getLinePixels(this.previousCol, this.startCol, this.previousRow, this.startRow);
|
||||
return this.pixels.concat(line);
|
||||
};
|
||||
|
||||
@ -69,7 +69,7 @@
|
||||
row = pskl.utils.Math.minmax(row, 0, frame.getHeight() - 1);
|
||||
|
||||
// line interpolation needed in case mousemove was too fast
|
||||
var interpolatedPixels = this.getLinePixels_(col, this.previousCol, row, this.previousRow);
|
||||
var interpolatedPixels = pskl.PixelUtils.getLinePixels(col, this.previousCol, row, this.previousRow);
|
||||
this.pixels = this.pixels.concat(interpolatedPixels);
|
||||
|
||||
// update state
|
||||
|
@ -4,6 +4,12 @@
|
||||
ns.Math = {
|
||||
minmax : function (val, min, max) {
|
||||
return Math.max(Math.min(val, max), min);
|
||||
},
|
||||
|
||||
distance : function (x0, x1, y0, y1) {
|
||||
var dx = Math.abs(x1 - x0);
|
||||
var dy = Math.abs(y1 - y0);
|
||||
return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
@ -1,6 +1,11 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl');
|
||||
|
||||
/**
|
||||
* Maximum step for uniform lines
|
||||
*/
|
||||
var MAX_LINE_STEP = 5;
|
||||
|
||||
ns.PixelUtils = {
|
||||
|
||||
getRectanglePixels : function (x0, y0, x1, y1) {
|
||||
@ -234,6 +239,104 @@
|
||||
*/
|
||||
calculateZoomForContainer : function (container, pictureHeight, pictureWidth) {
|
||||
return this.calculateZoom(container.height(), container.width(), pictureHeight, pictureWidth);
|
||||
},
|
||||
|
||||
/**
|
||||
* Bresenham line algorithm: Get an array of pixels from
|
||||
* start and end coordinates.
|
||||
*
|
||||
* http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
|
||||
* http://stackoverflow.com/questions/4672279/bresenham-algorithm-in-javascript
|
||||
*/
|
||||
getLinePixels : function (x0, x1, y0, y1) {
|
||||
var pixels = [];
|
||||
|
||||
x1 = pskl.utils.normalize(x1, 0);
|
||||
y1 = pskl.utils.normalize(y1, 0);
|
||||
|
||||
var dx = Math.abs(x1 - x0);
|
||||
var dy = Math.abs(y1 - y0);
|
||||
|
||||
var sx = (x0 < x1) ? 1 : -1;
|
||||
var sy = (y0 < y1) ? 1 : -1;
|
||||
|
||||
var err = dx - dy;
|
||||
while (true) {
|
||||
// Do what you need to for this
|
||||
pixels.push({'col': x0, 'row': y0});
|
||||
|
||||
if ((x0 == x1) && (y0 == y1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
var e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if (e2 < dx) {
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
|
||||
return pixels;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a uniform line using the same number of pixel at each step, between the provided
|
||||
* origin and target coordinates.
|
||||
*/
|
||||
getUniformLinePixels : function (x0, x1, y0, y1) {
|
||||
var pixels = [];
|
||||
|
||||
x1 = pskl.utils.normalize(x1, 0);
|
||||
y1 = pskl.utils.normalize(y1, 0);
|
||||
|
||||
var dx = Math.abs(x1 - x0);
|
||||
var dy = Math.abs(y1 - y0);
|
||||
|
||||
var sx = (x0 < x1) ? 1 : -1;
|
||||
var sy = (y0 < y1) ? 1 : -1;
|
||||
|
||||
var ratio = Math.max(dx, dy) / Math.min(dx, dy);
|
||||
// in pixel art, lines should use uniform number of pixels for each step
|
||||
var pixelStep = Math.round(ratio);
|
||||
// invalid step, bail out
|
||||
if (pixelStep === 0 || isNaN(pixelStep)) {
|
||||
return pixels;
|
||||
}
|
||||
|
||||
if (pixelStep > MAX_LINE_STEP && pixelStep < MAX_LINE_STEP * 2) {
|
||||
pixelStep = MAX_LINE_STEP;
|
||||
} else if (pixelStep >= MAX_LINE_STEP * 2) {
|
||||
// straight line
|
||||
pixelStep = Infinity;
|
||||
}
|
||||
|
||||
var maxDistance = pskl.utils.Math.distance(x0, x1, y0, y1);
|
||||
|
||||
var x = x0;
|
||||
var y = y0;
|
||||
var i = 0;
|
||||
while (true) {
|
||||
i++;
|
||||
|
||||
pixels.push({'col': x, 'row': y});
|
||||
if (pskl.utils.Math.distance(x0, x, y0, y) >= maxDistance) {
|
||||
break;
|
||||
}
|
||||
|
||||
var isAtStep = i % pixelStep === 0;
|
||||
if (dx >= dy || isAtStep) {
|
||||
x += sx;
|
||||
}
|
||||
if (dy >= dx || isAtStep) {
|
||||
y += sy;
|
||||
}
|
||||
}
|
||||
|
||||
return pixels;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
Loading…
x
Reference in New Issue
Block a user