EEffects

Flutter package providing a variety of effects:

  • Point Lights
  • Light Beams
  • Fire
  • Lightning bolts

Documentation is below Examples

Examples

Simple example how this package can light up your app/website

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  EScene? scene;

  MyApp() {
    scene = EScene(
      width: 0,
      height: 0,
      effects: [
        ERadialLight(
            ERelativePos(0.3, 0.1),
            ERelative(100, ERelative.absolute),
            EGradient([
              EColorShift([Color.fromARGB(150, 255, 255, 255)], 0)
            ]),
            0,
            0,
            ERelative(30, ERelative.absolute),
            ERelative(2, ERelative.absolute),
            0.1,
            1),
        ELightBeam(
            ERelativePos(0.5, 0.5),
            EVector2D(1, 0),
            ERelative(0.6, ERelative.widthAndHeightRelative),
            ERelative(10, ERelative.absolute),
            ERelative(0, ERelative.absolute),
            EGradient([
              EColorShift([Color.fromARGB(150, 255, 255, 255)], 0),
            ]),
            1,
            0,
            ERelative(100, ERelative.absolute),
            ERelative(2, ERelative.absolute),
            0.1,
            1,
            name: "Example Beam")
      ],
      darkness: EColorShift([Color.fromARGB(255, 0, 0, 0)], 0),
      afterUpdate: () {
        EEffect effect = scene!.getEffect("Example Beam")!;
        if (effect is ELightBeam) {
          ELightBeam ourLightBeam = effect;
          //equivalent to mousePos - ourLightBeam.direction
          EVector2D newDirection = mousePos.getAdd(ourLightBeam.position
              .getAbsolutePair(Size(scene!.width, scene!.height))
              .getMultiply(-1));
          ourLightBeam.direction = newDirection;
        }
      },
      beforeUpdate: () {},
    );
  }

  EVector2D mousePos = EVector2D(0, 0);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(body: LayoutBuilder(builder: (context, size) {
      scene!.resize(size.biggest.width, size.biggest.height);
      return MouseRegion(
        child: Stack(
          children: [
            Container(
              width: 600,
              height: 100,
              color: Colors.pink,
            ),
            Positioned(
                width: 200,
                height: 200,
                top: 800,
                left: 100,
                child: Container(
                  color: Colors.red,
                )),
            Positioned(
                width: 400,
                height: 400,
                top: 800,
                left: 800,
                child: Container(
                  color: Colors.blue,
                )),
            Positioned(
                width: 300,
                height: 300,
                top: 200,
                left: 1700,
                child: Container(color: Colors.black)),
            Container(
              child: scene,
            )
          ],
        ),
        onHover: (PointerHoverEvent pointerHoverEvent) {
          mousePos = EVector2D(
              pointerHoverEvent.position.dx, pointerHoverEvent.position.dy);
        },
      );
    })));
  }
}

Make a Light Beam that follows your mouse and changes colors

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  EScene? scene;

  MyApp() {
    scene = EScene(
      width: 0,
      height: 0,
      effects: [
        ELightBeam(
            ERelativePos(0.5, 0.5),
            EVector2D(1, 0),
            ERelative(0.5, ERelative.widthAndHeightRelative),
            ERelative(10, ERelative.absolute),
            ERelative(0, ERelative.absolute),
            EGradient([
              EColorShift([Colors.red, Colors.blue], 0.01),
              EColorShift([Colors.blue, Colors.red], 0.01)
            ]),
            1,
            0,
            ERelative(100, ERelative.absolute),
            ERelative(2, ERelative.absolute),
            0.1,
            1,
            name: "Example Beam")
      ],
      darkness: EColorShift([Color.fromARGB(255, 0, 0, 0)], 0),
      afterUpdate: () {
        EEffect effect = scene!.getEffect("Example Beam")!;
        if (effect is ELightBeam) {
          ELightBeam ourLightBeam = effect;
          //equivalent to mousePos - ourLightBeam.direction
          EVector2D newDirection = mousePos.getAdd(ourLightBeam.position
              .getAbsolutePair(Size(scene!.width, scene!.height))
              .getMultiply(-1));
          ourLightBeam.direction = newDirection;
        }
      },
      beforeUpdate: () {},
    );
  }

  EVector2D mousePos = EVector2D(0, 0);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(body: LayoutBuilder(builder: (context, size) {
      scene!.resize(size.biggest.width, size.biggest.height);
      return MouseRegion(
        child: scene,
        onHover: (PointerHoverEvent pointerHoverEvent) {
          mousePos = EVector2D(
              pointerHoverEvent.position.dx, pointerHoverEvent.position.dy);
        },
      );
    })));
  }
}

A Flame

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  EScene? scene;

  MyApp() {
    scene = EScene(
      width: 0,
      height: 0,
      effects: [
        EFire(
            EGradient([
              EColorShift([Colors.red], 0),
              EColorShift([Colors.orange.shade800], 0),
              EColorShift([Colors.orange.shade600], 0)
            ]),
            EGradient([
              EColorShift([Color.fromARGB(10, 100, 100, 100)], 0)
            ]),
            EGradient([
              EColorShift([Color.fromARGB(20, 140, 100, 60)], 0),
              EColorShift([Color.fromARGB(10, 140, 100, 60)], 0)
            ]),
            1,
            0,
            ERelativePos(0.5, 0.5),
            EVector2D(0, -1),
            ERelative(30, ERelative.absolute),
            ERelative(40, ERelative.absolute),
            ERelative(2, ERelative.absolute),
            ERelative(40, ERelative.absolute),
            ERelative(150, ERelative.absolute),
            ERelative(8, ERelative.absolute)),
      ],
      darkness: EColorShift([Color.fromARGB(255, 0, 0, 0)], 0),
      afterUpdate: () {},
      beforeUpdate: () {},
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(body: LayoutBuilder(builder: (context, size) {
      scene!.resize(size.biggest.width, size.biggest.height);
      return Container(
        child: scene,
      );
    })));
  }
}

Or make a lightning that strikes where you click
note that the number of points is very high
you might experience lag on a slow device
just turn that number a little bit down and you should be fine

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  EScene? scene;

  MyApp() {
    scene = EScene(
      width: 0,
      height: 0,
      effects: [
        ELightning(
            ERelativePos(0.5, 0),
            0.02,
            ERelative(1, ERelative.absolute),
            ERelative(20, ERelative.absolute),
            ERelative(600, ERelative.absolute),
            50,
            5,
            EColorShift([Color.fromARGB(255, 80, 0, 255)], 0),
            true,
            8,
            1,
            name: "Example Lightning"),
      ],
      darkness: EColorShift([Color.fromARGB(255, 0, 0, 0)], 0),
      afterUpdate: () {},
      beforeUpdate: () {},
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(body: LayoutBuilder(builder: (context, size) {
      scene!.resize(size.biggest.width, size.biggest.height);
      return GestureDetector(
        child: scene,
        onTapDown: (TapDownDetails tapDownDetails) {
          EEffect effect = scene!.getEffect("Example Lightning")!;
          if (effect is ELightning) {
            ELightning ourLightning = effect;
            ourLightning.buildLightningOnNextTickATTarget(ERelativePair(
                ERelative(tapDownDetails.globalPosition.dx, ERelative.absolute),
                ERelative(
                    tapDownDetails.globalPosition.dy, ERelative.absolute)));

            ourLightning.fireLightningIn(1);
          }
        },
      );
    })));
  }
}

Documentation

EVector2D

Implementation of simple 2D vectors.

Constructors:

  • EVector2D(double x, double y)

Variables:

  • x
  • y

Methods:

  • norm() -> void
    sets the length of the vector to 1
  • add(EVector2D vct) -> void
    adds another vector to this one by adding their values
  • getAdd(EVector2D vct) -> EVector2D
    returns an EVector2D containing the values of this vector after adding vct
  • multiply(double value) -> void
    multiplies this vector by multiplying x and y with value
  • getMultiply(double value) -> EVector2D
    returns an EVector2D containing the values of this vector multiplied with value
  • rotate(double angle) -> void
    rotates the vector by the given angle in degrees
  • getRotate(double angle) -> EVector2D
    returns an EVector2D that is equivalent to this one but rotated by the given angle in degrees
  • getLength() -> double
    returns the length of this vector
  • getAngle(EVector2D vct) -> double
    returns the angle between this vector and vct in radians
  • setLength(double value) -> void
    set the length of this vector to value
  • getOffset() -> Offset
    returns the offset containing the values of the vector

ERelative

holds a value that is relative to the length of an EVector2D represented by an angle: relativeDependent length of this EVector2D is the maximum length that this vector can have while still being within the scene an angle of 0 is represented as EVector2D(1,0) => relative to width

Constructors:

  • ERelative(double relative, double relativeDependent)
    relativeDependent can be any value bigger than 0 and smaller than 179 or -1
    if relativeDependent is bigger than 0 and smaller than 179, relative is relative to the EVector2D represented by this angle
    an angle of 90 represents the EVector2D(0,1) and the value is relative to the height
    if relativeDependent is -1, relative is absolute and getAbsoluteValue will just return relative
    so if relativeDependent is 90 and relative is 0.5, the absolute value will be half the height

Variables:

  • relative
  • relativeDependent

Pre-defined Values:

  • ERelative.widthRelative = 0
  • ERelative.heightRelative = 90
  • ERelative.widthAndHeightRelative = 45
  • ERelative.absolute = -1

Methods:

  • getAbsoluteValue(Size size) -> double
    returns the absolute value

ERelativePair

Contains 2 ERelative

Constructors:

  • ERelativePair(ERelative firstRelative, ERelative secondRelative)

Variables:

  • ERelative firstRelative
  • ERelative secondRelative

Methods:

  • set setFirstRelativeValue(double value)
    sets the relative of firstRelative
  • get getFirstRelativeValue -> double
    returns the relative of firstRelative
  • set setSecondRelativeValue(double value)
    sets the relative of secondRelative
  • get getSecondRelativeValue -> double
    returns the relative of secondRelative
  • getAbsolutePair(Size size) -> EVector2D
    returns the absolutes of the two ERelatives stored in an EVector2D

ERelativePos

Subclass of ERelativePair
relativeDependent of first ERelative is set to ERelative.widthRelative
relativeDependent of second ERelative is set to ERelative.heightRelative
=>first value is always relative to width and second to height
=>positional relative

Constructors:

  • ERelativePos(double firstRelativeValue, double secondRelativeValue)

EColorShift

List of colors where the current color changes
current color moves linear from one color to the one that follows in the list
if last color is reached next color is the one in the beginning
with a shiftSpeed of 1, the current Color jumps in 1 tick from one color to the next one

Constructors:

  • EColorShift(List

Variables:

  • List
  • double shiftSpeed
  • double currentShift
  • Color currentColor

Methods:

  • update(double deltaTime) -> void
    updates all values
  • buildColor() -> void
    assigns the current Color to currentColor
  • getCurrentColor -> Color
    returns currentColor

EGradient

Custom gradient with ColorShifts instead of colors
can return a RadialGradient or a LinearGradient

Constructors:

  • EGradient(List

Variables:

  • List

Methods:

  • update(double deltaTime) -> void
    updates the EGradient
  • getRadialGradient() -> RadialGradient
    returns a RadialGradient
  • getLinearGradient(Alignment begin, Alignment end) -> LinearGradient
    returns a LinearGradient

EEffect

Constructors:

  • EEffect(double isDrawable, double updateFromScene, {String name = ""})

Variables:

  • String name
    name of the EEffect
  • bool isToggled = false
    if Effect is toggled it won't be drawn

Methods:

  • update(double deltaTime, Size size) -> void
  • draw(Canvas canvas, Size size) -> void
  • drawEffect(Canvas canvas, Size size) -> void
  • drawLight(Canvas canvas, Size size) -> void
  • toggle() -> void
    changes isToggled

ELight

Subclass of EEffect

Constructors:

  • ELight (double flickerOn, double flickerOff, ERelative blur,
    ERelative blurPulseRange,double blurPulseSpeed,{String name = ""})

Variables:

  • ERelative blur
    blur value
  • double _currentBlur = 0
  • double _newBlur = 0
    new blur value that currentBlur will change to
  • ERelative blurPulseRange
    currentBlur will change linear to random values
    within blur-blurPulseRange,blur+blurPulseRange
  • double blurPulseSpeed
    value between 0 and 1. If blurPulseSpeed is one, currentBlur
    will change in one tick to newBlur
  • double flickerOn
    chance that light will turn on when off. Value between 0 and 1. 1 is equal to 100% and 0 to 0%
  • double flickerOff
    chance that light will turn off when on. Value between 0 and 1. 1 is equal to 100% and 0 to 0%

Methods:

  • get currentBlur() -> double
    returns the current blur
  • update(double deltaTime, Size size) -> void

ERadialLight

Simple point light. Subclass of ELight

Constructors:

  • ERadialLight(ERelativePair position, ERelative radius, EGradient gradient,
    double flickerOn, double flickerOff, ERelative blur,
    ERelative blurPulseRange, double blurPulseSpeed, int repainter,
    {String name = ""})

Variables:

  • ERelativePair position
  • ERelative radius
  • EGradient gradient
  • int repainter
    how often the light will be painted

ELightBeam

Constructors:

  • ELightBeam(ERelativePair position, EVector2D direction, ERelative length,
    ERelative angle, ERelative startPositionDist, EGradient gradient,
    double flickerOn, double flickerOff, ERelative blur,
    ERelative blurPulseRange, double blurPulseSpeed, int repainter,
    {String name = ""})

Variables:

  • ERelativePair position
  • EVector2D direction
  • ERelative length
  • ERelative angle
  • EGradient gradient
  • ERelative startPositionDist
    how wide the light beam is at the start position position
  • int repainter
    how often the light will be painted

EFire

Subclass of EEffect

Constructors:

  • EFire( EGradient fireGradient, EGradient smokeGradient, EGradient lightGradient,
    int fireParticlesPerTick, int smokeParticlesPerTick, ERelativePair startPoint,
    EVector2D flameDirection, ERelative scatteringAngle, ERelative startSize,
    ERelative decreaseSize, ERelative glow, ERelative lightRadius,
    ERelative particleSpeed, {String name = ""})

Variables:

  • EGradient fireGradient
  • EGradient smokeGradient
  • EGradient lightGradient
  • int fireParticlesPerTick
    fire particles that spawn per tick
  • int smokeParticlesPerTick
    smoke particles that spawn per tick
  • ERelativePair startPoint
  • EVector2D flameDirection
  • ERelative scatteringAngle
    max difference bewtween particleDirection and flameDirection
  • ERelative startSize
    start size of particles
  • ERelative decreaseSize
    value that particles shrink per tick
  • ERelative particleSpeed
  • ERelative glow
  • ERelative lightRadius

ELightning

Subclass of EEffect

Constructors:

  • ELightning( ERelativePair position, double spread, ERelative glow,
    ERelative width, ERelative curve, int numberOfPoints,
    double buildingTimeInTicks, EColorShift color, bool throwsLight,
    double lightningBlur, int repainter, {String name = ""})

Variables:

  • ERelativePair position
  • double spread
    value between 0 and 1. Chance that a sub lightning will appear on a point
    values below 0.08 are recommended
  • ERelative glow
  • ERelative width
    width of the lightning
  • ERelative curve
    curve value of the lightning
    this is the max width that the whole lightning can have
    for a lot of points absolute values above 400 are recommended
  • int numberOfPoints
    number of points the lightning will have
    more points results in a better look but also in less fps
  • double buildingTimeInTicks
    time that the lightning will take to build itself from position to its destination
    it will take the same time to erase itself
  • EColorShift color
  • bool throwsLight
  • double lightningBlur
  • int repainter
    how often the lightning should be painted

Methods:

  • buildLightningOnNextTickATTarget(ERelativePair targetPosition) -> void
    will build the lightning bold and make all the preparation for drawing it
  • fireLightningIn(double ticks) -> void
    will actually make the lightning appear in ticks ticks
    if you call fireLightningIn(1) the lightning will appear on the next tick
    if you call fireLightningIn(0) nothing will happen

EScene

Constructors:

  • EScene({ required double width, required double height, EColorShift? _darkness,
    List

Variables:

  • double _width = 0
  • double _height = 0
  • EColorShift _darkness = EColorShift(Color.fromARGB(0, 0, 0, 0), 0)
    color that the are with no light will have

Methods:

  • get width -> double
    returns width
  • get height > double
    returns height
  • **set darkness(EColorShift value)
    sets darkness
  • getEffect(String name) -> EEffect?
    returns Effect with the name name
  • addEffect(EEffect eEffect) -> void
  • addEffects(List
  • removeEffect(String name) -> void
  • resize(double width, double height) -> void
    resizes the scene