Reputation: 5699
I'm playing around with creating some optical art with p5 and I'm running into issues with the image
function. This is mt sketch.js file:
import Tile from "./Tile.js";
new p5(p5 => {
const rows = 14;
const columns = 14;
const dimension = 40
const height = rows * dimension;
const width = columns * dimension;
const framerate = 1;
const tiles = [];
p5.setup = () => {
p5.createCanvas(width, height);
p5.frameRate(framerate);
for (let r = 0; r < rows; r++) {
for (let c = 0; c < columns; c++) {
tiles.push(new Tile(p5, c * dimension, r * dimension, dimension, r, c));
}
}
};
p5.draw = () => {
p5.background(200);
tiles.forEach((tile) => {
console.log(tile);
p5.image(tile.update(), tile.x, tile.y);
});
};
});
And this is Tile.js:
export default class Tile {
constructor(p5, x, y, dimension, row, column) {
this.p5 = p5;
this.x = x;
this.y = y;
this.dimension = dimension;
this.row = row;
this.column = column;
this.onFirst = true;
this.on = p5.color(255, 184, 0);
this.off = p5.color(26, 17, 16);
this.diameter = Math.sqrt(Math.pow(dimension, 2) * 2)
this.pg = this.p5.createGraphics(dimension, dimension)
this.pg.noStroke();
}
update() {
if (this.diameter < 0) {
this.diameter = Math.sqrt(Math.pow(this.dimension, 2) * 2);
this.onFirst = !this.onFirst
}
else {
this.diameter -= 1;
}
return this.draw();
}
draw() {
this.pg.fill(this.onFirst ? this.off : this.on);
this.pg.rect(this.x, this.y, this.dimension, this.dimension);
this.pg.fill(this.onFirst ? this.on : this.off);
this.pg.circle(this.x + this.dimension / 2, this.y + this.dimension / 2, this.diameter);
return this.pg;
}
}
While I starting out I just had the one image and that was displayed on the top left as I wanted... subsequent images are not though, artefacts appear in odd places though (as you can see here: https://jsfiddle.net/annoyingmouse/Lbs9v8f4/). I've tried all sorts of things like exporting the image as a Base64 image and using loadImage
but I think I might've been barking up the wrong tree.
Any help would be greatly appreciated :-)
Upvotes: 1
Views: 681
Reputation: 211278
Note, the method Tile.draw
draws to an image (.pg
) with a size of (.dimension
, .dimension
) rather than the canvas.
So the the origin has to be (0, 0) rather than (.x
, .y
), because the final image (.pg
) is placed on the canvas at (.x
, .y
).
Change the code as follows, to solve the issue:
draw() {
this.pg.fill(this.onFirst ? this.off : this.on);
// this.pg.rect(this.x, this.y, this.dimension, this.dimension);
this.pg.rect(0, 0, this.dimension, this.dimension);
this.pg.fill(this.onFirst ? this.on : this.off);
// this.pg.circle(this.x + this.dimension / 2, this.y + this.dimension / 2, this.diameter);
this.pg.circle(this.dimension / 2, this.dimension / 2, this.diameter);
return this.pg;
}
See the example:
new p5(p5 => {
const rows = 14;
const columns = 14;
const dimension = 40
const height = rows * dimension;
const width = columns * dimension;
const framerate = 60;
const tiles = [];
p5.setup = () => {
p5.createCanvas(width, height);
p5.frameRate(framerate);
for (let r = 0; r < rows; r++) {
for (let c = 0; c < columns; c++) {
tiles.push(new Tile(p5, c * dimension, r * dimension, dimension, r, c));
}
}
};
p5.draw = () => {
p5.background(200);
tiles.forEach((tile) => {
console.log(tile);
p5.image(tile.update(), tile.x, tile.y);
});
};
});
class Tile {
constructor(p5, x, y, dimension, row, column) {
this.p5 = p5;
this.x = x;
this.y = y;
this.dimension = dimension;
this.row = row;
this.column = column;
this.onFirst = true;
this.on = p5.color(255, 184, 0);
this.off = p5.color(26, 17, 16);
this.diameter = Math.sqrt(Math.pow(dimension, 2) * 2)
this.pg = this.p5.createGraphics(dimension, dimension)
this.pg.noStroke();
}
update() {
if (this.diameter < 0) {
this.diameter = Math.sqrt(Math.pow(this.dimension, 2) * 2);
this.onFirst = !this.onFirst
}
else {
this.diameter -= 1;
}
return this.draw();
}
draw() {
this.pg.fill(this.onFirst ? this.off : this.on);
this.pg.rect(0, 0, this.dimension, this.dimension);
this.pg.fill(this.onFirst ? this.on : this.off);
this.pg.circle(this.dimension / 2, this.dimension / 2, this.diameter);
return this.pg;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
Upvotes: 1