# Draw with loops

In here I will document some methods for time-based drawing using simple loops

Before getting into the details, I'll start by going through a basic canvas setup that will give me some of the basics. You can use available frameworks such as p5js as-well, but I prefer this method.

I've put in documentation into the js code of the details, but the important part is that I've created a `draw`

function that executes on every render frame. For now, I've only put in a function that fills the background with a red color, you will see it fade in, as it is using a low opacity.

The basis, at the lowest level, is a variable that goes(increments) from `0`

to `n`

then starts over again

The mechanics is that you have a variable `val`

that gets updated every time an update is called. If the value reaches a maximum `range`

value, it starts from beginning again. This is done using a modulo(`%`

) function `val = (val + 1) % range`

This is a class that will allow a variable to hold some basic values

` ````
// create a class to hold value and have built in incrementing functionality
function Looper (range, start) {
this.val = start || 0 // set value to start value if defined, or 1
this.range = range || 100 // set range to passed value or default to 0
this.norm = this.val / this.range // initialize normalized value (between 0 and 1)
this.update = function () {
this.val = (this.val + 1) % this.range // update value
this.norm = this.val / this.range // update normalize value (between 0 and 1)
}
}
```

to show how this works, I created a loop instance, which will go from 0 to 299
`var loop1 = new Looper(300, 0)`

and then inside the draw loop, I use it to draw a circle (using a custom function that takes x, y, and radius values)

`drawCircle(loop1.val - loop1.range / 2, 0, 50)`

and, also inside the draw loop, I update the loop and the loop values
`loop1.update()`

what you will see is that the circle will move along the x axis from -150 to 149, then go to -150 again and repeat indefinetly. This is because the value goes from 0 to 299 and is offset by -150.

now instead of using the value `val`

, I switch to using the normalized value `norm`

which will return a value between 0 and 1. The `range`

in this case becomes the number of steps between 0 and 1. *node that it will never be 1, because instead of a value of 1 it will skip back to 0*

This is the code I'm using to draw using a normalized value. (I offset it by `-0.5`

because my 0,0 point is in the middle)

` ````
drawCircle((loop1.norm - 0.5) * (canvas.width - 100), 0, 50)
```

The next step is to add a smoother back-and forth animation.

This is done using some simple trigonometry.

` ````
// in the loop function
this.sin = Math.sin(this.norm * Math.PI * 2)
//in the draw loop
drawCircle((loop1.sin) * (canvas.width/2), 0, 50)
```

to understand how this works, look at this graph. The *x* axis, in the ranges from 0 to 2 * PI, completes a full wave. Thy *y* axis ranges from -1 to +1. So to get a value that goes from 0, up to 1, then down to -1 and back to 0, we map the normalized value `norm`

to 2PI (so instead of ranging from 0 to 1 it ranges from 0 to 2PI)

*source: wikipedia*

Now the same thing with normalized the sine, so we have a range from 0 to 1

adding new variable called `sinNorm`

to the loop class

` ````
this.sinNorm = (this.sin + 1) / 2
```

and updating the draw function to utilize it.
```
drawCircle((loop1.sinNorm - 0.5) * (canvas.width), 0, 50)
```

Now I'm adding a cos value as-well and applying to y axis

` ````
// in loop class/function
this.cos = Math.cos(this.norm * Math.PI * 2) // get cosine value from norm normalized to [0, 2PI]
this.cosNorm = (this.cos + 1) / 2 // normalize cos to [0,1]
//in draw loop
var r = 50 // radius of circle (using it below to adjust range along x and y axis)
drawCircle((loop1.sin) * (canvas.width/2 - r), (loop1.cos) * (canvas.height/2 - r), r)
```

Now that that works and makes sense, I apply the create multipe particle instances that have multiple loopers mapped to position, size, and color

The magic happens in the `Particle`

class. I've set up 3 particles, and using all of them to update the the x and y position. I'm using the loopers to update the circle radius and color.

` ````
function Particle() {
// initialize loopers with random trange and offset
this.loop1 = new Looper(2000 + 200 * Math.random(), 860 * Math.random())
this.loop2 = new Looper(500 + 250 * Math.random(), 220 * Math.random())
this.loop3 = new Looper(120 + 20 * Math.random(), 140 * Math.random())
this.offset = Math.random() // some color offset for the color
this.draw = function (){
// set x,y, radius, and color params
var x = (this.loop1.sin) * (canvas.width/4 - 10) + (this.loop2.sin) * (canvas.width/6 - 10) + (this.loop3.sin) * 30
var y = (this.loop1.cos) * (canvas.height/4 - 10) + (this.loop2.cos) * (canvas.height/6 - 10) + (this.loop3.cos) * 30
var r = 0.5 + 8 * this.loop3.sinNorm * this.loop3.cosNorm // set the radius
var c = `hsla(${80 + 50 * (this.loop3.cosNorm + this.offset) * this.loop2.sinNorm}, ${100}%, ${50 + 10 * this.loop3.sin}%, ${0.5})`
drawCircle(x, y, r, c); // draw the circle
this.loop1.update() // update looper
this.loop2.update() // update looper
this.loop3.update() // update looper
}
}
```

Awesome! I am really amazed to see your work. Thanks

Best breakdown ever! Thank you.

I am really amazed by your work sir.