xxxxxxxxxx
214
class WeavingDraft {
constructor(nbThreads, nbTieups, lengthDraw, cellSize, padding) {
// Define grid sizes, positions, and offsets
this.threading = new Grid(nbThreads, 2, cellSize, 'threading', padding, padding);
this.tieup = new Grid(2, 2, cellSize, 'tieUp', nbThreads * cellSize + 1.5 * padding, padding * 1);
this.treadling = new Grid(2, lengthDraw, cellSize, 'treadling', nbThreads * cellSize + 1.5 * padding, 2 * cellSize + 1.5 * padding);
this.drawdown = new Grid(nbThreads, lengthDraw, cellSize, 'drawdown', padding, 2 * cellSize + 1.5 * padding);
this.padding = padding;
// Initialize a straight tie-up configuration for the 2x2 grid
this.tieup.cells[0][0] = true; // First block on the first line is on
this.tieup.cells[1][1] = true; // Second block on the second line is on
// Initialize alternating light and dark squares for the threading and treadling grids
for (let i = 0; i < this.threading.cols; i++) {
for (let j = 0; j < this.threading.rows; j++) {
this.threading.cells[i][j] = (i + j) % 2 === 0;
}
}
for (let i = 0; i < this.treadling.cols; i++) {
for (let j = 0; j < this.treadling.rows; j++) {
this.treadling.cells[i][j] = (i + j) % 2 === 0;
}
}
// Automatically calculate the drawdown grid on load
this.updateDrawdown();
}
draw() {
this.threading.draw();
this.tieup.draw();
this.treadling.draw();
this.drawLabels();
this.drawdown.draw();
// Handle cursor change to hand when hovering over threading and treadling grids
if (this.isMouseOverGrid(this.threading) || this.isMouseOverGrid(this.treadling)) {
cursor(HAND);
} else {
cursor(ARROW);
}
}
drawLabels() {
textAlign(CENTER, CENTER);
textSize(14);
fill(0);
// Label threading grid
text("Threading", this.threading.xOffset + (this.threading.cols * this.threading.cellSize) / 2, this.padding / 2);
// Label treadling grid (rotated)
push();
translate(this.tieup.xOffset + this.tieup.cols * this.tieup.cellSize + this.padding / 2, height / 2 + this.padding / 2);
rotate(HALF_PI);
text("Pedaling Order", 0, 0);
pop();
// Label drawdown grid
text("Weaving Matrix", this.drawdown.xOffset + (this.drawdown.cols * this.drawdown.cellSize) / 2, height - this.padding / 2);
}
mousePressed(mouseX, mouseY) {
// Delegate the mousePressed event to each grid
if (!this.threading.mousePressed(mouseX, mouseY)
&& !this.tieup.mousePressed(mouseX, mouseY)
&& !this.treadling.mousePressed(mouseX, mouseY)) {
this.drawdown.mousePressed(mouseX, mouseY);
}
// Update the drawdown after any interaction
this.updateDrawdown();
}
updateDrawdown() {
// Clear the current drawdown
this.drawdown.cells.forEach(row => row.fill(false));
// Iterate through each row in the treadling
for (let treadlingRow = 0; treadlingRow < this.treadling.rows; treadlingRow++) {
for (let treadleCol = 0; treadleCol < this.treadling.cols; treadleCol++) {
// Check if the treadle is pressed
if (this.treadling.cells[treadleCol][treadlingRow]) {
// For each pressed treadle, look up the tie-up to see which shafts are lifted
for (let shaft = 0; shaft < this.tieup.rows; shaft++) {
if (this.tieup.cells[treadleCol][shaft]) {
// For each lifted shaft, find the corresponding warp threads in the threading
for (let threadingCol = 0; threadingCol < this.threading.cols; threadingCol++) {
if (this.threading.cells[threadingCol][shaft]) {
// Mark the intersection of the lifted warp and the current weft as weft-dominant (black)
this.drawdown.cells[threadingCol][treadlingRow] = true;
}
}
}
}
}
}
}
}
isMouseOverGrid(grid) {
return mouseX >= grid.xOffset && mouseX <= grid.xOffset + grid.cols * grid.cellSize
&& mouseY >= grid.yOffset && mouseY <= grid.yOffset + grid.rows * grid.cellSize;
}
}
class Grid {
constructor(cols, rows, cellSize, type, xOffset, yOffset) {
this.cols = cols;
this.rows = rows;
this.cellSize = cellSize;
this.type = type;
this.xOffset = xOffset;
this.yOffset = yOffset;
this.cells = new Array(cols).fill(null).map(() => new Array(rows).fill(false));
}
draw() {
for (let i = 0; i < this.cols; i++) {
for (let j = 0; j < this.rows; j++) {
const x = this.xOffset + i * this.cellSize;
const y = this.yOffset + j * this.cellSize;
if (this.type === 'drawdown') {
stroke('black');
if (this.cells[i][j]) {
fill('#333');
} else {
fill('#fff');
}
} else {
strokeWeight(0.2);
stroke('#FF5F1F');
if (this.cells[i][j]) {
fill('#FF5F1F');
} else {
fill('#fff');
}
}
rect(x, y, this.cellSize, this.cellSize);
}
}
}
mousePressed(mouseX, mouseY) {
// Check if the click is within this grid's bounds
if (mouseX >= this.xOffset && mouseX <= this.xOffset + this.cols * this.cellSize
&& mouseY >= this.yOffset && mouseY <= this.yOffset + this.rows * this.cellSize) {
// Calculate the cell indices
const i = Math.floor((mouseX - this.xOffset) / this.cellSize);
const j = Math.floor((mouseY - this.yOffset) / this.cellSize);
// Toggle the cell if the grid is not 'drawdown'
if (this.type !== 'drawdown') {
this.toggleCell(i, j);
}
return true; // Indicate that the click was handled
}
return false; // Click was not within this grid
}
toggleCell(i, j) {
if (i >= 0 && i < this.cols && j >= 0 && j < this.rows) {
if (this.type === 'treadling' && !this.cells[i][j]) {
for (let col = 0; col < this.cols; col++) {
this.cells[col][j] = false;
}
}
this.cells[i][j] = !this.cells[i][j];
}
}
}
// P5.js setup and draw functions
let draft;
let img; // Declare the variable for the image
function preload() {
// Load the image in the preload function so that it's available when the sketch starts
img = loadImage('loomanatomy.png'); // Replace with the correct path to your image
}
function setup() {
const cellSize = 20;
const padding = 50;
const nbThreads = 10;
const nbTieups = 2;
const lengthDraw = 10;
createCanvas(370 * 2, 370);
draft = new WeavingDraft(nbThreads, nbTieups, lengthDraw, cellSize, padding);
}
function draw() {
background(255);
draft.draw();
// Resize the image to match the height of the canvas and display it on the right side
const imgHeight = height; // Set the image height equal to the canvas height
const imgWidth = img.width * (imgHeight / img.height); // Scale the image width proportionally to the height
// Display the image centered in the right half of the canvas
image(img, width - imgWidth, 0, imgWidth, imgHeight);
}
function mousePressed() {
draft.mousePressed(mouseX, mouseY);
}