diff --git a/src/distanceField/distance-field.ts b/src/distanceField/distance-field.ts index 7a62b72..8dfdc35 100644 --- a/src/distanceField/distance-field.ts +++ b/src/distanceField/distance-field.ts @@ -68,29 +68,10 @@ export class DistanceField extends HTMLElement { } private renderDistanceField() { - const imageData = this.offscreenCtx.getImageData(0, 0, this.resolution, this.resolution); - - for (let row = 0; row < this.resolution; row++) { - for (let col = 0; col < this.resolution; col++) { - const index = (col * this.resolution + row) * 4; - const distance = this.fields.getDistance(row, col); - const color = this.fields.getColor(row, col); - - const maxDistance = 10; - const normalizedDistance = Math.sqrt(distance) / maxDistance; - const baseColor = { - r: (color * 7) % 256, - g: (color * 13) % 256, - b: (color * 19) % 256, - }; - - imageData.data[index] = baseColor.r * (1 - normalizedDistance); - imageData.data[index + 1] = baseColor.g * (1 - normalizedDistance); - imageData.data[index + 2] = baseColor.b * (1 - normalizedDistance); - imageData.data[index + 3] = 255; - } - } + // Get the computed ImageData from Fields + const imageData = this.fields.generateImageData(); + // Put the ImageData onto the offscreen canvas this.offscreenCtx.putImageData(imageData, 0, 0); // Draw scaled version to main canvas @@ -164,7 +145,8 @@ export class DistanceField extends HTMLElement { handleGeometryUpdate = (event: Event) => { const geometry = event.target as HTMLElement; - const index = Array.from(document.querySelectorAll('fc-geometry')).indexOf(geometry as FolkGeometry); + // TODO: store as array from getgo + const index = Array.from(this.geometries).indexOf(geometry as FolkGeometry); if (index === -1) return; const rect = geometry.getBoundingClientRect(); @@ -176,16 +158,15 @@ export class DistanceField extends HTMLElement { ]; if (index < this.fields.shapes.length) { - this.updateShape(index, points); + this.fields.updateShape(index, this.transformPoints(points)); } else { - this.addShape(points); + this.fields.addShape(this.transformPoints(points)); } + + this.renderDistanceField(); }; - updateShape(index: number, points: Vector2[]) { - // Transform each point from screen coordinates to field coordinates - const transformedPoints = points.map((point) => this.transformToFieldCoordinates(point)); - this.fields.updateShape(index, transformedPoints); - this.renderDistanceField(); + private transformPoints(points: Vector2[]): Vector2[] { + return points.map((point) => this.transformToFieldCoordinates(point)); } } diff --git a/src/distanceField/fields.ts b/src/distanceField/fields.ts index 9cf39aa..a1ff011 100644 --- a/src/distanceField/fields.ts +++ b/src/distanceField/fields.ts @@ -39,11 +39,10 @@ export class Fields { return this.colorField[x][y]; } - addShape(points: Vector2[]) { - const color = Math.floor(Math.random() * 255); - this.shapes.push({ points, color }); + addShape(points: Vector2[], color?: number) { + const shapeColor = color ?? Math.floor(Math.random() * 255); + this.shapes.push({ points, color: shapeColor }); this.updateFields(); - console.log(this.shapes); } removeShape(index: number) { @@ -245,4 +244,34 @@ export class Fields { this.updateFields(); } } + + /** + * Generates ImageData for rendering, encapsulating all computational logic. + */ + public generateImageData(): ImageData { + const imageData = new ImageData(this.resolution, this.resolution); + + for (let row = 0; row < this.resolution; row++) { + for (let col = 0; col < this.resolution; col++) { + const index = (col * this.resolution + row) * 4; + const distance = this.getDistance(row, col); + const color = this.getColor(row, col); + + const maxDistance = 10; + const normalizedDistance = Math.sqrt(distance) / maxDistance; + const baseColor = { + r: (color * 7) % 256, + g: (color * 13) % 256, + b: (color * 19) % 256, + }; + + imageData.data[index] = baseColor.r * (1 - normalizedDistance); + imageData.data[index + 1] = baseColor.g * (1 - normalizedDistance); + imageData.data[index + 2] = baseColor.b * (1 - normalizedDistance); + imageData.data[index + 3] = 255; + } + } + + return imageData; + } }