mirror of
https://github.com/gunner47/GyverLamp.git
synced 2025-08-08 09:20:59 +03:00
183 lines
5.9 KiB
C++
183 lines
5.9 KiB
C++
// ================================= ЭФФЕКТЫ ====================================
|
|
|
|
// --------------------------------- конфетти ------------------------------------
|
|
void sparklesRoutine() {
|
|
for (byte i = 0; i < modes[0].scale; i++) {
|
|
byte x = random(0, WIDTH);
|
|
byte y = random(0, HEIGHT);
|
|
if (getPixColorXY(x, y) == 0)
|
|
leds[getPixelNumber(x, y)] = CHSV(random(0, 255), 255, 255);
|
|
}
|
|
fader(70);
|
|
}
|
|
|
|
// функция плавного угасания цвета для всех пикселей
|
|
void fader(byte step) {
|
|
for (byte i = 0; i < WIDTH; i++) {
|
|
for (byte j = 0; j < HEIGHT; j++) {
|
|
fadePixel(i, j, step);
|
|
}
|
|
}
|
|
}
|
|
void fadePixel(byte i, byte j, byte step) { // новый фейдер
|
|
int pixelNum = getPixelNumber(i, j);
|
|
if (getPixColor(pixelNum) == 0) return;
|
|
|
|
if (leds[pixelNum].r >= 30 ||
|
|
leds[pixelNum].g >= 30 ||
|
|
leds[pixelNum].b >= 30) {
|
|
leds[pixelNum].fadeToBlackBy(step);
|
|
} else {
|
|
leds[pixelNum] = 0;
|
|
}
|
|
}
|
|
|
|
// -------------------------------------- огонь ---------------------------------------------
|
|
// эффект "огонь"
|
|
#define SPARKLES 1 // вылетающие угольки вкл выкл
|
|
unsigned char line[WIDTH];
|
|
int pcnt = 0;
|
|
|
|
//these values are substracetd from the generated values to give a shape to the animation
|
|
const unsigned char valueMask[8][16] PROGMEM = {
|
|
{32 , 0 , 0 , 0 , 0 , 0 , 0 , 32 , 32 , 0 , 0 , 0 , 0 , 0 , 0 , 32 },
|
|
{64 , 0 , 0 , 0 , 0 , 0 , 0 , 64 , 64 , 0 , 0 , 0 , 0 , 0 , 0 , 64 },
|
|
{96 , 32 , 0 , 0 , 0 , 0 , 32 , 96 , 96 , 32 , 0 , 0 , 0 , 0 , 32 , 96 },
|
|
{128, 64 , 32 , 0 , 0 , 32 , 64 , 128, 128, 64 , 32 , 0 , 0 , 32 , 64 , 128},
|
|
{160, 96 , 64 , 32 , 32 , 64 , 96 , 160, 160, 96 , 64 , 32 , 32 , 64 , 96 , 160},
|
|
{192, 128, 96 , 64 , 64 , 96 , 128, 192, 192, 128, 96 , 64 , 64 , 96 , 128, 192},
|
|
{255, 160, 128, 96 , 96 , 128, 160, 255, 255, 160, 128, 96 , 96 , 128, 160, 255},
|
|
{255, 192, 160, 128, 128, 160, 192, 255, 255, 192, 160, 128, 128, 160, 192, 255}
|
|
};
|
|
|
|
//these are the hues for the fire,
|
|
//should be between 0 (red) to about 25 (yellow)
|
|
const unsigned char hueMask[8][16] PROGMEM = {
|
|
{1 , 11, 19, 25, 25, 22, 11, 1 , 1 , 11, 19, 25, 25, 22, 11, 1 },
|
|
{1 , 8 , 13, 19, 25, 19, 8 , 1 , 1 , 8 , 13, 19, 25, 19, 8 , 1 },
|
|
{1 , 8 , 13, 16, 19, 16, 8 , 1 , 1 , 8 , 13, 16, 19, 16, 8 , 1 },
|
|
{1 , 5 , 11, 13, 13, 13, 5 , 1 , 1 , 5 , 11, 13, 13, 13, 5 , 1 },
|
|
{1 , 5 , 11, 11, 11, 11, 5 , 1 , 1 , 5 , 11, 11, 11, 11, 5 , 1 },
|
|
{0 , 1 , 5 , 8 , 8 , 5 , 1 , 0 , 0 , 1 , 5 , 8 , 8 , 5 , 1 , 0 },
|
|
{0 , 0 , 1 , 5 , 5 , 1 , 0 , 0 , 0 , 0 , 1 , 5 , 5 , 1 , 0 , 0 },
|
|
{0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 }
|
|
};
|
|
|
|
void fireRoutine() {
|
|
if (loadingFlag) {
|
|
loadingFlag = false;
|
|
//FastLED.clear();
|
|
generateLine();
|
|
}
|
|
if (pcnt >= 100) {
|
|
shiftUp();
|
|
generateLine();
|
|
pcnt = 0;
|
|
}
|
|
drawFrame(pcnt);
|
|
pcnt += 30;
|
|
}
|
|
|
|
// Randomly generate the next line (matrix row)
|
|
|
|
void generateLine() {
|
|
for (uint8_t x = 0; x < WIDTH; x++) {
|
|
line[x] = random(64, 255);
|
|
}
|
|
}
|
|
|
|
void shiftUp() {
|
|
for (uint8_t y = HEIGHT - 1; y > 0; y--) {
|
|
for (uint8_t x = 0; x < WIDTH; x++) {
|
|
uint8_t newX = x;
|
|
if (x > 15) newX = x - 15;
|
|
if (y > 7) continue;
|
|
matrixValue[y][newX] = matrixValue[y - 1][newX];
|
|
}
|
|
}
|
|
|
|
for (uint8_t x = 0; x < WIDTH; x++) {
|
|
uint8_t newX = x;
|
|
if (x > 15) newX = x - 15;
|
|
matrixValue[0][newX] = line[newX];
|
|
}
|
|
}
|
|
|
|
// draw a frame, interpolating between 2 "key frames"
|
|
// @param pcnt percentage of interpolation
|
|
|
|
void drawFrame(int pcnt) {
|
|
int nextv;
|
|
|
|
//each row interpolates with the one before it
|
|
for (unsigned char y = HEIGHT - 1; y > 0; y--) {
|
|
for (unsigned char x = 0; x < WIDTH; x++) {
|
|
uint8_t newX = x;
|
|
if (x > 15) newX = x - 15;
|
|
if (y < 8) {
|
|
nextv =
|
|
(((100.0 - pcnt) * matrixValue[y][newX]
|
|
+ pcnt * matrixValue[y - 1][newX]) / 100.0)
|
|
- pgm_read_byte(&(valueMask[y][newX]));
|
|
|
|
CRGB color = CHSV(
|
|
modes[1].scale * 2.5 + pgm_read_byte(&(hueMask[y][newX])), // H
|
|
255, // S
|
|
(uint8_t)max(0, nextv) // V
|
|
);
|
|
|
|
leds[getPixelNumber(x, y)] = color;
|
|
} else if (y == 8 && SPARKLES) {
|
|
if (random(0, 20) == 0 && getPixColorXY(x, y - 1) != 0) drawPixelXY(x, y, getPixColorXY(x, y - 1));
|
|
else drawPixelXY(x, y, 0);
|
|
} else if (SPARKLES) {
|
|
|
|
// старая версия для яркости
|
|
if (getPixColorXY(x, y - 1) > 0)
|
|
drawPixelXY(x, y, getPixColorXY(x, y - 1));
|
|
else drawPixelXY(x, y, 0);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
//first row interpolates with the "next" line
|
|
for (unsigned char x = 0; x < WIDTH; x++) {
|
|
uint8_t newX = x;
|
|
if (x > 15) newX = x - 15;
|
|
CRGB color = CHSV(
|
|
modes[1].scale * 2.5 + pgm_read_byte(&(hueMask[0][newX])), // H
|
|
255, // S
|
|
(uint8_t)(((100.0 - pcnt) * matrixValue[0][newX] + pcnt * line[newX]) / 100.0) // V
|
|
);
|
|
leds[getPixelNumber(newX, 0)] = color;
|
|
}
|
|
}
|
|
|
|
byte hue;
|
|
// ---------------------------------------- радуга ------------------------------------------
|
|
void rainbowVertical() {
|
|
hue += 2;
|
|
for (byte j = 0; j < HEIGHT; j++) {
|
|
CHSV thisColor = CHSV((byte)(hue + j * modes[2].scale), 255, 255);
|
|
for (byte i = 0; i < WIDTH; i++)
|
|
drawPixelXY(i, j, thisColor);
|
|
}
|
|
}
|
|
void rainbowHorizontal() {
|
|
hue += 2;
|
|
for (byte i = 0; i < WIDTH; i++) {
|
|
CHSV thisColor = CHSV((byte)(hue + i * modes[3].scale), 255, 255);
|
|
for (byte j = 0; j < HEIGHT; j++)
|
|
drawPixelXY(i, j, thisColor); //leds[getPixelNumber(i, j)] = thisColor;
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------- ЦВЕТА ------------------------------------------
|
|
void colorsRoutine() {
|
|
hue += modes[4].scale;
|
|
for (int i = 0; i < NUM_LEDS; i++) {
|
|
leds[i] = CHSV(hue, 255, 255);
|
|
}
|
|
}
|