Pen Settings

JavaScript

Babel includes JSX processing.

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

Flutter

              
                /*
  COPYRIGHT 2020. @ishandeveloper
  
  YOU CAN FIND THE REFACTORED CODE AT https://github.com/ishandeveloper/WinAMP_Flutter
  
  LISTEN TO ACTUAL MUSIC IN THE DEMO AT :
  
  https://winamp.ishandeveloper.com
*/
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:ui';

bool mono = false;
double seekTime = 0;
String currentTrack = "No Track Selected";
String trackMin = "00";
String trackSec = "00";

int trackMinint = 0;
int trackSecint = 0;

void main() {
  runApp(
    MaterialApp(
      title: 'Ishan Sharma',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        scaffoldBackgroundColor: Colors.black,
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Player(),
    ),
  );
}

class Player extends StatefulWidget {
  @override
  _PlayerState createState() => _PlayerState();
}

class _PlayerState extends State<Player> {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        if (constraints.maxWidth > 768) {
          return DesktopUI();
        }
        return MobileUI();
      },
    );
  }
}

class DesktopUI extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xff020088),
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        decoration: BoxDecoration(
          image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/xp.jpg?raw=false'),
            fit: BoxFit.cover,
          ),
        ),
        child: Center(
          child: Container(
            width: 780,
            height: 350,
            decoration: BoxDecoration(color: Colors.black, boxShadow: [
              BoxShadow(blurRadius: 5, color: Colors.black, spreadRadius: 1)
            ]),
            child: Column(
              children: [
                DesktopNavbar(),
                DesktopMain(),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// DESKTOP NAVBAR

class DesktopNavbar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 5, horizontal: 10),
      child: Row(
        children: [
          WinLogo(),
          SizedBox(width: 10),
          Row(
            children: [
              NavLine(),
              SizedBox(width: 10),
              Text(
                "WINAMP",
                style: TextStyle(
                  color: Colors.white,
                  fontFamily: 'Pixer',
                  fontSize: 18,
                ),
              ),
              SizedBox(width: 10),
              NavLine(),
              SizedBox(width: 10),
              Padding(
                padding: const EdgeInsets.all(0.0),
                child: Container(
                  width: 18,
                  height: 18,
                  decoration: BoxDecoration(
                      image: DecorationImage(
                    image: NetworkImage(
                      'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/btn1.png?raw=false',
                    ),
                    fit: BoxFit.cover,
                  )),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(0.0),
                child: Container(
                  width: 18,
                  height: 18,
                  decoration: BoxDecoration(
                      // color: Colors.white,
                      image: DecorationImage(
                    image: NetworkImage(
                      'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/btn1.png?raw=false',
                    ),
                    fit: BoxFit.cover,
                  )),
                ),
              )
            ],
          )
        ],
      ),
    );
  }
}

class DesktopMain extends StatefulWidget {
  @override
  _DesktopMainState createState() => _DesktopMainState();
}

class _DesktopMainState extends State<DesktopMain> {
  bool paused = true;
  bool initial = true;

  @override
  Widget build(BuildContext context) {
    void stopMusic() {
      setState(() {
        paused = true;
        currentTrack = "No Track Selected";
      });
    }

    void trackTime() {
      setState(() {
        // ignore: division_optimization
        trackMinint = (seekTime / 60).toInt();
        trackSecint = (seekTime - (trackMinint * 60)).toInt();
      });

      if (trackSecint < 10) {
        setState(() {
          trackSec = "0" + trackSecint.toString();
        });
      } else {
        setState(() {
          trackSec = trackSecint.toString();
        });
      }

      setState(() {
        trackMin = "0" + trackMinint.toString();
      });

      if (trackMin == "04" && trackSec == "59") {
        setState(() {
          seekTime = 0;
          trackMinint = 0;
          trackSecint = 0;
          trackMin = "00";
          trackSec = "00";
        });
        stopMusic();
      }
    }

    void seeker() async {
      Timer.periodic(Duration(milliseconds: 1000), (timer) {
        if (!paused) {
          setState(() {
            seekTime += 1;
          });
          trackTime();
        } else {
          // dispose();
        }
      });
    }

    void playMusic() async {
      if (paused) {
        // playAudio('assets/music.mp3');
        setState(() {
          paused = false;
          // initial=false;
          currentTrack = "Silent - DEMO Track (*JavaScript Required)";
        });
        if (initial) {
          setState(() {
            initial = false;
            seekTime = 0;
          });
          seeker();
        }
      }
    }

    void seekMusic(double position) {
      int time = position.toInt();

      setState(() {
        trackSecint = time;
        seekTime = position;
      });
      trackTime();
    }

    void pauseMusic() {
      setState(() {
        paused = true;
        currentTrack = "PAUSED - Silent - DEMO Track (*JavaScript Required)";
      });
    }

    return Container(
      width: 770,
      height: 300,
      decoration: BoxDecoration(
        border: Border.all(color: Color(0xFF555569), width: 2.0),
        gradient: LinearGradient(
          begin: Alignment.centerLeft,
          end: Alignment(0.8, 0.0),
          colors: [
            Color(0xFF212132),
            Color(0XFF353454),
            Color(0xFF474766),
          ],
          tileMode: TileMode.repeated,
        ),
      ),
      child: Padding(
        padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            /* TOP CONTROLS */
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Transform.scale(
                    scale: 1,
                    child: MainInfoWidget(
                        minutes: trackMin,
                        seconds: trackSec,
                        playing: !paused)),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    TrackNameBar(currentTrack),
                    SizedBox(height: 15),
                    Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        MiniControls(
                            units: "kbps",
                            initialValue: 160,
                            min: 98,
                            max: 320),
                        MiniControls(
                          units: "dB",
                          initialValue: 50,
                          min: 0,
                          max: 100,
                          control: (double level) {
                            // setAudioVolume(level);
                          },
                        ),
                        MiniControls(
                            units: "kHz", initialValue: 44, min: 32, max: 98),
                        Row(
                          children: [
                            Column(
                              children: [
                                ControlLabel(
                                    text: "mono",
                                    enabled: mono,
                                    onPress: () {
                                      setState(() {
                                        mono = true;
                                      });
                                    }),
                                SizedBox(height: 15),
                                MiniButton(light: Colors.yellow, text: "EQ"),
                              ],
                            ),
                            SizedBox(width: 10),
                            Column(
                              children: [
                                ControlLabel(
                                    text: "stereo",
                                    enabled: !mono,
                                    onPress: () => setState(() {
                                          mono = false;
                                        })),
                                SizedBox(height: 15),
                                MiniButton(light: Colors.red, text: "PL"),
                              ],
                            )
                          ],
                        )
                      ],
                    ),
                  ],
                )
              ],
            ),
            SizedBox(height: 15),
            SeekBar(
              min: 0,
              max: 300, // Time in seconds,
              value: seekTime,
              seek: (val) {
                print("SEEKED" + val.toString());
                seekMusic(val);
              },
            ),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Row(
                  children: [
                    RetroButton(
                        onPress: () {
                          seekMusic(0);
                        },
                        icon: Icons.fast_rewind),
                    SizedBox(width: 5),
                    RetroButton(
                        onPress: () => playMusic(), icon: Icons.play_arrow),
                    SizedBox(width: 5),
                    RetroButton(onPress: () => pauseMusic(), icon: Icons.pause),
                    SizedBox(width: 5),
                    RetroButton(
                        onPress: () {
                          stopMusic();
                          this.initState();
                        },
                        icon: Icons.stop),
                    SizedBox(width: 5),
                    RetroButton(onPress: () {}, icon: Icons.fast_forward),
                    SizedBox(width: 10),
                    RetroButton(onPress: () {}, icon: Icons.eject),
                  ],
                ),
                Row(
                  children: [
                    TextControlButton(text: "Shuffle", light: Colors.red),
                    SizedBox(width: 10),
                    TextControlButton(
                        icon: true,
                        ico: Icons.repeat,
                        light: Colors.yellow,
                        width: 40)
                  ],
                )
              ],
            )
          ],
        ),
      ),
    );
  }
}

class TextControlButton extends StatefulWidget {
  final Color light;
  final String text;
  final bool selected;
  final bool icon;
  final double width;
  final IconData ico;

  TextControlButton(
      {this.light,
      this.text,
      this.selected = false,
      this.icon = false,
      this.width = 60,
      this.ico});

  @override
  _TextControlButtonState createState() => _TextControlButtonState();
}

class _TextControlButtonState extends State<TextControlButton> {
  bool enabled;
  @override
  void initState() {
    enabled = widget.selected;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          enabled = !enabled;
        });
      },
      child: Container(
        width: widget.width,
        height: 30,
        decoration: BoxDecoration(
            color: enabled ? Color(0xFFBDCED6) : Color(0xFFBDCED6),
            border: Border(
              top: BorderSide(
                  width: 1,
                  color: enabled ? Color(0xFF000000) : Color(0xFFFFFFFF)),
              left: BorderSide(
                  width: 1,
                  color: enabled ? Color(0xFF000000) : Color(0xFFFFFFFF)),
              right: BorderSide(
                  width: 2,
                  color: enabled ? Color(0xFFFFFFFF) : Color(0xFF000000)),
              bottom: BorderSide(
                  width: 2,
                  color: enabled ? Color(0xFFFFFFFF) : Color(0xFF000000)),
            )),
        child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
          Container(
            height: 10,
            width: 10,
            decoration: BoxDecoration(
                color: widget.light,
                border: Border.all(color: Color(0xFF000000), width: 1)),
          ),
          widget.icon
              ? Icon(
                  widget.ico,
                  size: 18,
                  color: Colors.black,
                )
              : Text(
                  widget.text,
                  style: TextStyle(
                      fontFamily: 'Pixer', color: Colors.black, fontSize: 14),
                ),
        ]),
      ),
    );
  }
}

class SeekBar extends StatelessWidget {
  final Function seek;
  final double min;
  final double max;
  final double value;
  SeekBar({this.seek, this.min, this.max, this.value});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      mainAxisSize: MainAxisSize.max,
      children: [
        Container(
          // decoration: BoxDecoration(color: Color(0xff1B1932)),
          child: CustomSlider(
            value: value,
            min: min,
            max: max,
            thumbSize: 34.0,
            sliderWidth: 720.0,
            thumbColor: Colors.yellow,
            roundedRectangleThumbRadius: 0.0,
            topLeftShadow: false,
            bottomRightShadow: true,
            bottomRightShadowBlur: MaskFilter.blur(BlurStyle.outer, 3),
            bottomRightShadowColor: Colors.black,
            activeLineStroke: 2.0,
            activeLineColor: Color(0xff1B1932),
            inactiveLineColor: Color(0xff1B1932),
            child: Padding(
              padding: EdgeInsets.all(2.0),
              child: Center(
                  child: Text(
                '──',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 18.0,
                  fontFamily: 'Pixer',
                  fontWeight: FontWeight.bold,
                ),
              )),
            ),
            onChanged: (double val) {
              seek(val);
            },
          ),
        ),
      ],
    );
  }
}

class RetroButton extends StatefulWidget {
  final IconData icon;
  final Function onPress;
  final double width;
  final double height;
  RetroButton({this.icon, this.onPress, this.width = 50, this.height = 30});

  @override
  _RetroButtonState createState() => _RetroButtonState();
}

class _RetroButtonState extends State<RetroButton> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: widget.onPress,
      child: Container(
        width: widget.width,
        height: widget.height,
        decoration: BoxDecoration(
            color: Color(0xFFBDCED6),
            border: Border(
              top: BorderSide(width: 1, color: Color(0xFFFFFFFF)),
              left: BorderSide(width: 1, color: Color(0xFFFFFFFF)),
              right: BorderSide(width: 2, color: Color(0xFF000000)),
              bottom: BorderSide(width: 2, color: Color(0xFF000000)),
            )),
        child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
          Icon(
            widget.icon,
            size: 24,
            color: Color(0xff687582),
          ),
        ]),
      ),
    );
  }
}

class MiniButton extends StatefulWidget {
  final Color light;
  final String text;
  final bool selected;

  MiniButton({this.light, this.text, this.selected = false});

  @override
  _MiniButtonState createState() => _MiniButtonState();
}

class _MiniButtonState extends State<MiniButton> {
  bool enabled;
  @override
  void initState() {
    enabled = widget.selected;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          enabled = !enabled;
        });
      },
      child: Container(
        width: 40,
        height: 25,
        decoration: BoxDecoration(
            color: enabled ? Color(0xFFBDCED6) : Colors.grey[500],
            border: Border(
              top: BorderSide(
                  width: 1,
                  color: enabled ? Color(0xFF000000) : Color(0xFFFFFFFF)),
              left: BorderSide(
                  width: 1,
                  color: enabled ? Color(0xFF000000) : Color(0xFFFFFFFF)),
              right: BorderSide(
                  width: 2,
                  color: enabled ? Color(0xFFFFFFFF) : Color(0xFF000000)),
              bottom: BorderSide(
                  width: 2,
                  color: enabled ? Color(0xFFFFFFFF) : Color(0xFF000000)),
            )),
        child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
          Container(
            height: 10,
            width: 10,
            decoration: BoxDecoration(
                color: widget.light,
                border: Border.all(color: Color(0xFF000000), width: 1)),
          ),
          Text(
            widget.text,
            style: TextStyle(
                fontFamily: 'Pixer', color: Colors.black, fontSize: 16),
          ),
        ]),
      ),
    );
  }
}

class ControlLabel extends StatelessWidget {
  final String text;
  final bool enabled;
  final Function onPress;

  ControlLabel({this.text, this.enabled, this.onPress});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onPress,
      child: Text(
        text,
        style: TextStyle(
            fontFamily: 'Pixer',
            fontSize: 18,
            color: enabled ? Color(0XFF04E406) : Colors.white),
      ),
    );
  }
}

class MiniControls extends StatefulWidget {
  final String units;
  final double initialValue;
  final double min;
  final double max;
  final Function control;

  MiniControls(
      {this.units, this.initialValue, this.min, this.max, this.control});

  @override
  _MiniControlsState createState() => _MiniControlsState();
}

class _MiniControlsState extends State<MiniControls> {
  double _value = 0;

  @override
  void initState() {
    _value = widget.initialValue;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Container(
              width: 45,
              height: 32,
              padding: EdgeInsets.symmetric(horizontal: 3, vertical: 2),
              decoration: BoxDecoration(
                color: Color(0xFF040405),
                border: Border(
                  right: BorderSide(width: 2, color: Color(0xFF555569)),
                  bottom: BorderSide(width: 2, color: Color(0xFF555569)),
                ),
                image: DecorationImage(
                    image: NetworkImage(
                        'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
                    fit: BoxFit.fill,
                    repeat: ImageRepeat.repeat),
              ),
              child: Text(
                _value.toString(),
                textAlign: TextAlign.center,
                style: TextStyle(
                    fontFamily: 'Pixer',
                    fontSize: 19,
                    color: Color(0XFF04E406)),
              ),
            ),
            SizedBox(
              width: 5,
            ),
            Text(
              widget.units,
              style: TextStyle(
                  fontFamily: 'Pixer', fontSize: 18, color: Colors.white),
            ),
          ],
        ),
        SizedBox(height: 10),
        Container(
          padding: EdgeInsets.all(0),
          width: 110,
          child: AwesomeSlider(
            value: _value,
            min: widget.min,
            max: widget.max,
            thumbSize: 22.0,
            sliderWidth: 80.0,
            thumbColor: Colors.grey[500],
            roundedRectangleThumbRadius: 0.0,
            topLeftShadow: false,
            bottomRightShadow: true,
            bottomRightShadowBlur: MaskFilter.blur(BlurStyle.outer, 3),
            bottomRightShadowColor: Colors.black,
            activeLineStroke: 2.0,
            activeLineColor: Color(0xFF248A19),
            inactiveLineColor: Color(0xFF248A19),
            child: Padding(
              padding: EdgeInsets.all(2.0),
              child: Center(
                  child: Text(
                '〣 ',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 18.0,
                  fontFamily: 'Pixer',
                  fontWeight: FontWeight.bold,
                ),
              )),
            ),
            onChanged: (double value) {
              widget.control(value);
              setState(() {
                _value = value;
              });
            },
          ),
        ),
      ],
    );
  }
}

class TrackNameBar extends StatelessWidget {
  final String trackName;

  TrackNameBar(this.trackName);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 460,
      height: 32,
      padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: Color(0xFF040405),
        border: Border(
          right: BorderSide(width: 2, color: Color(0xFF555569)),
          bottom: BorderSide(width: 2, color: Color(0xFF555569)),
        ),
        image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
            fit: BoxFit.fill,
            repeat: ImageRepeat.repeat),
      ),
      child: Text(
        this.trackName,
        textAlign: TextAlign.right,
        style: TextStyle(
            fontFamily: 'Pixer', fontSize: 18, color: Color(0XFF04E406)),
      ),
    );
  }
}

class MainInfoWidget extends StatelessWidget {
  final String minutes;
  final String seconds;
  final bool playing;

  MainInfoWidget({this.minutes, this.seconds, this.playing});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 250,
      height: 150,
      decoration: BoxDecoration(
        color: Color(0xFF040405),
        border: Border(
          right: BorderSide(width: 2, color: Color(0xFF555569)),
          bottom: BorderSide(width: 2, color: Color(0xFF555569)),
        ),
        image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
            fit: BoxFit.fill,
            repeat: ImageRepeat.repeat),
      ),
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            SidebarText(),
            Column(
              children: [
                MusicTimer(minutes: this.minutes, seconds: this.seconds),
                Container(
                  width: 190,
                  height: 50,
                  decoration: BoxDecoration(
                    image: DecorationImage(
                        image: playing
                            ? NetworkImage(
                                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/music_bars.gif?raw=false')
                            : NetworkImage(
                                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/musicbars.png?raw=false')),
                  ),
                )
              ],
            ),
          ],
        ),
      ),
    );
  }
}

class SidebarText extends StatelessWidget {
  const SidebarText({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: [
        Text(
          "O",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
        Text(
          "A",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
        Text(
          "I",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
        Text(
          "D",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
        Text(
          "V",
          style: TextStyle(
            fontFamily: 'Pixer',
            color: Color(0xFF404C61),
            fontSize: 20,
          ),
        ),
      ],
    );
  }
}

class MusicTimer extends StatelessWidget {
  final String minutes;
  final String seconds;

  MusicTimer({this.minutes, this.seconds});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text(
          "▶- ",
          style: TextStyle(
              fontFamily: 'Pixer', fontSize: 36, color: Color(0XFF04E406)),
        ),
        Text(
          "${this.minutes}:${this.seconds}",
          style: TextStyle(
              fontFamily: 'Pixer', fontSize: 64, color: Color(0XFF04E406)),
        ),
      ],
    );
  }
}

class WinLogo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 36,
      height: 36,
      decoration: BoxDecoration(
          // color: Colors.white,
          image: DecorationImage(
        image: NetworkImage(
          'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/logo.png?raw=false',
        ),
        fit: BoxFit.cover,
      )),
    );
  }
}

class NavLine extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 285,
      color: Colors.yellow,
      height: 5,
    );
  }
}

/* MOBILE */
class MobileUI extends StatefulWidget {
  @override
  _MobileUIState createState() => _MobileUIState();
}

class _MobileUIState extends State<MobileUI> {
  bool mono = false;
  double seekTime = 0;
  String currentTrack = "No Track Selected";
  String trackMin = "00";
  String trackSec = "00";

  int trackMinint = 0;
  int trackSecint = 0;

  bool paused = true;
  bool initial = true;

  @override
  void initState() {
    setState(() {
      mono = false;
      seekTime = 0;
      currentTrack = "No Track Selected";
      trackMin = "00";
      trackSec = "00";
      trackMinint = 0;
      trackSecint = 0;
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // ignore: unused_element
    void stopMusic() {
      setState(() {
        paused = true;
        currentTrack = "No Track Selected";
      });
    }

    void trackTime() {
      setState(() {
        // ignore: division_optimization
        trackMinint = (seekTime / 60).toInt();
        trackSecint = (seekTime - (trackMinint * 60)).toInt();
      });

      if (trackSecint < 10) {
        setState(() {
          trackSec = "0" + trackSecint.toString();
        });
      } else {
        setState(() {
          trackSec = trackSecint.toString();
        });
      }

      setState(() {
        trackMin = "0" + trackMinint.toString();
      });

      if (trackMin == "03" && trackSec == "04") {
        setState(() {
          seekTime = 0;
          trackMinint = 0;
          trackSecint = 0;
          trackMin = "00";
          trackSec = "00";
        });
        stopMusic();
        // seekAudio(0);
      }
    }

    void seeker() async {
      Timer.periodic(Duration(milliseconds: 1000), (timer) {
        if (!paused) {
          trackTime();

          if (seekTime == 185) {
            stopMusic();
          }

          setState(() {
            seekTime += 1;
          });
        } else {
          // dispose();
        }
      });
    }

    // ignore: unused_element
    void playMusic() {
      if (paused) {
        // playAudio();
        setState(() {
          paused = false;
          // initial=false;
          currentTrack = "Silent - DEMO Track (*JavaScript Required)";
        });
        if (initial) {
          setState(() {
            initial = false;
            seekTime = 0;
          });
          seeker();
        }
      }
    }

    // ignore: unused_element
    void seekMusic(double position) {
      int time = position.toInt();
      // seekAudio(time);

      setState(() {
        trackSecint = time;
        seekTime = position;
      });
      trackTime();
    }

    // ignore: unused_element
    void pauseMusic() {
      // pauseAudio();

      setState(() {
        paused = true;
        currentTrack = "PAUSED - Silent - DEMO Track";
      });
    }

    return Scaffold(
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          MobileNav(),
          Container(
            width: MediaQuery.of(context).size.width * 0.97,
            height: MediaQuery.of(context).size.height - 40,
            decoration: BoxDecoration(
              border: Border.all(color: Color(0xFF555569), width: 2.0),
              gradient: LinearGradient(
                begin: Alignment.centerLeft,
                end: Alignment(0.8, 0.0),
                colors: [
                  Color(0xFF212132),
                  Color(0XFF353454),
                  Color(0xFF474766),
                ],
                tileMode: TileMode.repeated,
              ),
            ),
            child: Padding(
              padding: const EdgeInsets.only(left: 4.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  SizedBox(width: MediaQuery.of(context).size.width * 0.98),
                  SizedBox(height: 5),
                  MobileTrackBar(currentTrack),
                  SizedBox(height: 10),
                  MobileInfoWidget(
                    minutes: trackMin,
                    seconds: trackSec,
                    playing: !paused,
                  ),
                  SizedBox(height: 15),
                  Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      MiniControls(
                          units: "kbps", initialValue: 160, min: 98, max: 320),
                      MiniControls(
                        units: "dB",
                        initialValue: 50,
                        min: 0,
                        max: 100,
                        control: (double level) {
                          // setAudioVolume(level);
                        },
                      ),
                      MiniControls(
                          units: "kHz", initialValue: 44, min: 32, max: 98),
                      SizedBox(width: 10),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          ControlLabel(
                              text: "mono",
                              enabled: mono,
                              onPress: () {
                                setState(() {
                                  mono = true;
                                });
                              }),
                          SizedBox(height: 15),
                          MiniButton(light: Colors.yellow, text: "EQ"),
                        ],
                      ),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          ControlLabel(
                              text: "stereo",
                              enabled: !mono,
                              onPress: () => setState(() {
                                    mono = false;
                                  })),
                          SizedBox(height: 15),
                          MiniButton(light: Colors.red, text: "PL"),
                        ],
                      )
                    ],
                  ),
                  SizedBox(height: 40),
                  MobileSeekBar(
                    min: 0,
                    max: 185, // Time in seconds,
                    value: seekTime,
                    seek: (val) {
                      print("SEEKED" + val.toString());
                      seekMusic(val);
                    },
                  ),
                  SizedBox(height: 40),
                  Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      RetroButton(
                          width: 60,
                          height: 40,
                          onPress: () {
                            seekMusic(0);
                          },
                          icon: Icons.fast_rewind),
                      // SizedBox(width: 10),
                      RetroButton(
                        onPress: () => playMusic(),
                        icon: Icons.play_arrow,
                        width: 60,
                        height: 40,
                      ),
                      // SizedBox(width: 10),
                      RetroButton(
                          width: 60,
                          height: 40,
                          onPress: () => pauseMusic(),
                          icon: Icons.pause),
                      // SizedBox(width: 10),
                      RetroButton(
                          width: 60,
                          height: 40,
                          onPress: () {
                            stopMusic();
                            this.initState();
                          },
                          icon: Icons.stop),
                      // SizedBox(width: 10),
                      RetroButton(
                        width: 60,
                        height: 40,
                        icon: Icons.fast_forward,
                        onPress: () {},
                      ),
                    ],
                  ),
                  SizedBox(height: 25),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    mainAxisSize: MainAxisSize.max,
                    children: [
                      Transform.scale(
                        scale: 1.25,
                        child: TextControlButton(
                            text: "Shuffle", light: Colors.red, width: 65),
                      ),
                      Transform.scale(
                        scale: 1.25,
                        child: TextControlButton(
                            icon: true,
                            ico: Icons.repeat,
                            light: Colors.yellow,
                            width: 65),
                      )
                    ],
                  ),
                  SizedBox(
                    height: 20,
                  ),
                  Container(
                    width: 54,
                    height: 54,
                    decoration: BoxDecoration(
                        // color: Colors.white,
                        image: DecorationImage(
                      image: NetworkImage(
                        'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/logo2.png?raw=true',
                      ),
                      fit: BoxFit.cover,
                    )),
                  )
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// MOBILE SEEKBAR

class MobileSeekBar extends StatelessWidget {
  final Function seek;
  final double min;
  final double max;
  final double value;
  MobileSeekBar({this.seek, this.min, this.max, this.value});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      mainAxisSize: MainAxisSize.max,
      children: [
        Container(
          // decoration: BoxDecoration(color: Color(0xff1B1932)),
          child: MobileSlider(
            value: value,
            min: min,
            max: max,
            thumbSize: 28.0,
            sliderWidth: MediaQuery.of(context).size.width * 0.9,
            thumbColor: Colors.yellow,
            roundedRectangleThumbRadius: 0.0,
            topLeftShadow: false,
            bottomRightShadow: true,
            bottomRightShadowBlur: MaskFilter.blur(BlurStyle.outer, 3),
            bottomRightShadowColor: Colors.black,
            activeLineStroke: 2.0,
            activeLineColor: Color(0xff1B1932),
            inactiveLineColor: Color(0xff1B1932),
            child: Padding(
              padding: EdgeInsets.all(2.0),
              child: Center(
                  child: Text(
                '──',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 18.0,
                  fontFamily: 'Pixer',
                  fontWeight: FontWeight.bold,
                ),
              )),
            ),
            onChanged: (double val) {
              seek(val);
            },
          ),
        ),
      ],
    );
  }
}

// MOBILE SLIDER
class MobileSlider extends StatefulWidget {
  MobileSlider({
    this.value,
    this.min,
    this.max,
    this.onChanged,
    this.child,
    this.sliderWidth,
    this.thumbSize,
    this.thumbColor = Colors.grey,
    this.roundedRectangleThumbRadius = 0.0,
    this.inactiveLineColor = Colors.blue,
    this.inactiveLineStroke,
    this.activeLineColor = Colors.blue,
    this.activeLineStroke,
    this.topLeftShadow = false,
    this.topLeftShadowColor = Colors.blueGrey,
    this.topLeftShadowBlur,
    this.bottomRightShadow = false,
    this.bottomRightShadowColor = Colors.blueGrey,
    this.bottomRightShadowBlur,
  })  : assert(value != null),
        assert(min != null),
        assert(max != null),
        assert(min <= max),
        assert(value >= min && value <= max);

  /// Value of the Slider Position
  /// (Value!=null)
  /// (value >= min && value <= max)

  final double value;

  /// minimum value for the Slider
  /// (min != null)
  /// (min <= max)
  final double min;

  /// maximum value for the Slider
  /// (max != null)
  final double max;

  /// Called when the user starts selecting a new value for the slider.
  final ValueChanged<double> onChanged;

  /// Provide a child Widget to the Slider Thumb
  final Widget child;

  /// Total Width of the Slider.
  /// Default width will be the Canvas Width with a difference of 40px
  final double sliderWidth;

  /// Size of the thumb
  /// Default value will be a 90px ratio of the original Canvas
  final double thumbSize;

  ///Colour of the thumb
  ///Default colour is grey Colour
  final Color thumbColor;

  /// Give this radius to convert the Rectangle into a Rounded Rectangle
  /// Increase in radius will make the  rectangle into a circle
  final double roundedRectangleThumbRadius;

  ///The color for the inactive portion of the slider track.
  ///Default colour is Blue Colour
  final Color inactiveLineColor;

  ///The stroke value for the inactive portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for inactiveLineStroke = activeLineStroke unless given different values for both
  final double inactiveLineStroke;

  ///The color for the active portion of the slider track.
  ///Default colour is Blue Colour
  final Color activeLineColor;

  ///The stroke value for the active portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for activeLineStroke = inactiveLineStroke unless given different values for both
  final double activeLineStroke;

  ///Give true value if a Shadow required on Top - Left of the thumb
  final bool topLeftShadow;

  ///Colour of shadow of Top - Left of the thumb
  ///Default is Blue - Grey
  final Color topLeftShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter topLeftShadowBlur;

  ///Give true value if a Shadow required on Bottom - Right of the thumb
  final bool bottomRightShadow;

  ///Colour of shadow of Bottom - Right of the thumb
  ///Default is Blue - Grey
  final Color bottomRightShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter bottomRightShadowBlur;

  @override
  _MobileSliderState createState() => _MobileSliderState();
}

class _MobileSliderState extends State<MobileSlider> {
  double sliderXCoordinatePositionNow = 0.0;

  double _strokeOfInactiveLine() => (widget.inactiveLineStroke == null)
      ? (widget.activeLineStroke == null) ? 4.0 : widget.activeLineStroke
      : widget.inactiveLineStroke;

  double _strokeOfActiveLine() => (widget.activeLineStroke == null)
      ? (widget.inactiveLineStroke == null) ? 4.0 : widget.inactiveLineStroke
      : widget.activeLineStroke;

  MaskFilter _topLeftShadowBlur() => (widget.topLeftShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.topLeftShadowBlur;

  MaskFilter _bottomRightShadowBlur() => (widget.bottomRightShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.bottomRightShadowBlur;

  double _incrementValueForThumb() =>
      (widget.value == 0.0) ? widget.min : widget.value - widget.min;

  double _lineLengthForPixel() => _sliderWidth() - _sliderHeight();
  double _userValueForPixel() => widget.max - widget.min;
  double _pixelDivision() => _lineLengthForPixel() / _userValueForPixel();

  double _sliderChildPosition() => _incrementValueForThumb() * _pixelDivision();

  double _sliderWidth() {
    double userInputWidth = widget.sliderWidth;
    double screenWidth = window.physicalSize.width;
    double pixelRatio = window.devicePixelRatio;
    double sliderWidth = (userInputWidth == null)
        ? ((screenWidth / pixelRatio) - 40.0)
        : userInputWidth;
    return sliderWidth;
  }

  double _sliderHeight() {
    double userInputHeight = widget.thumbSize;
    double screenHeight = window.physicalSize.height;
    double pixelRatio = window.devicePixelRatio;
    double multiplicationFactor = (90 / 805.3333334);
    double sliderHeight = (userInputHeight == null)
        ? ((screenHeight / pixelRatio) * multiplicationFactor)
        : userInputHeight;
    return sliderHeight.roundToDouble();
    // return 25;
  }

  void _onDragUpdate(DragUpdateDetails dragUpdateDetails) {
    Offset localDragUpdate = dragUpdateDetails.localPosition;
    double xCoordinate;
    (localDragUpdate.dx < 0)
        ? xCoordinate = 0
        : (localDragUpdate.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragUpdate.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _onDragStart(DragStartDetails dragStartDetails) {
    Offset localDragStart = dragStartDetails.localPosition;
    double xCoordinate;
    (localDragStart.dx < 0)
        ? xCoordinate = 0
        : (localDragStart.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragStart.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _value() {
    double incrementValue = sliderXCoordinatePositionNow / _pixelDivision();
    double value = (incrementValue > _userValueForPixel())
        ? _userValueForPixel()
        : incrementValue;
    double userValue = value + widget.min;
    if (widget.onChanged != null) {
      widget.onChanged(userValue);
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onHorizontalDragUpdate: (DragUpdateDetails updateDetails) {
        _onDragUpdate(updateDetails);
        _value();
      },
      onHorizontalDragStart: (DragStartDetails startDetails) {
        _onDragStart(startDetails);
        _value();
      },
      child: Container(
        padding: EdgeInsets.all(0.0),
        child: Stack(
          children: <Widget>[
            Container(
              height: _sliderHeight(),
              width: _sliderWidth(),
              child: CustomPaint(
                painter: MobileSliderPaint(
                  sliderLength: _sliderWidth(),
                  thumbSize: _sliderHeight(),
                  thumbColor: widget.thumbColor,
                  value: _incrementValueForThumb(),
                  min: widget.min,
                  max: widget.max,
                  inactiveLineColor: widget.inactiveLineColor,
                  inactiveLineStroke: _strokeOfInactiveLine(),
                  activeLineColor: widget.activeLineColor,
                  activeLineStroke: _strokeOfActiveLine(),
                  currentTouchPosition: sliderXCoordinatePositionNow,
                  roundedThumbRadius: widget.roundedRectangleThumbRadius,
                  topLeftShadowColor: widget.topLeftShadowColor,
                  bottomRightShadowColor: widget.bottomRightShadowColor,
                  topLeftShadowBlurFactor: _topLeftShadowBlur(),
                  bottomRightShadowBlurFactor: _bottomRightShadowBlur(),
                  bottomRightShadow: widget.bottomRightShadow,
                  topLeftShadow: widget.topLeftShadow,
                ),
              ),
            ),
            Positioned(
              height: _sliderHeight(),
              width: _sliderHeight(),
              left: _sliderChildPosition(),
              child: Container(
                height: double.infinity,
                width: double.infinity,
                child: widget.child,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class MobileSliderPaint extends CustomPainter {
  MobileSliderPaint({
    @required this.sliderLength,
    @required this.thumbSize,
    @required this.thumbColor,
    @required this.value,
    @required this.min,
    @required this.max,
    @required this.roundedThumbRadius,
    @required this.inactiveLineColor,
    @required this.inactiveLineStroke,
    @required this.currentTouchPosition,
    @required this.activeLineColor,
    @required this.activeLineStroke,
    @required this.topLeftShadowColor,
    @required this.bottomRightShadowColor,
    @required this.topLeftShadowBlurFactor,
    @required this.bottomRightShadowBlurFactor,
    @required this.topLeftShadow,
    @required this.bottomRightShadow,
  });
  final double sliderLength;
  final double thumbSize;
  final Color thumbColor;
  final double value;
  final double min;
  final double max;
  final double roundedThumbRadius;
  final Color inactiveLineColor;
  final double inactiveLineStroke;
  final double currentTouchPosition;
  final Color activeLineColor;
  final double activeLineStroke;
  final Color topLeftShadowColor;
  final Color bottomRightShadowColor;
  final MaskFilter bottomRightShadowBlurFactor;
  final MaskFilter topLeftShadowBlurFactor;
  final bool topLeftShadow;
  final bool bottomRightShadow;

  @override
  void paint(Canvas canvas, Size size) {
    double roundedRectangleTopLeftShadowShift = 13.0;
    double roundedRectangleBottomRightShadowShift = 1.5;
    double _increment() {
      double lineLengthForPixel = sliderLength - thumbSize;
      double userValueForPixel = max - min;
      double pixelDivision = lineLengthForPixel / userValueForPixel;
      return value * pixelDivision;
    }

    ///    Inactive Line Paint

    Path inactiveLinePath = Path();
    Paint inactiveLinePaint = Paint()
      ..color = inactiveLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 20;
    inactiveLinePath.moveTo(0.0, thumbSize / 2);
    inactiveLinePath.lineTo(sliderLength, thumbSize / 2);
    canvas.drawPath(inactiveLinePath, inactiveLinePaint);

    ///    Active Line Paint

    Path activeLinePath = Path();
    Paint activeLinePaint = Paint()
      ..color = activeLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 20;
    activeLinePath.moveTo(0.0, thumbSize / 2);
    activeLinePath.lineTo(currentTouchPosition, thumbSize / 2);
    canvas.drawPath(activeLinePath, activeLinePaint);

    ///    Rounded Rectangle Top Left Shadow Paint

    Path roundedRectangleTopLeftShadow = Path();
    Paint roundedRectangleTopLeftShadowPaint = Paint()
      ..color = topLeftShadowColor
      ..maskFilter = topLeftShadowBlurFactor;

    roundedRectangleTopLeftShadow.addRRect(RRect.fromLTRBR(
        0.0 - roundedRectangleTopLeftShadowShift + _increment(),
        0.0 - roundedRectangleTopLeftShadowShift,
        thumbSize - roundedRectangleTopLeftShadowShift + _increment(),
        thumbSize - roundedRectangleTopLeftShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (topLeftShadow == true)
      canvas.drawPath(
          roundedRectangleTopLeftShadow, roundedRectangleTopLeftShadowPaint);

    ///    Rounded Rectangle Bottom Right Shadow Paint

    Path roundedRectangleBottomRightShadow = Path();
    Paint roundedRectangleBottomRightShadowPaint = Paint()
      ..color = bottomRightShadowColor
      ..maskFilter = bottomRightShadowBlurFactor;
    roundedRectangleBottomRightShadow.addRRect(RRect.fromLTRBR(
        0.0 + roundedRectangleBottomRightShadowShift + _increment(),
        0.0 + roundedRectangleBottomRightShadowShift,
        thumbSize + roundedRectangleBottomRightShadowShift + _increment(),
        thumbSize + roundedRectangleBottomRightShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (bottomRightShadow == true)
      canvas.drawPath(roundedRectangleBottomRightShadow,
          roundedRectangleBottomRightShadowPaint);

    ///   Rounded Rectangle Thumb Paint

    Path roundedRectangle = Path();
    Paint roundedRectanglePaint = Paint()..color = thumbColor;

    roundedRectangle.addRRect(RRect.fromLTRBR(
        -5.0 + _increment(),
        0.0,
        thumbSize + 5 + _increment(),
        thumbSize,
        Radius.circular(roundedThumbRadius)));
    canvas.drawPath(roundedRectangle, roundedRectanglePaint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

// MOBILE TRACK BAR

class MobileTrackBar extends StatelessWidget {
  final String trackName;

  MobileTrackBar(this.trackName);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width * 0.98,
      height: 32,
      padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: Color(0xFF040405),
        border: Border(
          right: BorderSide(width: 2, color: Color(0xFF555569)),
          bottom: BorderSide(width: 2, color: Color(0xFF555569)),
        ),
        image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
            fit: BoxFit.fill,
            repeat: ImageRepeat.repeat),
      ),
      child: Text(
        this.trackName,
        textAlign: TextAlign.right,
        style: TextStyle(
            fontFamily: 'Pixer', fontSize: 18, color: Color(0XFF04E406)),
      ),
    );
  }
}

class MobileInfoWidget extends StatelessWidget {
  final String minutes;
  final String seconds;
  final bool playing;

  MobileInfoWidget({this.minutes, this.seconds, this.playing});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width * 0.98,
      height: 250,
      decoration: BoxDecoration(
        color: Color(0xFF040405),
        border: Border(
          right: BorderSide(width: 2, color: Color(0xFF555569)),
          bottom: BorderSide(width: 2, color: Color(0xFF555569)),
        ),
        image: DecorationImage(
            image: NetworkImage(
                'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/gridtexture.png?raw=false'),
            fit: BoxFit.fill,
            repeat: ImageRepeat.repeat),
      ),
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                SizedBox(
                  width: MediaQuery.of(context).size.width * 0.9,
                ),
                MusicTimer(
                  minutes: this.minutes,
                  seconds: this.seconds,
                ),
                Container(
                  width: MediaQuery.of(context).size.width * 0.90,
                  height: 140,
                  decoration: BoxDecoration(
                    image: DecorationImage(
                      image: playing
                          ? NetworkImage(
                              'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/music_bars.gif?raw=false')
                          : NetworkImage(
                              'https://github.com/ishandeveloper/WinAMP_Flutter/blob/master/assets/musicbars.png?raw=false'),
                    ),
                  ),
                )
              ],
            ),
          ],
        ),
      ),
    );
  }
}

// MOBILE NAV

class MobileNav extends StatelessWidget {
  const MobileNav({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 8),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Container(
            width: MediaQuery.of(context).size.width * 0.33,
            color: Colors.yellow,
            height: 5,
          ),
          SizedBox(width: 10),
          Text(
            "WINAMP",
            style: TextStyle(
              color: Colors.white,
              fontFamily: 'Pixer',
              fontSize: 18,
            ),
          ),
          Container(
            width: MediaQuery.of(context).size.width * 0.33,
            color: Colors.yellow,
            height: 5,
          ),
        ],
      ),
    );
  }
}

// AWESOME SLIDER

class AwesomeSlider extends StatefulWidget {
  AwesomeSlider({
    this.value,
    this.min,
    this.max,
    this.onChanged,
    this.child,
    this.sliderWidth,
    this.thumbSize,
    this.thumbColor = Colors.grey,
    this.roundedRectangleThumbRadius = 0.0,
    this.inactiveLineColor = Colors.blue,
    this.inactiveLineStroke,
    this.activeLineColor = Colors.blue,
    this.activeLineStroke,
    this.topLeftShadow = false,
    this.topLeftShadowColor = Colors.blueGrey,
    this.topLeftShadowBlur,
    this.bottomRightShadow = false,
    this.bottomRightShadowColor = Colors.blueGrey,
    this.bottomRightShadowBlur,
  })  : assert(value != null),
        assert(min != null),
        assert(max != null),
        assert(min <= max),
        assert(value >= min && value <= max);

  /// Value of the Slider Position
  /// (Value!=null)
  /// (value >= min && value <= max)

  final double value;

  /// minimum value for the Slider
  /// (min != null)
  /// (min <= max)
  final double min;

  /// maximum value for the Slider
  /// (max != null)
  final double max;

  /// Called when the user starts selecting a new value for the slider.
  final ValueChanged<double> onChanged;

  /// Provide a child Widget to the Slider Thumb
  final Widget child;

  /// Total Width of the Slider.
  /// Default width will be the Canvas Width with a difference of 40px
  final double sliderWidth;

  /// Size of the thumb
  /// Default value will be a 90px ratio of the original Canvas
  final double thumbSize;

  ///Colour of the thumb
  ///Default colour is grey Colour
  final Color thumbColor;

  /// Give this radius to convert the Rectangle into a Rounded Rectangle
  /// Increase in radius will make the  rectangle into a circle
  final double roundedRectangleThumbRadius;

  ///The color for the inactive portion of the slider track.
  ///Default colour is Blue Colour
  final Color inactiveLineColor;

  ///The stroke value for the inactive portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for inactiveLineStroke = activeLineStroke unless given different values for both
  final double inactiveLineStroke;

  ///The color for the active portion of the slider track.
  ///Default colour is Blue Colour
  final Color activeLineColor;

  ///The stroke value for the active portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for activeLineStroke = inactiveLineStroke unless given different values for both
  final double activeLineStroke;

  ///Give true value if a Shadow required on Top - Left of the thumb
  final bool topLeftShadow;

  ///Colour of shadow of Top - Left of the thumb
  ///Default is Blue - Grey
  final Color topLeftShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter topLeftShadowBlur;

  ///Give true value if a Shadow required on Bottom - Right of the thumb
  final bool bottomRightShadow;

  ///Colour of shadow of Bottom - Right of the thumb
  ///Default is Blue - Grey
  final Color bottomRightShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter bottomRightShadowBlur;

  @override
  _AwesomeSliderState createState() => _AwesomeSliderState();
}

class _AwesomeSliderState extends State<AwesomeSlider> {
  double sliderXCoordinatePositionNow = 0.0;

  double _strokeOfInactiveLine() => (widget.inactiveLineStroke == null)
      ? (widget.activeLineStroke == null) ? 4.0 : widget.activeLineStroke
      : widget.inactiveLineStroke;

  double _strokeOfActiveLine() => (widget.activeLineStroke == null)
      ? (widget.inactiveLineStroke == null) ? 4.0 : widget.inactiveLineStroke
      : widget.activeLineStroke;

  MaskFilter _topLeftShadowBlur() => (widget.topLeftShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.topLeftShadowBlur;

  MaskFilter _bottomRightShadowBlur() => (widget.bottomRightShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.bottomRightShadowBlur;

  double _incrementValueForThumb() =>
      (widget.value == 0.0) ? widget.min : widget.value - widget.min;

  double _lineLengthForPixel() => _sliderWidth() - _sliderHeight();
  double _userValueForPixel() => widget.max - widget.min;
  double _pixelDivision() => _lineLengthForPixel() / _userValueForPixel();

  double _sliderChildPosition() => _incrementValueForThumb() * _pixelDivision();

  double _sliderWidth() {
    double userInputWidth = widget.sliderWidth;
    double screenWidth = window.physicalSize.width;
    double pixelRatio = window.devicePixelRatio;
    double sliderWidth = (userInputWidth == null)
        ? ((screenWidth / pixelRatio) - 40.0)
        : userInputWidth;
    return sliderWidth;
  }

  double _sliderHeight() {
    double userInputHeight = widget.thumbSize;
    double screenHeight = window.physicalSize.height;
    double pixelRatio = window.devicePixelRatio;
    double multiplicationFactor = (90 / 805.3333334);
    double sliderHeight = (userInputHeight == null)
        ? ((screenHeight / pixelRatio) * multiplicationFactor)
        : userInputHeight;
    return sliderHeight.roundToDouble();
  }

  void _onDragUpdate(DragUpdateDetails dragUpdateDetails) {
    Offset localDragUpdate = dragUpdateDetails.localPosition;
    double xCoordinate;
    (localDragUpdate.dx < 0)
        ? xCoordinate = 0
        : (localDragUpdate.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragUpdate.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _onDragStart(DragStartDetails dragStartDetails) {
    Offset localDragStart = dragStartDetails.localPosition;
    double xCoordinate;
    (localDragStart.dx < 0)
        ? xCoordinate = 0
        : (localDragStart.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragStart.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _value() {
    double incrementValue = sliderXCoordinatePositionNow / _pixelDivision();
    double value = (incrementValue > _userValueForPixel())
        ? _userValueForPixel()
        : incrementValue;
    double userValue = value + widget.min;
    if (widget.onChanged != null) {
      widget.onChanged(userValue);
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onHorizontalDragUpdate: (DragUpdateDetails updateDetails) {
        _onDragUpdate(updateDetails);
        _value();
      },
      onHorizontalDragStart: (DragStartDetails startDetails) {
        _onDragStart(startDetails);
        _value();
      },
      child: Container(
        padding: EdgeInsets.all(0.0),
        child: Stack(
          children: <Widget>[
            Container(
              height: _sliderHeight(),
              width: _sliderWidth(),
              child: CustomPaint(
                painter: AwesomeSliderPaint(
                  sliderLength: _sliderWidth(),
                  thumbSize: _sliderHeight(),
                  thumbColor: widget.thumbColor,
                  value: _incrementValueForThumb(),
                  min: widget.min,
                  max: widget.max,
                  inactiveLineColor: widget.inactiveLineColor,
                  inactiveLineStroke: _strokeOfInactiveLine(),
                  activeLineColor: widget.activeLineColor,
                  activeLineStroke: _strokeOfActiveLine(),
                  currentTouchPosition: sliderXCoordinatePositionNow,
                  roundedThumbRadius: widget.roundedRectangleThumbRadius,
                  topLeftShadowColor: widget.topLeftShadowColor,
                  bottomRightShadowColor: widget.bottomRightShadowColor,
                  topLeftShadowBlurFactor: _topLeftShadowBlur(),
                  bottomRightShadowBlurFactor: _bottomRightShadowBlur(),
                  bottomRightShadow: widget.bottomRightShadow,
                  topLeftShadow: widget.topLeftShadow,
                ),
              ),
            ),
            Positioned(
              height: _sliderHeight(),
              width: _sliderHeight(),
              left: _sliderChildPosition(),
              child: Container(
                height: double.infinity,
                width: double.infinity,
                child: widget.child,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class AwesomeSliderPaint extends CustomPainter {
  AwesomeSliderPaint({
    @required this.sliderLength,
    @required this.thumbSize,
    @required this.thumbColor,
    @required this.value,
    @required this.min,
    @required this.max,
    @required this.roundedThumbRadius,
    @required this.inactiveLineColor,
    @required this.inactiveLineStroke,
    @required this.currentTouchPosition,
    @required this.activeLineColor,
    @required this.activeLineStroke,
    @required this.topLeftShadowColor,
    @required this.bottomRightShadowColor,
    @required this.topLeftShadowBlurFactor,
    @required this.bottomRightShadowBlurFactor,
    @required this.topLeftShadow,
    @required this.bottomRightShadow,
  });
  final double sliderLength;
  final double thumbSize;
  final Color thumbColor;
  final double value;
  final double min;
  final double max;
  final double roundedThumbRadius;
  final Color inactiveLineColor;
  final double inactiveLineStroke;
  final double currentTouchPosition;
  final Color activeLineColor;
  final double activeLineStroke;
  final Color topLeftShadowColor;
  final Color bottomRightShadowColor;
  final MaskFilter bottomRightShadowBlurFactor;
  final MaskFilter topLeftShadowBlurFactor;
  final bool topLeftShadow;
  final bool bottomRightShadow;

  @override
  void paint(Canvas canvas, Size size) {
    double roundedRectangleTopLeftShadowShift = 13.0;
    double roundedRectangleBottomRightShadowShift = 1.5;
    double _increment() {
      double lineLengthForPixel = sliderLength - thumbSize;
      double userValueForPixel = max - min;
      double pixelDivision = lineLengthForPixel / userValueForPixel;
      return value * pixelDivision;
    }

    ///    Inactive Line Paint

    Path inactiveLinePath = Path();
    Paint inactiveLinePaint = Paint()
      ..color = inactiveLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = inactiveLineStroke;
    inactiveLinePath.moveTo(0.0, thumbSize / 2);
    inactiveLinePath.lineTo(sliderLength, thumbSize / 2);
    canvas.drawPath(inactiveLinePath, inactiveLinePaint);

    ///    Active Line Paint

    Path activeLinePath = Path();
    Paint activeLinePaint = Paint()
      ..color = activeLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = activeLineStroke;
    activeLinePath.moveTo(0.0, thumbSize / 2);
    activeLinePath.lineTo(currentTouchPosition, thumbSize / 2);
    canvas.drawPath(activeLinePath, activeLinePaint);

    ///    Rounded Rectangle Top Left Shadow Paint

    Path roundedRectangleTopLeftShadow = Path();
    Paint roundedRectangleTopLeftShadowPaint = Paint()
      ..color = topLeftShadowColor
      ..maskFilter = topLeftShadowBlurFactor;

    roundedRectangleTopLeftShadow.addRRect(RRect.fromLTRBR(
        0.0 - roundedRectangleTopLeftShadowShift + _increment(),
        0.0 - roundedRectangleTopLeftShadowShift,
        thumbSize - roundedRectangleTopLeftShadowShift + _increment(),
        thumbSize - roundedRectangleTopLeftShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (topLeftShadow == true)
      canvas.drawPath(
          roundedRectangleTopLeftShadow, roundedRectangleTopLeftShadowPaint);

    ///    Rounded Rectangle Bottom Right Shadow Paint

    Path roundedRectangleBottomRightShadow = Path();
    Paint roundedRectangleBottomRightShadowPaint = Paint()
      ..color = bottomRightShadowColor
      ..maskFilter = bottomRightShadowBlurFactor;
    roundedRectangleBottomRightShadow.addRRect(RRect.fromLTRBR(
        0.0 + roundedRectangleBottomRightShadowShift + _increment(),
        0.0 + roundedRectangleBottomRightShadowShift,
        thumbSize + roundedRectangleBottomRightShadowShift + _increment(),
        thumbSize + roundedRectangleBottomRightShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (bottomRightShadow == true)
      canvas.drawPath(roundedRectangleBottomRightShadow,
          roundedRectangleBottomRightShadowPaint);

    ///   Rounded Rectangle Thumb Paint

    Path roundedRectangle = Path();
    Paint roundedRectanglePaint = Paint()..color = thumbColor;

    roundedRectangle.addRRect(RRect.fromLTRBR(
        0.0 + _increment(),
        0.0,
        thumbSize + _increment(),
        thumbSize,
        Radius.circular(roundedThumbRadius)));
    canvas.drawPath(roundedRectangle, roundedRectanglePaint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

// CUSTOM SLIDER

class CustomSlider extends StatefulWidget {
  CustomSlider({
    this.value,
    this.min,
    this.max,
    this.onChanged,
    this.child,
    this.sliderWidth,
    this.thumbSize,
    this.thumbColor = Colors.grey,
    this.roundedRectangleThumbRadius = 0.0,
    this.inactiveLineColor = Colors.blue,
    this.inactiveLineStroke,
    this.activeLineColor = Colors.blue,
    this.activeLineStroke,
    this.topLeftShadow = false,
    this.topLeftShadowColor = Colors.blueGrey,
    this.topLeftShadowBlur,
    this.bottomRightShadow = false,
    this.bottomRightShadowColor = Colors.blueGrey,
    this.bottomRightShadowBlur,
  })  : assert(value != null),
        assert(min != null),
        assert(max != null),
        assert(min <= max),
        assert(value >= min && value <= max);

  /// Value of the Slider Position
  /// (Value!=null)
  /// (value >= min && value <= max)

  final double value;

  /// minimum value for the Slider
  /// (min != null)
  /// (min <= max)
  final double min;

  /// maximum value for the Slider
  /// (max != null)
  final double max;

  /// Called when the user starts selecting a new value for the slider.
  final ValueChanged<double> onChanged;

  /// Provide a child Widget to the Slider Thumb
  final Widget child;

  /// Total Width of the Slider.
  /// Default width will be the Canvas Width with a difference of 40px
  final double sliderWidth;

  /// Size of the thumb
  /// Default value will be a 90px ratio of the original Canvas
  final double thumbSize;

  ///Colour of the thumb
  ///Default colour is grey Colour
  final Color thumbColor;

  /// Give this radius to convert the Rectangle into a Rounded Rectangle
  /// Increase in radius will make the  rectangle into a circle
  final double roundedRectangleThumbRadius;

  ///The color for the inactive portion of the slider track.
  ///Default colour is Blue Colour
  final Color inactiveLineColor;

  ///The stroke value for the inactive portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for inactiveLineStroke = activeLineStroke unless given different values for both
  final double inactiveLineStroke;

  ///The color for the active portion of the slider track.
  ///Default colour is Blue Colour
  final Color activeLineColor;

  ///The stroke value for the active portion of the slider track.
  ///Default stroke value is 4.0
  ///Value for activeLineStroke = inactiveLineStroke unless given different values for both
  final double activeLineStroke;

  ///Give true value if a Shadow required on Top - Left of the thumb
  final bool topLeftShadow;

  ///Colour of shadow of Top - Left of the thumb
  ///Default is Blue - Grey
  final Color topLeftShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter topLeftShadowBlur;

  ///Give true value if a Shadow required on Bottom - Right of the thumb
  final bool bottomRightShadow;

  ///Colour of shadow of Bottom - Right of the thumb
  ///Default is Blue - Grey
  final Color bottomRightShadowColor;

  ///MaskFilter blur value for shadow of Top - Left of the thumb
  ///MaskFilter.blur(BlurStyle.normal, 3.0)
  final MaskFilter bottomRightShadowBlur;

  @override
  _CustomSliderState createState() => _CustomSliderState();
}

class _CustomSliderState extends State<CustomSlider> {
  double sliderXCoordinatePositionNow = 0.0;

  double _strokeOfInactiveLine() => (widget.inactiveLineStroke == null)
      ? (widget.activeLineStroke == null) ? 4.0 : widget.activeLineStroke
      : widget.inactiveLineStroke;

  double _strokeOfActiveLine() => (widget.activeLineStroke == null)
      ? (widget.inactiveLineStroke == null) ? 4.0 : widget.inactiveLineStroke
      : widget.activeLineStroke;

  MaskFilter _topLeftShadowBlur() => (widget.topLeftShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.topLeftShadowBlur;

  MaskFilter _bottomRightShadowBlur() => (widget.bottomRightShadowBlur == null)
      ? MaskFilter.blur(BlurStyle.normal, 3.0)
      : widget.bottomRightShadowBlur;

  double _incrementValueForThumb() =>
      (widget.value == 0.0) ? widget.min : widget.value - widget.min;

  double _lineLengthForPixel() => _sliderWidth() - _sliderHeight();
  double _userValueForPixel() => widget.max - widget.min;
  double _pixelDivision() => _lineLengthForPixel() / _userValueForPixel();

  double _sliderChildPosition() => _incrementValueForThumb() * _pixelDivision();

  double _sliderWidth() {
    double userInputWidth = widget.sliderWidth;
    double screenWidth = window.physicalSize.width;
    double pixelRatio = window.devicePixelRatio;
    double sliderWidth = (userInputWidth == null)
        ? ((screenWidth / pixelRatio) - 40.0)
        : userInputWidth;
    return sliderWidth;
  }

  double _sliderHeight() {
    double userInputHeight = widget.thumbSize;
    double screenHeight = window.physicalSize.height;
    double pixelRatio = window.devicePixelRatio;
    double multiplicationFactor = (90 / 805.3333334);
    double sliderHeight = (userInputHeight == null)
        ? ((screenHeight / pixelRatio) * multiplicationFactor)
        : userInputHeight;
    return sliderHeight.roundToDouble();
    // return 25;
  }

  void _onDragUpdate(DragUpdateDetails dragUpdateDetails) {
    Offset localDragUpdate = dragUpdateDetails.localPosition;
    double xCoordinate;
    (localDragUpdate.dx < 0)
        ? xCoordinate = 0
        : (localDragUpdate.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragUpdate.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _onDragStart(DragStartDetails dragStartDetails) {
    Offset localDragStart = dragStartDetails.localPosition;
    double xCoordinate;
    (localDragStart.dx < 0)
        ? xCoordinate = 0
        : (localDragStart.dx > _sliderWidth())
            ? xCoordinate = _sliderWidth()
            : xCoordinate = localDragStart.dx;
    setState(() {
      sliderXCoordinatePositionNow = xCoordinate;
    });
  }

  void _value() {
    double incrementValue = sliderXCoordinatePositionNow / _pixelDivision();
    double value = (incrementValue > _userValueForPixel())
        ? _userValueForPixel()
        : incrementValue;
    double userValue = value + widget.min;
    if (widget.onChanged != null) {
      widget.onChanged(userValue);
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      behavior: HitTestBehavior.translucent,
      onHorizontalDragUpdate: (DragUpdateDetails updateDetails) {
        _onDragUpdate(updateDetails);
        _value();
      },
      onHorizontalDragStart: (DragStartDetails startDetails) {
        _onDragStart(startDetails);
        _value();
      },
      child: Container(
        padding: EdgeInsets.all(0.0),
        child: Stack(
          children: <Widget>[
            Container(
              height: _sliderHeight(),
              width: _sliderWidth(),
              child: CustomPaint(
                painter: CustomSliderPaint(
                  sliderLength: _sliderWidth(),
                  thumbSize: _sliderHeight(),
                  thumbColor: widget.thumbColor,
                  value: _incrementValueForThumb(),
                  min: widget.min,
                  max: widget.max,
                  inactiveLineColor: widget.inactiveLineColor,
                  inactiveLineStroke: _strokeOfInactiveLine(),
                  activeLineColor: widget.activeLineColor,
                  activeLineStroke: _strokeOfActiveLine(),
                  currentTouchPosition: sliderXCoordinatePositionNow,
                  roundedThumbRadius: widget.roundedRectangleThumbRadius,
                  topLeftShadowColor: widget.topLeftShadowColor,
                  bottomRightShadowColor: widget.bottomRightShadowColor,
                  topLeftShadowBlurFactor: _topLeftShadowBlur(),
                  bottomRightShadowBlurFactor: _bottomRightShadowBlur(),
                  bottomRightShadow: widget.bottomRightShadow,
                  topLeftShadow: widget.topLeftShadow,
                ),
              ),
            ),
            Positioned(
              height: _sliderHeight(),
              width: _sliderHeight(),
              left: _sliderChildPosition(),
              child: Container(
                height: double.infinity,
                width: double.infinity,
                child: widget.child,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class CustomSliderPaint extends CustomPainter {
  CustomSliderPaint({
    @required this.sliderLength,
    @required this.thumbSize,
    @required this.thumbColor,
    @required this.value,
    @required this.min,
    @required this.max,
    @required this.roundedThumbRadius,
    @required this.inactiveLineColor,
    @required this.inactiveLineStroke,
    @required this.currentTouchPosition,
    @required this.activeLineColor,
    @required this.activeLineStroke,
    @required this.topLeftShadowColor,
    @required this.bottomRightShadowColor,
    @required this.topLeftShadowBlurFactor,
    @required this.bottomRightShadowBlurFactor,
    @required this.topLeftShadow,
    @required this.bottomRightShadow,
  });
  final double sliderLength;
  final double thumbSize;
  final Color thumbColor;
  final double value;
  final double min;
  final double max;
  final double roundedThumbRadius;
  final Color inactiveLineColor;
  final double inactiveLineStroke;
  final double currentTouchPosition;
  final Color activeLineColor;
  final double activeLineStroke;
  final Color topLeftShadowColor;
  final Color bottomRightShadowColor;
  final MaskFilter bottomRightShadowBlurFactor;
  final MaskFilter topLeftShadowBlurFactor;
  final bool topLeftShadow;
  final bool bottomRightShadow;

  @override
  void paint(Canvas canvas, Size size) {
    double roundedRectangleTopLeftShadowShift = 13.0;
    double roundedRectangleBottomRightShadowShift = 1.5;
    double _increment() {
      double lineLengthForPixel = sliderLength - thumbSize;
      double userValueForPixel = max - min;
      double pixelDivision = lineLengthForPixel / userValueForPixel;
      return value * pixelDivision;
    }

    ///    Inactive Line Paint

    Path inactiveLinePath = Path();
    Paint inactiveLinePaint = Paint()
      ..color = inactiveLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 30;
    inactiveLinePath.moveTo(0.0, thumbSize / 2);
    inactiveLinePath.lineTo(sliderLength, thumbSize / 2);
    canvas.drawPath(inactiveLinePath, inactiveLinePaint);

    ///    Active Line Paint

    Path activeLinePath = Path();
    Paint activeLinePaint = Paint()
      ..color = activeLineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 32;
    activeLinePath.moveTo(0.0, thumbSize / 2);
    activeLinePath.lineTo(currentTouchPosition, thumbSize / 2);
    canvas.drawPath(activeLinePath, activeLinePaint);

    ///    Rounded Rectangle Top Left Shadow Paint

    Path roundedRectangleTopLeftShadow = Path();
    Paint roundedRectangleTopLeftShadowPaint = Paint()
      ..color = topLeftShadowColor
      ..maskFilter = topLeftShadowBlurFactor;

    roundedRectangleTopLeftShadow.addRRect(RRect.fromLTRBR(
        0.0 - roundedRectangleTopLeftShadowShift + _increment(),
        0.0 - roundedRectangleTopLeftShadowShift,
        thumbSize - roundedRectangleTopLeftShadowShift + _increment(),
        thumbSize - roundedRectangleTopLeftShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (topLeftShadow == true)
      canvas.drawPath(
          roundedRectangleTopLeftShadow, roundedRectangleTopLeftShadowPaint);

    ///    Rounded Rectangle Bottom Right Shadow Paint

    Path roundedRectangleBottomRightShadow = Path();
    Paint roundedRectangleBottomRightShadowPaint = Paint()
      ..color = bottomRightShadowColor
      ..maskFilter = bottomRightShadowBlurFactor;
    roundedRectangleBottomRightShadow.addRRect(RRect.fromLTRBR(
        0.0 + roundedRectangleBottomRightShadowShift + _increment(),
        0.0 + roundedRectangleBottomRightShadowShift,
        thumbSize + roundedRectangleBottomRightShadowShift + _increment(),
        thumbSize + roundedRectangleBottomRightShadowShift,
        Radius.circular(roundedThumbRadius)));
    if (bottomRightShadow == true)
      canvas.drawPath(roundedRectangleBottomRightShadow,
          roundedRectangleBottomRightShadowPaint);

    ///   Rounded Rectangle Thumb Paint

    Path roundedRectangle = Path();
    Paint roundedRectanglePaint = Paint()..color = thumbColor;

    roundedRectangle.addRRect(RRect.fromLTRBR(
        -5.0 + _increment(),
        0.0,
        thumbSize + 5 + _increment(),
        thumbSize,
        Radius.circular(roundedThumbRadius)));
    canvas.drawPath(roundedRectangle, roundedRectanglePaint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}

              
            
!
999px

Console