Reputation: 145
I'm trying to build a continuous animation that connects the dots based on a simple algorithm. The end result will look like this, https://editor.p5js.org/knectar/sketches/c7BygWs3c The animation will look like this, https://editor.p5js.org/knectar/sketches/lpn3kSO7D.
The code is below.
It seems like it's close, but after the first element animates as expected, the remainder of the path just fills out in one frame.
Any suggestions?
var zag;
var spacing = 125;
var ready = false;
var nodeCounter;
function setup() {
createCanvas(windowWidth, windowHeight);
zag = new Zag();
nodeCounter = zag.comboArr.length - 1;
}
function draw() {
background(0);
translate(200, 0);
zag.animateLine(nodeCounter);
if (ready) {
ready = false;
nodeCounter--;
console.log(nodeCounter);
}
// zag.display();
}
class Zag {
constructor() {
this.nodeCount = 4;
this.comboArr = [];
this.setArrs();
this.combineArr();
}
animateLine(index) {
let tempX, tempY;
let first = this.comboArr[index];
let next = this.comboArr[index - 1];
tempX = map(frameCount, 0, 100, first.x, next.x, 1);
tempY = map(frameCount, 0, 100, first.y, next.y, 1);
stroke(25, 22, 220);
noFill();
strokeWeight(10);
line(first.x, first.y, tempX, tempY);
if (tempX == next.x && tempY == next.y) {
ready = true;
console.log(nodeCounter);
}
}
setArrs() {
this.baseArrA = [];
this.baseArrB = [];
for (let i = 1; i <= this.nodeCount; i++) {
this.baseArrA.push(i);
this.baseArrB.push(i);
}
this.shuffleArr(this.baseArrA);
this.shuffleArr(this.baseArrB);
}
combineArr() {
for (let i = 0; i <= this.nodeCount - 1; i++) {
this.comboArr.push(createVector(0, this.baseArrA[i] * spacing));
this.comboArr.push(createVector(spacing, this.baseArrB[i] * spacing));
}
}
shuffleArr(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
display() {
let i = 1;
fill(200);
noStroke();
textSize(15);
for (let item of this.comboArr) {
text(i + ": " + item.x + ":" + item.y, item.x + 10, item.y - 5);
i++;
}
}
}
Upvotes: 0
Views: 189
Reputation: 1830
There are a couple of problems with the code.
frameCount
does not work well for the map
function because we need to reset it to zero for each line. We can work around this by keeping a dedicated count variable that gets reset to zero every time it reaches 100x
and y
positions have reached the next point does not work well because they may never match exactly. If we use our new count
variable we don't have to check line end point positionsHere is code similar to your sketch that uses the independent count
variable
var zag;
var spacing = 125;
var ready = false;
var nodeCounter;
function setup() {
createCanvas(600, 600);
zag = new Zag();
nodeCounter = zag.comboArr.length - 1;
background(0);
frameRate(20);
}
function draw() {
translate(200, 0);
zag.animateLine(nodeCounter);
if (ready && nodeCounter > 1) {
ready = false;
nodeCounter--;
}
}
var count = 0;
class Zag {
constructor() {
this.nodeCount = 4;
this.comboArr = [];
this.setArrs();
this.combineArr();
}
animateLine(index) {
let tempX, tempY;
let first = this.comboArr[index];
let next = this.comboArr[index - 1];
count++;
tempX = map(count, 0, 100, first.x, next.x, 1);
tempY = map(count, 0, 100, first.y, next.y, 1);
stroke(25, 22, 220);
noFill();
strokeWeight(10);
line(first.x, first.y, tempX, tempY);
if (count > 99){
ready = true;
count = 0;
}
}
setArrs() {
this.baseArrA = [];
this.baseArrB = [];
for (let i = 1; i <= this.nodeCount; i++) {
this.baseArrA.push(i);
this.baseArrB.push(i);
}
this.shuffleArr(this.baseArrA);
this.shuffleArr(this.baseArrB);
}
combineArr() {
for (let i = 0; i <= this.nodeCount - 1; i++) {
this.comboArr.push(createVector(0, this.baseArrA[i] * spacing));
this.comboArr.push(createVector(spacing, this.baseArrB[i] * spacing));
}
}
shuffleArr(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>
Upvotes: 1
Reputation: 1164
The reason why you're getting this is that when you do:
tempX = map(frameCount, 0, 100, first.x, next.x, 1);
tempY = map(frameCount, 0, 100, first.y, next.y, 1);
you're expecting that frameCount
is between 0
and 100
. In fact, frameCount
keeps increasing, and the drawing speed keeps increasing, too.
Try changing the two lines to:
var tempFrameCount = frameCount % 100;
tempX = map(tempFrameCount, 0, 99, first.x, next.x, 1);
tempY = map(tempFrameCount, 0, 99, first.y, next.y, 1);
This should work.
Upvotes: 1