143 lines
5.0 KiB
JavaScript
143 lines
5.0 KiB
JavaScript
// js/canvasManager.js
|
|
|
|
let backgroundCanvas;
|
|
let lastShapesArray = [];
|
|
|
|
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
|
|
/**
|
|
* Renders all shapes into an SVG container
|
|
* @param {SVGElement} container
|
|
* @param {Array} shapesArray
|
|
* @param {Array} patches
|
|
*/
|
|
export function drawAllShapesOnCanvas(container, shapesArray, patches = []) {
|
|
if (!container || !(container instanceof SVGElement)) {
|
|
return;
|
|
}
|
|
|
|
// Ensure patches is an array
|
|
const patchArray = patches?.patches || patches || [];
|
|
if (!Array.isArray(patchArray)) {
|
|
console.warn("Expected patches to be an array, got:", typeof patchArray, patchArray);
|
|
// Fall back to full redraw
|
|
patches = [];
|
|
}
|
|
|
|
// If no patches, do a full redraw
|
|
if (!patchArray || patchArray.length === 0) {
|
|
// Clear container
|
|
while (container.firstChild) {
|
|
container.removeChild(container.firstChild);
|
|
}
|
|
|
|
// Draw all shapes
|
|
shapesArray.forEach(shape => {
|
|
let element;
|
|
if (shape.type === "circle") {
|
|
element = document.createElementNS(SVG_NS, "circle");
|
|
element.id = shape.id;
|
|
updateCircleAttributes(element, shape);
|
|
} else if (shape.type === "triangle") {
|
|
element = document.createElementNS(SVG_NS, "polygon");
|
|
element.id = shape.id;
|
|
updateTriangleAttributes(element, shape);
|
|
}
|
|
if (element) {
|
|
container.appendChild(element);
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Process patches
|
|
patchArray.forEach(patch => {
|
|
// Check if this patch affects the shapes array
|
|
if (patch.path[0] === 'shapes') {
|
|
if (patch.action === 'put') {
|
|
const shapeIndex = patch.path[1];
|
|
const shape = shapesArray[shapeIndex];
|
|
if (!shape) return;
|
|
|
|
let element = document.getElementById(shape.id);
|
|
if (!element) {
|
|
// Create new element
|
|
if (shape.type === "circle") {
|
|
element = document.createElementNS(SVG_NS, "circle");
|
|
element.id = shape.id;
|
|
updateCircleAttributes(element, shape);
|
|
} else if (shape.type === "triangle") {
|
|
element = document.createElementNS(SVG_NS, "polygon");
|
|
element.id = shape.id;
|
|
updateTriangleAttributes(element, shape);
|
|
}
|
|
if (element) {
|
|
container.appendChild(element);
|
|
}
|
|
} else {
|
|
// Update existing element
|
|
if (shape.type === "circle") {
|
|
updateCircleAttributes(element, shape);
|
|
} else if (shape.type === "triangle") {
|
|
updateTriangleAttributes(element, shape);
|
|
}
|
|
}
|
|
} else if (patch.action === 'del') {
|
|
// Shape removed
|
|
const element = document.getElementById(patch.path[1]);
|
|
if (element) {
|
|
container.removeChild(element);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateSpecificAttribute(element, shape, path) {
|
|
if (shape.type === "circle") {
|
|
switch (path[path.length - 1]) {
|
|
case 'x':
|
|
element.setAttributeNS(null, "cx", shape.x);
|
|
break;
|
|
case 'y':
|
|
element.setAttributeNS(null, "cy", shape.y);
|
|
break;
|
|
case 'radius':
|
|
element.setAttributeNS(null, "r", shape.radius);
|
|
break;
|
|
case 'color':
|
|
element.setAttributeNS(null, "fill", shape.color || "black");
|
|
break;
|
|
}
|
|
} else if (shape.type === "triangle") {
|
|
if (path.includes('coordinates')) {
|
|
const points = shape.coordinates
|
|
.map(p => `${p.x},${p.y}`)
|
|
.join(" ");
|
|
element.setAttributeNS(null, "points", points);
|
|
} else if (path.includes('color')) {
|
|
element.setAttributeNS(null, "fill", shape.color || "black");
|
|
}
|
|
}
|
|
}
|
|
|
|
function updateCircleAttributes(element, shape) {
|
|
element.setAttributeNS(null, "cx", shape.x);
|
|
element.setAttributeNS(null, "cy", shape.y);
|
|
element.setAttributeNS(null, "r", shape.radius);
|
|
element.setAttributeNS(null, "fill", shape.color || "black");
|
|
element.setAttributeNS(null, "stroke", "black");
|
|
element.setAttributeNS(null, "stroke-width", "1");
|
|
}
|
|
|
|
function updateTriangleAttributes(element, shape) {
|
|
const points = shape.coordinates
|
|
.map(p => `${p.x},${p.y}`)
|
|
.join(" ");
|
|
element.setAttributeNS(null, "points", points);
|
|
element.setAttributeNS(null, "fill", shape.color || "black");
|
|
element.setAttributeNS(null, "stroke", "black");
|
|
element.setAttributeNS(null, "stroke-width", "1");
|
|
}
|
|
|