225 lines
6 KiB
JavaScript
225 lines
6 KiB
JavaScript
import { rgbToHex } from "../utils/rgbToHex";
|
|
import { shadeColor } from "../utils/shadeColor";
|
|
|
|
function Stitch(x, y, flags, color) {
|
|
this.flags = flags;
|
|
this.x = x;
|
|
this.y = y;
|
|
this.color = color;
|
|
}
|
|
|
|
function Color(r, g, b, description) {
|
|
this.r = r;
|
|
this.g = g;
|
|
this.b = b;
|
|
this.description = description;
|
|
}
|
|
|
|
const stitchTypes = {
|
|
normal: 0,
|
|
jump: 1,
|
|
trim: 2,
|
|
stop: 4,
|
|
end: 8,
|
|
};
|
|
|
|
function Pattern() {
|
|
this.colors = [];
|
|
this.stitches = [];
|
|
this.hoop = {};
|
|
this.lastX = 0;
|
|
this.lastY = 0;
|
|
this.top = 0;
|
|
this.bottom = 0;
|
|
this.left = 0;
|
|
this.right = 0;
|
|
this.currentColorIndex = 0;
|
|
}
|
|
|
|
Pattern.prototype.addColorRgb = function (r, g, b, description) {
|
|
this.colors[this.colors.length] = new Color(r, g, b, description);
|
|
};
|
|
|
|
Pattern.prototype.addColor = function (color) {
|
|
this.colors[this.colors.length] = color;
|
|
};
|
|
|
|
Pattern.prototype.addStitchAbs = function (x, y, flags, isAutoColorIndex) {
|
|
if ((flags & stitchTypes.end) === stitchTypes.end) {
|
|
this.calculateBoundingBox();
|
|
this.fixColorCount();
|
|
}
|
|
if (
|
|
(flags & stitchTypes.stop) === stitchTypes.stop &&
|
|
this.stitches.length === 0
|
|
) {
|
|
return;
|
|
}
|
|
if ((flags & stitchTypes.stop) === stitchTypes.stop && isAutoColorIndex) {
|
|
this.currentColorIndex += 1;
|
|
}
|
|
this.stitches[this.stitches.length] = new Stitch(
|
|
x,
|
|
y,
|
|
flags,
|
|
this.currentColorIndex
|
|
);
|
|
};
|
|
|
|
Pattern.prototype.addStitchRel = function (dx, dy, flags, isAutoColorIndex) {
|
|
if (this.stitches.length !== 0) {
|
|
let nx = this.lastX + dx,
|
|
ny = this.lastY + dy;
|
|
this.lastX = nx;
|
|
this.lastY = ny;
|
|
this.addStitchAbs(nx, ny, flags, isAutoColorIndex);
|
|
} else {
|
|
this.addStitchAbs(dx, dy, flags, isAutoColorIndex);
|
|
}
|
|
};
|
|
|
|
Pattern.prototype.calculateBoundingBox = function () {
|
|
let i = 0,
|
|
stitchCount = this.stitches.length,
|
|
pt;
|
|
if (stitchCount === 0) {
|
|
this.bottom = 1;
|
|
this.right = 1;
|
|
return;
|
|
}
|
|
this.left = 99999;
|
|
this.top = 99999;
|
|
this.right = -99999;
|
|
this.bottom = -99999;
|
|
|
|
for (i = 0; i < stitchCount; i += 1) {
|
|
pt = this.stitches[i];
|
|
if (!(pt.flags & stitchTypes.trim)) {
|
|
this.left = this.left < pt.x ? this.left : pt.x;
|
|
this.top = this.top < pt.y ? this.top : pt.y;
|
|
this.right = this.right > pt.x ? this.right : pt.x;
|
|
this.bottom = this.bottom > pt.y ? this.bottom : pt.y;
|
|
}
|
|
}
|
|
};
|
|
|
|
Pattern.prototype.moveToPositive = function () {
|
|
let i = 0,
|
|
stitchCount = this.stitches.length;
|
|
for (i = 0; i < stitchCount; i += 1) {
|
|
this.stitches[i].x -= this.left;
|
|
this.stitches[i].y -= this.top;
|
|
}
|
|
this.right -= this.left;
|
|
this.left = 0;
|
|
this.bottom -= this.top;
|
|
this.top = 0;
|
|
};
|
|
|
|
Pattern.prototype.invertPatternVertical = function () {
|
|
let i = 0,
|
|
temp = -this.top,
|
|
stitchCount = this.stitches.length;
|
|
for (i = 0; i < stitchCount; i += 1) {
|
|
this.stitches[i].y = -this.stitches[i].y;
|
|
}
|
|
this.top = -this.bottom;
|
|
this.bottom = temp;
|
|
};
|
|
|
|
Pattern.prototype.addColorRandom = function () {
|
|
this.colors[this.colors.length] = new Color(
|
|
Math.round(Math.random() * 256),
|
|
Math.round(Math.random() * 256),
|
|
Math.round(Math.random() * 256),
|
|
"random"
|
|
);
|
|
};
|
|
|
|
Pattern.prototype.fixColorCount = function () {
|
|
let maxColorIndex = 0,
|
|
stitchCount = this.stitches.length,
|
|
i;
|
|
for (i = 0; i < stitchCount; i += 1) {
|
|
maxColorIndex = Math.max(maxColorIndex, this.stitches[i].color);
|
|
}
|
|
while (this.colors.length <= maxColorIndex) {
|
|
this.addColorRandom();
|
|
}
|
|
this.colors.splice(maxColorIndex + 1, this.colors.length - maxColorIndex - 1);
|
|
};
|
|
|
|
Pattern.prototype.drawShapeTo = function (canvas) {
|
|
canvas.width = this.right;
|
|
canvas.height = this.bottom;
|
|
|
|
let gradient, tx, ty;
|
|
let lastStitch = this.stitches[0];
|
|
let gWidth = 100;
|
|
if (canvas.getContext) {
|
|
const ctx = canvas.getContext("2d");
|
|
ctx.lineWidth = 3;
|
|
ctx.lineJoin = "round";
|
|
|
|
let color = this.colors[this.stitches[0].color];
|
|
for (let i = 0; i < this.stitches.length; i++) {
|
|
const currentStitch = this.stitches[i];
|
|
if (i > 0) lastStitch = this.stitches[i - 1];
|
|
tx = currentStitch.x - lastStitch.x;
|
|
ty = currentStitch.y - lastStitch.y;
|
|
|
|
gWidth = Math.sqrt(tx * tx + ty * ty);
|
|
gradient = ctx.createRadialGradient(
|
|
currentStitch.x - tx,
|
|
currentStitch.y - ty,
|
|
0,
|
|
currentStitch.x - tx,
|
|
currentStitch.y - ty,
|
|
gWidth * 1.4
|
|
);
|
|
|
|
gradient.addColorStop("0", shadeColor(rgbToHex(color), -60));
|
|
gradient.addColorStop("0.05", rgbToHex(color));
|
|
gradient.addColorStop("0.5", shadeColor(rgbToHex(color), 60));
|
|
gradient.addColorStop("0.9", rgbToHex(color));
|
|
gradient.addColorStop("1.0", shadeColor(rgbToHex(color), -60));
|
|
|
|
ctx.strokeStyle = gradient;
|
|
if (
|
|
currentStitch.flags === stitchTypes.jump ||
|
|
currentStitch.flags === stitchTypes.trim ||
|
|
currentStitch.flags === stitchTypes.stop
|
|
) {
|
|
color = this.colors[currentStitch.color];
|
|
ctx.beginPath();
|
|
ctx.strokeStyle =
|
|
"rgba(" + color.r + "," + color.g + "," + color.b + ",0)";
|
|
ctx.moveTo(currentStitch.x, currentStitch.y);
|
|
ctx.stroke();
|
|
}
|
|
ctx.beginPath();
|
|
ctx.moveTo(lastStitch.x, lastStitch.y);
|
|
ctx.lineTo(currentStitch.x, currentStitch.y);
|
|
ctx.stroke();
|
|
lastStitch = currentStitch;
|
|
}
|
|
}
|
|
};
|
|
|
|
Pattern.prototype.drawColorsTo = function (colorContainer) {
|
|
this.colors.forEach((color) => {
|
|
colorContainer.innerHTML += `<div style='background-color: rgb(${color.r}, ${color.g}, ${color.b}); height: 25px; width: 25px; border: 1px solid #000000;'></div>`;
|
|
});
|
|
};
|
|
|
|
Pattern.prototype.drawStitchesCountTo = function (stitchesContainer, stitchesString) {
|
|
stitchesContainer.innerHTML += `<div><strong>${stitchesString}:</strong> ${this.stitches.length} </div>`;
|
|
};
|
|
|
|
Pattern.prototype.drawSizeValuesTo = function (sizeContainer, dimensionsString) {
|
|
sizeContainer.innerHTML += `<div><strong>${dimensionsString}:</strong> ${Math.round(
|
|
this.right / 10
|
|
)}mm x ${Math.round(this.bottom / 10)}mm </div>`;
|
|
};
|
|
|
|
export { Pattern, Color, stitchTypes };
|