Hi @Vitaliy ,
Here’s my take on a 2D canvas in a pattern, I’ve used something similar in many patterns.
2D canvas example.epe (7.9 KB)
/* Rendering into a "canvas" example
*
* In this example, an array is created to represent a 2D canvas with
* x and y values in world coordinates, which are values from 0 to 1 exclusive.
* The canvas is then scaled and drawn to the LEDs. The LEDs could match 1:1
* or could be some other size, or even a non uniform layout.
* The canvas is set up with 2 arrays, one for values, one for hues, which
* are then fed to hsv() during render2D.
*
* This example draws a dot traveling around the circumference of a circle,
* leaving a fading trail of color.
*/
var width = 8
var height = 8
var numPixels = width * height
var canvasValues = array(numPixels) //make a "canvas" of brightness values
var canvasHues = array(numPixels) //likewise for hues
var fade = .95
//find the pixel index within a canvas array
//pixels are packed in rows, then columns of rows
function getIndex(x, y) {
return floor(x*width) + floor(y*height)*width
}
function isIndexValid(index) {
return index >= 0 && index < numPixels
}
export function beforeRender(delta) {
//fade out any existing pixels
canvasValues.mutate(p => p*fade) //TODO fade based on delta for consistent fade
//draw into the canvas here
//this draws a pixel moving in a circle
//radius 1/3rd, centered at 0.5, 0.5
var a = time(.01) * PI2
var r = 1/3
var x = sin(a) * r + 0.5
var y = cos(a) * r + 0.5
//optionally, you can make the pixels "wrap" around to the other side if out of bounds
// x = mod(x,.99999)
// y = mod(y,.99999)
//calc this pixel's index in the canvas based on position of our coordinate
var index = getIndex(x, y)
//check that the coordinate is within bounds of the canvas before using it
if (isIndexValid(index)) {
canvasValues[index] = 1
canvasHues[index] = time(.015)
}
}
export function render2D(index, x, y) {
index = getIndex(x, y) //calc this pixel's index in the canvas based on position
h = canvasHues[index]
v = canvasValues[index]
hsv(h, 1, v*v)
}
More context here: