24#if SKETCH_HAS_LARGE_MEMORY
50fl::UISlider triggerSpeed(
"Trigger Speed", .5f, 0.0f, 1.0f, 0.01f);
53fl::UISlider blurAmount(
"Global Blur Amount", 0, 0, 172, 1);
54fl::UISlider blurPasses(
"Global Blur Passes", 1, 1, 10, 1);
60fl::UISlider speedUpper(
"Wave Upper: Speed", 0.12f, 0.0f, 1.0f);
61fl::UISlider dampeningUpper(
"Wave Upper: Dampening", 8.9f, 0.0f, 20.0f, 0.1f);
63fl::UISlider blurAmountUpper(
"Wave Upper: Blur Amount", 95, 0, 172, 1);
64fl::UISlider blurPassesUpper(
"Wave Upper: Blur Passes", 1, 1, 10, 1);
65fl::UICheckbox isotropicStencilUpper(
"Wave Upper: Isotropic stencil (rounder ripples)",
false);
68fl::UISlider speedLower(
"Wave Lower: Speed", 0.26f, 0.0f, 1.0f);
69fl::UISlider dampeningLower(
"Wave Lower: Dampening", 9.0f, 0.0f, 20.0f, 0.1f);
71fl::UISlider blurAmountLower(
"Wave Lower: Blur Amount", 0, 0, 172, 1);
72fl::UISlider blurPassesLower(
"Wave Lower: Blur Passes", 1, 1, 10, 1);
73fl::UICheckbox isotropicStencilLower(
"Wave Lower: Isotropic stencil (rounder ripples)",
false);
77fl::UISlider fancyIntensity(
"Fancy Intensity", 32, 1, 255, 1);
78fl::UISlider fancyParticleSpan(
"Fancy Particle Span", 0.06f, 0.01f, 0.2f, 0.01f);
81UIHelp changeGridHelp(
"Use Change fl::Grid preserves the set point over multiple iterations to ensure more stable results across simulation resolutions. However, turning it off may result in more dramatic effects and saves memory.");
166 int x = random(min_x, max_x);
167 int y = random(min_y, max_y);
171 waveFxLower.setf(
x,
y, 1);
172 waveFxUpper.setf(
x,
y, 1);
176void applyFancyEffect(uint32_t now,
bool button_active) {
180 map(fancySpeed.as<uint32_t>(), 0, fancySpeed.getMax(), 1000, 100);
192 if (!pointTransition.
isActive(now)) {
198 int mid_x =
WIDTH / 2;
202 int amount =
WIDTH / 2;
205 int start_x = mid_x - amount;
206 int end_x = mid_x + amount;
207 int start_y = mid_y - amount;
208 int end_y = mid_y + amount;
211 int curr_alpha = pointTransition.
update8(now);
215 int left_x =
map(curr_alpha, 0, 255, mid_x, start_x);
216 int down_y =
map(curr_alpha, 0, 255, mid_y, start_y);
217 int right_x =
map(curr_alpha, 0, 255, mid_x, end_x);
218 int up_y =
map(curr_alpha, 0, 255, mid_y, end_y);
221 float curr_alpha_f = curr_alpha / 255.0f;
225 float valuef = (1.0f - curr_alpha_f) * fancyIntensity.value() / 255.0f;
228 int span = fancyParticleSpan.value() *
WIDTH;
234 for (
int x = left_x - span;
x < left_x + span;
x++) {
235 waveFxLower.addf(
x, mid_y, valuef);
236 waveFxUpper.addf(
x, mid_y, valuef);
240 for (
int x = right_x - span;
x < right_x + span;
x++) {
241 waveFxLower.addf(
x, mid_y, valuef);
242 waveFxUpper.addf(
x, mid_y, valuef);
246 for (
int y = down_y - span;
y < down_y + span;
y++) {
247 waveFxLower.addf(mid_x,
y, valuef);
248 waveFxUpper.addf(mid_x,
y, valuef);
252 for (
int y = up_y - span;
y < up_y + span;
y++) {
253 waveFxLower.addf(mid_x,
y, valuef);
254 waveFxUpper.addf(mid_x,
y, valuef);
261 bool bigButton =
false;
275 waveFxLower.setSpeed(speedLower);
276 waveFxLower.setDampening(dampeningLower);
277 waveFxLower.setHalfDuplex(halfDuplexLower);
281 waveFxLower.setStencil(isotropicStencilLower
284 waveFxLower.setEasingMode(easeMode);
285 waveFxLower.setUseChangeGrid(useChangeGrid);
288 waveFxUpper.setSpeed(speedUpper);
289 waveFxUpper.setDampening(dampeningUpper);
290 waveFxUpper.setHalfDuplex(halfDuplexUpper);
292 waveFxUpper.setStencil(isotropicStencilUpper
295 waveFxUpper.setEasingMode(easeMode);
296 waveFxUpper.setUseChangeGrid(useChangeGrid);
299 fxBlend.setGlobalBlurAmount(blurAmount);
300 fxBlend.setGlobalBlurPasses(blurPasses);
312 fxBlend.setParams(waveFxLower, lower_params);
313 fxBlend.setParams(waveFxUpper, upper_params);
318 state.bigButton = buttonFancy;
323void processAutoTrigger(uint32_t now) {
328 uint32_t trigger_delta = nextTrigger - now;
331 if (trigger_delta > 10000) {
339 if (now >= nextTrigger) {
345 float speed = 1.0f - triggerSpeed.value();
362 nextTrigger = now + random(
min,
max);
380 title.setGroup(
"Main Controls");
382 button.setGroup(
"Main Controls");
383 buttonFancy.setGroup(
"Main Controls");
385 triggerSpeed.setGroup(
"Main Controls");
389 easeModeSqrt.setGroup(
"Global Settings");
390 useChangeGrid.setGroup(
"Global Settings");
391 blurAmount.setGroup(
"Global Settings");
392 blurPasses.setGroup(
"Global Settings");
396 speedUpper.setGroup(
"Upper Wave Layer");
397 dampeningUpper.setGroup(
"Upper Wave Layer");
398 halfDuplexUpper.setGroup(
"Upper Wave Layer");
399 blurAmountUpper.setGroup(
"Upper Wave Layer");
400 blurPassesUpper.setGroup(
"Upper Wave Layer");
401 isotropicStencilUpper.setGroup(
"Upper Wave Layer");
404 speedLower.setGroup(
"Lower Wave Layer");
405 dampeningLower.setGroup(
"Lower Wave Layer");
406 halfDuplexLower.setGroup(
"Lower Wave Layer");
407 blurAmountLower.setGroup(
"Lower Wave Layer");
408 blurPassesLower.setGroup(
"Lower Wave Layer");
409 isotropicStencilLower.setGroup(
"Lower Wave Layer");
412 fancySpeed.setGroup(
"Fancy Effects");
413 fancyIntensity.setGroup(
"Fancy Effects");
414 fancyParticleSpan.setGroup(
"Fancy Effects");
418 fxBlend.add(waveFxLower);
419 fxBlend.add(waveFxUpper);
430 waveFxLower.setXCylindrical(
xCyclical.value());
441 applyFancyEffect(now,
state.bigButton);
444 processAutoTrigger(now);
fl::UIDescription description("Demo of the Animatrix effects. @author of fx is StefanPetrick")
fl::UITitle title("Animartrix")
fl::WaveFx::Args CreateArgsUpper()
fl::WaveFx::Args CreateArgsLower()
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
Memory functions are available in fl:: namespace via fl/stl/cstring.h Using declarations cannot work ...
constexpr common_type_t< T, U > max(T a, U b) FL_NOEXCEPT
fl::UICheckbox autoTrigger("Auto Trigger", true)
fl::UICheckbox xCyclical("X Is Cyclical", true)
::fl::DrawContext DrawContext
u8 update8(u32 now) FL_NOEXCEPT override
Compute current 0–255 output based on how much time has elapsed since trigger().
bool isActive(u32 now) const FL_NOEXCEPT override
void trigger(u32 now) FL_NOEXCEPT override
Call this when you want to (re)start the ramp cycle.
2D wave simulation effect with supersampling and gradient coloring
#define DEFINE_GRADIENT_PALETTE(X)
fl::UISlider superSample("SuperSampleExponent", 0.f, 0.f, 3.f, 1.f)
void triggerRipple(fl::WaveSimulation1D &waveSim, int x)
fl::SuperSample getSuperSample()
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NOEXCEPT
constexpr common_type_t< T, U > max(T a, U b) FL_NOEXCEPT
MapRedBlackTree< Key, T, Compare, fl::allocator_slab< char > > map
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
fl::UIButton button("Button")
2D wave simulation effect for LED matrices
Representation of an 8-bit RGB pixel (Red, Green, Blue)
float speed
Wave propagation speed (0.0-1.0, typical: 0.1-0.3)
WaveCrgbMapPtr crgbMap
Custom color mapper (nullptr uses default grayscale)
bool auto_updates
If true, simulation advances automatically in draw()
SuperSample factor
Supersampling quality (SUPER_SAMPLE_2X recommended for balance)
float dampening
Energy dampening factor (higher = faster decay, typical: 3-10)
bool half_duplex
If true, constrains waves to positive values only.
Aggregator header for the fl/ui/ family of per-element UI types.