Home Blog Page 7

Flutter Form Validation – Button State Active or InActive

0
Flutter Form Validation - BUTTON SHOULD NOT BE CLICKABLE UNTIL validated
Flutter Form Validation - BUTTON SHOULD NOT BE CLICKABLE UNTIL validated

Hi Guy’s, Welcome to Proto Coders Point. In this Flutter Tutorial Article, We will Learn how to enhance user experience in your Flutter applications by enabling a feature i.e. A button should be clickable only when form Textfields data are properly validated.

Source Code – Flutter TextField Form Validation – Disable Button Until Form is Valid

As you all know that Form Validation is very important for user input, making sure that submitted form is valid and data is received or submitted is not empty or irrelevant.

In flutter we have 'Form' widget for implementing form validation. This Article is specially for integrating submit button disable or active state depending on validation of form.

Form Validation with GlobalKey

In flutter to validate the data entered into the textfield of the form we can utilize the GlobalKey<FormState>, This contains the functionality to validate the form & manage it state.

final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

The _formKey is attached to Form Widget to enable the access to the form state and validate it’s functionality.


Managing Button State – Clickable or Disabled

The Form Widget has a property onChanged() which keep calling then use enter data in form textField.

Here to Control the state of the button, We have use a boolean variable that will be updated to true if _formKey.currentState!.validate() return true.

_formKey.currentState!.validate() => This function check if all the textField in the form meet with validated criteria. if validation is successful, the variable isValid is set to true.

bool isValid = false;

void onChange() {
  setState(() {
    isValid = _formKey.currentState!.validate();
  });
}

Now we can use this isValid variable to make button Clickable or NotClickable.


Button Activation with onPressed

Flutter Buttons onPressed when set to null, It means button is disable or NotClickable and the button color is set to grey automatically.

ElevatedButton(
         onPressed: isValid ? (){
                     // Do something
         } : null,
       child: Text("Submit"),

 ),

Here onPressed function is triggered only when isValid is true, Which ensure that the button remains inactive until the form is valid.

Complete Source Code

TextField InputDecoration Design

Create a File by name ‘input_TextFieldDecoration.dart’, The below code is just for giving stying to TextField

import 'package:flutter/material.dart';

InputDecoration buildInputDecoration(IconData icons,String hinttext) {
  return InputDecoration(
    hintText: hinttext,
    prefixIcon: Icon(icons),
    focusedBorder: OutlineInputBorder(
      borderRadius: BorderRadius.circular(25.0),
      borderSide: BorderSide(
          color: Colors.green,
          width: 1.5
      ),
    ),
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(25.0),
      borderSide: BorderSide(
        color: Colors.blue,
        width: 1.5,
      ),
    ),
    enabledBorder:OutlineInputBorder(
      borderRadius: BorderRadius.circular(25.0),
      borderSide: BorderSide(
        color: Colors.blue,
        width: 1.5,
      ),
    ),
  );
}

FormPage.dart

import 'package:flutter/material.dart';
import 'input_TextFieldDecoration.dart';

class FormPage extends StatefulWidget {
  @override
  _FormPageState createState() => _FormPageState();
}

class _FormPageState extends State<FormPage> {

  late String name,email,phone;

  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  bool isValid = false;

  void onChange(){
    setState(() {
      isValid = _formKey.currentState!.validate();
    });

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: SingleChildScrollView(
          child: Form(
            key: _formKey,
            onChanged: (){
              onChange();
            },
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const CircleAvatar(
                  radius: 70,
                  backgroundColor: Colors.lightGreen,
                  child: Icon(Icons.abc_sharp,size: 120,),
                ),
                const SizedBox(
                  height: 15,
                ),
                Padding(
                  padding: const EdgeInsets.only(bottom:15,left: 10,right: 10),
                  child: TextFormField(
                    keyboardType: TextInputType.text,
                    decoration: buildInputDecoration(Icons.person,"Full Name"),
                    validator: (value){
                      if(value!.isEmpty){
                        return "Please Enter name";
                      }
                      return null;
                    },
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(bottom: 15,left: 10,right: 10),
                  child: TextFormField(
                    keyboardType: TextInputType.text,
                    decoration:buildInputDecoration(Icons.email,"Email"),
                    validator: (value){
                      if(value!.isEmpty){
                        return "Please Enter Email";
                      }
                      // Rajat@gmail.com
                      if(!RegExp(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$').hasMatch(value)){
                        return 'Please a valid Email';
                      }



                      return null;
                    },
                  ),
                ),
                SizedBox(
                  width: 200,
                  height: 50,
                  child: ElevatedButton(
                    onPressed: isValid ? (){
                      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Valid Form")));
                    } : null,
                    child: Text("Submit"),
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Conclusion

In this Flutter Code, we illustrated a straightforward implementation of form validation with button state management, dynamically making button active or inactive based on form validation.

NodeJS Data Encryption & Decryption using CryptoJS Module

0
NodeJS Data encryption description using crypto js library
NodeJS Data encryption description using crypto js library

Hi Guys, Welcome to Proto Coders Point, Data Encrypting & Data Decryption is must requirement when it come to data security in any application development may be it Web Application, Mobile Application of any other Application. Especially when data or information that is transmit is sensitive and can’t be directly readable by the app users.

To make the data security high it’s always recommended to better apply an encryption and decryption during data transmission from server to client.

Video Tutorial

NodeJS Data Encryption & Decryption using Crypto-JS NodeJS Module

There are various NodeJS Module by which NodeJS Developer can achieve data encryption & decryption within the application. Will make use of popular and most commonly used module/library called 'crypto-js'.

Below is a simple example how to make use of 'crypto-js' module for encryption & decryption of data in NodeJS. For this example will create a NodeJS Express server and create 2 API routes, one for encryption and another for decryption.

Necessary Packages Required:

We need 4 dependencies modules for Implementation

  1. body-parser: Used as a middleware for parsing incoming request bodies in Express.
  2. cors: Middleware for enabling Cross-Origin Resource Sharing in web applications.
  3. express: Web Application framework of NodeJS used for creating NodeJS Server.
  4. crypto-js: is a JavaScript library used for data encryption & decryption using cryptographic functions.

Install them using below cmd

npm install body-parser cors express crypto-js

How to make use of NodeJS Crypto-JS to encrypt data

function encrypt(data,key){
    const cipherText = CryptoJS.AES.encrypt(data,key).toString();
    return cipherText;
}

The above function accept 2 parameter i.e data & key. Here data is the msg or information that you want to encrypt and key is basically a secret key that is been used by CryptoJS to encrypt that data.

The CryptoJS loibrary in NodeJS making use of Advanced Encryption Standard (AES) algorithm to encrypt the data.

The key is very important as it used for both data encryption & decryption.


How to decrypt data in NodeJS using CryptoJS

To decrypt data in nodeJS we need encrypted format of data and the key that was used to encrypt the data.

function decrypt(cipherText,key){
    try {
        const bytes = CryptoJS.AES.decrypt(cipherText,key);

        if(bytes.sigBytes > 0){
            const decryptedData = bytes.toString(CryptoJS.enc.Utf8);
            return decryptedData;
        }else{
            throw new Error('Decryption Failed Invalid Key')
        }
    } catch (error) {
        throw new Error('Decryption Failed Invalid Key')
    }

}

in above example cipherText means encrypted data and key is used to decrypt the data.


Complete Source Code – NodeJS Data Encryption & Description using CryptoJS library

app.js

Here we have 2 API Routes, encrypt & decrypt and as the make of this API itself says that it can we used for data encryption & decryption.

const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const CryptoJS = require('crypto-js');

const app = express();

app.use(cors());

app.use(bodyParser.json({limit:'50mb'}))
app.use(bodyParser.urlencoded({limit:'50mb',extended:true}));


app.get('/',(req,res)=>{
    res.send(" Say Hello To Proto Coders Point, Please Subscribe")
});


function encrypt(data,key){
    const cipherText = CryptoJS.AES.encrypt(data,key).toString();
    return cipherText;
}


function decrypt(cipherText,key){
    try {
        const bytes = CryptoJS.AES.decrypt(cipherText,key);

        if(bytes.sigBytes > 0){
            const decryptedData = bytes.toString(CryptoJS.enc.Utf8);
            return decryptedData;
        }else{
            throw new Error('Decryption Failed Invalid Key')
        }
    } catch (error) {
        throw new Error('Decryption Failed Invalid Key')
    }

}

app.post('/encrypt',(req,res)=>{
    const { data, key} = req.body;
    const encrypted = encrypt(data,key);
    res.json({encrypted});
});

app.post('/decrypt',(req,res)=>{
    const { encryptedData, key } = req.body;

    const decryptedData = decrypt(encryptedData, key);
    res.json({decryptedData});
});


module.exports = app;

index.js

This is the starting point of our NodeJS Project

start the nodeJS server using below cmd

node index.js

Flutter ListView: Scroll Up or Down – ScrollController Class

0
Flutter Listview Controller
Flutter Listview Controller

Hi Guy’s Welcome to Proto Coders Point. In this Flutter Article let’s learn how to implement Flutter ListView Scroll Up and Scroll Down by fully controlling the listview.

Flutter is an farmware developed by Google For building Native based application for Mobile, Web and Desktop from a single codebase i.e. Dart Language. While working with application development with flutter on commonly used UI element is ListView a Flutter widget using which we can display the list of data and used scroll through the data.

Now as we are want to implement feature to our flutter listview like controlling over the scrolling the behaviour. We make use of a controller i.e. ScrollController class.

This Article will help you in implementing smooth scrolling with animation effect to the ListView i.e. Scroll Up or Scroll Down.

Video Tutorial

Let’s Understand the power of Flutter Scroll Controller

Flutter ScrollController class using which flutter developer has controller over any Flutter Scrolling Widget, such as ListView. By attaching ScrollController to ListView developer can programmatically control the Scrolling of the ListView.

Here is how to create a ScrollController & attach it to listview

ScrollController _controller = ScrollController();

Attach it to ListView

ListView(
  controller: _controller,
  // other ListView properties
  children: [
    // list items
  ],
)

Now as I have attached the controller with ListView we have full controller programmatically to the ListView


ListView Scroll to Bottom – Flutter

Create a ScrollController

final controller = ScrollController();

Attach the controller to listview

ListView.builder(
        controller: controller, // attached the controller to listview
          itemCount: items.length,
          itemBuilder: (context,index){
          return Card(
            .......... card properties
           ),
         );
      }),

A Function to auto scroll to bottom of the listview when user perform and event like button click.

 void scrollDown(){
    final double goDown = controller.position.maxScrollExtent;
    controller.animateTo(goDown, duration: Duration(seconds: 2), curve: Curves.easeInCirc);
  }

A Button that call scrollDown function to scroll the listview to bottom

FloatingActionButton(
        onPressed:  scrollDown,
        child: iIcon(Icons.arrow_circle_down,size: 35,)
),

ListView Scroll to Top- Flutter

Similarly a function by which user can scroll to top of the listview

 void scrollUp(){
    final double goUp = 0;
    controller.animateTo(goUp, duration: Duration(seconds: 2), curve: Curves.easeInCirc);
  }

Scrolling to Top or Bottom in Flutter ListView – Complete Source Code

main.dart

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(

        colorScheme: ColorScheme.fromSeed(seedColor: Colors.grey),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final controller = ScrollController();
  final List<String> items = List.generate(100, (index) => 'Item ${index}');

  var isTopPosition = 0.0;

  void scrollDown(){
    final double goDown = controller.position.maxScrollExtent;
    controller.animateTo(goDown, duration: Duration(seconds: 2), curve: Curves.easeInCirc);

  }

  void scrollUp(){
    final double goUp = 0;
    controller.animateTo(goUp, duration: Duration(seconds: 2), curve: Curves.easeInCirc);

  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    controller.addListener(scrollPosition);
  }


  void scrollPosition(){
    final isTop = controller.position.pixels;
    setState(() {
      isTopPosition = isTop;
    });
  }



  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: ListView.builder(
        controller: controller,
          itemCount: items.length,
          itemBuilder: (context,index){
         return Card(
            color: index % 2 == 0 ? Colors.white70 : Colors.black87,
           child: Padding(
             padding: EdgeInsets.all(18),
             child: Text(items[index],style: TextStyle(fontSize: 18,color: index % 2 == 0 ? Colors.black87 : Colors.white70,),),
           ),
         );
      }),
      floatingActionButton: FloatingActionButton(
        onPressed: isTopPosition == 0 ? scrollDown : scrollUp,
        child: isTopPosition == 0 ? Icon(Icons.arrow_circle_down,size: 35,) : Icon(Icons.arrow_circle_up,size: 35,)
      ),
    );
  }
}

Conclusion

In this Article we show how to implement Flutter ListView Scroll to bottom or scroll to top by using Flutter Scroll Controller controller class.

Flutter Device Daemon Crash – Increase the maximum number of file handles available

0
Flutter Device Daemon Crash

Flutter developers who are making use of Android Studio are getting a warning message been shown when they create file or open a flutter project and the issue says it related to the Flutter Device Daemon Crash, The warning is advising you to “Increase the maximum number of file handles available.” This issue keep disrupt the flutter developer again an again while in the development workflow, but fear not, as there is a simple and straightforward solution to fix this problem. In this article, we’ll guide you through the steps to fix this warning and get your Flutter project back on track.

Follow Below Step to fix this issue

In windows open the Registry Editor:

Navigate to Below Path in registry editor:

HKEY_LOCAL_MACHINE -> SYSTEM -> CurrentControlSet -> Services -> WebClient -> Parameters

Now Look for file by name ‘FileSizelimitInBytes’, then select set the Base option select Decimal. In the “Value data” field, enter '4294967295', which is the maximum value for a 32-bit DWORD. That’s it Now Reboot the OS (Windows) This will fixed the warning been shown ‘Increase the maximum number of file handles available’.

Building Koi Mil Gaya Alien Communication Computer UI

0
koi mil gaya jadoo calling computer
koi mil gaya jadoo calling computer

Creating a user interface (UI) designing an alien communication computer’s user interface (UI) that looks like the one in the Bollywood film “Koi Mil Gaya” calls for integrating advanced technology Aliens. This is a fictitious UI concept that was inspired by the film  “Koi Mil Gaya”.

Koi Mil Gaya Alien Calling Computer UI Concept using HTML, CSS and JAVASCRIPT

Screenshot

Source Code – Clone the Project from Github Repository find the link at bottom of this article.

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml"
  xmlns:og="http://opengraphprotocol.org/schema/" lang="en">

<head>
  <meta charset="UTF-8">
  <title>Jadoo 👽💻</title>
  <meta name="description" content="Use this replica computer interface to call Jadoo from Koi Mil Gaya.">
  <meta name="author" content="Arjun Munji">
  <meta name="twitter:creator" content="@arjundot">
  <meta name="article:author" content="https://facebook.com/arjun.munji">
  <meta name="keywords" content="jadoo,koi mil gaya,hrithik roshan,alien,computer">
  <meta name="og:image" content="http://arjun.ninja/jadoo/assets/jadoo.png">
  <meta property="og:title" content="Jadoo 👽💻" />
  <meta property="og:url" content="http://arjun.ninja/jadoo" />
  <meta property="og:site_name" content="Arjun Munji" />
  <meta property="og:type" content="article" />

  <link rel="stylesheet" href="css/main.css">
  <link rel="icon" type="image/png" href="assets/favicon-32x32.png" sizes="32x32" />
  <link rel="icon" type="image/png" href="assets/favicon-16x16.png" sizes="16x16" />
</head>

<body>

  <div class="background-image"></div>
  <div id="monitor" class="crt content">
    <img class="background" src="assets/refresh.gif" />
    <div class="enter-text">
      <h1>press enter to continue</h1>
    </div>
    <div class="line vline nodisplay"></div>
    <div class="line hline nodisplay"></div>
    <div class="line hline1 nodisplay"></div>
    <div class="line hline2 nodisplay"></div>
    <div class='wrap nodisplay'>
      <div class='circle'>
        <div class="radar radar1"></div>
      </div>
      <div class='circle'>
        <div class="radar radar2"></div>
      </div>
      <div class='circle'>
        <div class="radar radar3"></div>
      </div>
      <div class='circle'></div>
    </div>
    <pre class="garbage garbage-left nodisplay">
    uplink = yes
     axis. = 40
      inc. = 48 pos
       dec = 57 neg

    signal = 80 b
  </pre>
    <pre class="garbage garbage-right nodisplay">
    B:066
    C:067
    D:068
    E:069
    F:070
  </pre>
    <div class="prompt nodisplay">
      PRESS KEYS <span class="prompt-key"></span>
    </div>
    <div class="sending nodisplay">
      SENDING
    </div>
    <div class="receiving nodisplay">
      RECEIVING
    </div>
    <div class="header nodisplay">
      JADOO v1 BY <a href="http://Developerrahul.com">Developer Rajat</a>
    </div>

    <div id="send" class="sea sea-left nodisplay" style="display:none;">
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
    </div>

    <!--                  -->


    <div id="receive" class="sea sea-right nodisplay" style="display:none;">
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
      <div class="wave nodisplay"></div>
    </div>
  </div>

  <audio data-key="66" src="assets/B.mp3"></audio>
  <audio data-key="67" src="assets/C.mp3"></audio>
  <audio data-key="68" src="assets/D.mp3"></audio>
  <audio data-key="69" src="assets/E.mp3"></audio>
  <audio data-key="70" src="assets/F.mp3"></audio>

  <script type="text/javascript" src="js/crt.js"></script>
  <script type="text/javascript">
    function playAudio(e) {
      console.log("--->", e);
      const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
      const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
      const sendDiv = document.getElementById('send');
      if (!audio) return; //exits the function altogether
      audio.currentTime = 0; //resets the playhead
      audio.play();
      sendDiv.style.display = 'flex';

      setTimeout(() => {
        const recDiv = document.getElementById('receive');
        recDiv.style.display = 'flex';
      }, 3000);

      ;

    }

    function stopSend(e) {
      setTimeout(() => {
        const sendDiv = document.getElementById('send');
        sendDiv.style.display = 'none';
        setTimeout(() => {
          const recDiv = document.getElementById('receive');
          recDiv.style.display = 'none';
        }, 1500)
      }, 3000);
    }
    window.addEventListener('keydown', playAudio);

    window.addEventListener('keyup', stopSend);

    onLoad();
  </script>
  <link rel="stylesheet" href="css/ellipse.css">
  <link rel="stylesheet" href="css/wave.css">
  <link rel="stylesheet" href="css/main.css">
</body>

</html>

crt.js

function onLoad(arg) {
    document.addEventListener("keydown", function(e) {
    if (e.keyCode == 13) {
      toggleFullScreen();
    }
  });
}

function toggleFullScreen() {
  if (!document.fullscreenElement) {
    // document.getElementById('monitor').webkitRequestFullscreen();

    function launchIntoFullscreen(element) {
      if(element.requestFullscreen) {
        element.requestFullscreen();
      } else if(element.mozRequestFullScreen) {
        element.mozRequestFullScreen();
      } else if(element.webkitRequestFullscreen) {
        element.webkitRequestFullscreen();
      } else if(element.msRequestFullscreen) {
        element.msRequestFullscreen();
      }
    }
    launchIntoFullscreen(document.documentElement);
  }
  document.querySelector('#monitor').style.backgroundColor="#161913";
  const nodisplays = document.querySelectorAll('.nodisplay');
  nodisplays.forEach(nodisplay => nodisplay.classList.remove('nodisplay'));

  document.querySelector('.enter-text').classList.add('nodisplay');
  document.querySelector('.background-image').classList.add('nodisplay');

  const promptKey = document.querySelector('.prompt-key');
  promptKey.innerHTML = "B C F E";
  promptKey.innerHTML += "\tB C E D";
  promptKey.innerHTML += "\tB C F E D C";
}

ellipse.css

.wrap {
  width: 50%;
  height: 50%;
  margin: 0;
  position: absolute;
  -webkit-perspective: 4000px;
  perspective: 4000px;
  -webkit-transform-style: preserve-3d;
  transform-style: preserve-3d;
  top: 55vh;
  left: 15vw;
}

.circle {
  -webkit-filter: blur(1px);
          filter: blur(1px);
  -webkit-transform-style: preserve-3d;
  transform-style: preserve-3d;
  box-sizing: border-box;
  opacity: 0;
  width: 30vh;
  height: 30vh;
  border: 1vh solid green;
  border-radius: 50%;
  position: absolute;
  top: 0;
  left: 0;
  -webkit-animation: spin 20s ease-in-out alternate infinite;
  animation: spin 20s ease-in-out alternate infinite;
}

.circle:nth-of-type(1) {
  -webkit-animation-delay: 500ms;
  animation-delay: 500ms;
}
.circle:nth-of-type(2) {
  -webkit-animation-delay: 1000ms;
  animation-delay: 1000ms;
}
.circle:nth-of-type(3) {
  -webkit-animation-delay: 1500ms;
  animation-delay: 1500ms;
}
.circle:nth-of-type(4) {
  -webkit-animation-delay: 2000ms;
  animation-delay: 2000ms;
}
.circle:nth-of-type(5) {
  -webkit-animation-delay: 2500ms;
  animation-delay: 2500ms;
}

@-webkit-keyframes spin {
  0% {
    -webkit-transform: rotateY(0deg) rotateX(0deg);
    opacity: 1;
  }
  25% {
    -webkit-transform: rotateY(180deg) rotateX(360deg);
  }
  50% {
    -webkit-transform: rotateY(540deg) rotateX(540deg);
  }
  75% {
    -webkit-transform: rotateY(720deg) rotateX(900deg);
  }
  100% {
    -webkit-transform: rotateY(900deg) rotateX(1080deg);
    opacity: 1;
  }
}
@keyframes spin {
  0% {
    -webkit-transform: rotateY(0deg) rotateX(0deg);
    transform: rotateY(0deg) rotateX(0deg);
    opacity: 1;
  }
  25% {
    -webkit-transform: rotateY(180deg) rotateX(360deg);
    transform: rotateY(180deg) rotateX(360deg);
  }
  50% {
    -webkit-transform: rotateY(540deg) rotateX(540deg);
    transform: rotateY(540deg) rotateX(540deg);
  }
  75% {
    -webkit-transform: rotateY(720deg) rotateX(900deg);
    transform: rotateY(720deg) rotateX(900deg);
  }
  100% {
    -webkit-transform: rotateY(900deg) rotateX(1080deg);
    transform: rotateY(900deg) rotateX(1080deg);
    opacity: 1;
  }
}

.circle1 {
  height: 40vh;
  width: 20vh;
}

.circle2 {
  width: 45vh;
  height: 25vh;
}

.circle3 {
  height: 10vh;
  width: 10vh;
}

main.css

@import url('https://fonts.googleapis.com/css?family=VT323');

body {
  pointer-events: none;
  cursor: none;
  padding: 0;
  margin: 0;
  text-align: center;
  overflow: hidden;
}

.crt {
 letter-spacing: 1px;
 font-family: 'VT323', monospace;
 color: #95e208;
 -webkit-filter: blur(0.5px);
          filter: blur(0.5px);
 text-transform: uppercase;
 font-size: 3vw;
}

#monitor {
  z-index: 2;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100vw;
  height: 100vh;
}

.content {
  white-space: nowrap;
  text-align: center;
  display: inline-block;
}

.background {
  pointer-events: none;
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.background {
  opacity: .01;
}

.enter-text {
  -webkit-filter: blur(0.6px);
  background: black;
  padding: 10px 20px 10px 20px;
  border: 5px double #95e208;
  box-shadow: 1px 1px 1px #95e208;
}

.background-image {
  right: -10px;
  bottom: -10px;
  top: -10px;
  left: -10px;
  background-image: url(../assets/space.jpg), radial-gradient(#0F0, #000), repeating-linear-gradient(transparent 0, rgba(0, 0, 0, 0.1) 2.5px, transparent 5px);
  background-size: cover;
  background-position: center;
  background-blend-mode: overlay;
  position: fixed;
  -webkit-filter: blur(5px);
  display: block;
  z-index: 1;
}

.content {
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.25);
  left: 0;
  position: fixed;
  right: 0;
  z-index: 2;
}

.line {
  height: 0.9vh;
  background: green;
  position: fixed;
  transform-origin: 50%;
  -webkit-filter: blur(0.15vh);
}

.vline {
  transform: rotate(90deg);
  width: 91vh;
}

.hline {
  width: 100vw;
  top: 45vh;
}

.hline1 {
  width: 100vw;
  top: 4%;
}

.hline2 {
  width: 100vw;
  top: 95%;
}

.prompt {
  font-size: 4.5vh;
  position: fixed;
  bottom: -0.5vh;
  left: 1vw;
  filter: blur(0.15vh);
  font-family: 'VT323', monospace;
  animation:pulse 0.55s infinite alternate
}

@keyframes pulse {
  from { color: green; }
  to { color: yellow; }
}

.prompt-key {
  color: red;
  font-weight: 700;
}

.sending, .receiving {
  position: fixed;
  top: 5vh;
  filter: blur(0.15vh);
}

.sending {
  left: 5vw;
}

.receiving {
  left: 55vw;
}

.sea {
  position: fixed;
  top: 5.5vh;
}

.sea-left {
  transform: rotateX(67deg) rotateZ(-223deg) rotateY(0deg);
  left: 10vw;
}

.sea-right {
  transform: rotateX(67deg) rotateZ(-57deg) rotateY(0deg);
  left: 60vw;
}

.header {
  position: fixed;
  top: 0;
  right: 1vh;
  text-transform: none;
  font-size: 4vh;
  filter: blur(0.15vh);
}

a {
  text-decoration: none;
  color: #95e208;
  cursor: hand;
  pointer-events: all;
}

a:hover {
  background-color: #95e208;
  color: #161913;
}

.radar {
  width:50%;
  height:6px;
  background:green;
  position: absolute;
  top:50%;
  transform-origin: 100%;
  transition: all 0.05s;
  transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
}

.radar1 {
  transform: rotate(-30deg);
}

.radar2 {
  transform: rotate(90deg);
}

.radar3 {
  transform: rotate(210deg);
}

.garbage {
  filter: blur(0.15vh);
  position: fixed;
  top: 53vh;
  text-align: justify;
  margin: 0;
}

.garbage-left {
  left: 50vw;
  font-size: 4.5vh;
}

.garbage-right  {
  right: 0vw;
  font-size: 5vh;
}

pre {
  font-family: 'VT323', monospace;
}

.nodisplay {
  display: none;
}

wave.css

.sea {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
      flex-wrap: wrap;
  width: 25vw;
  height: 25vw;
  -webkit-transform-style: preserve-3d;
          transform-style: preserve-3d;
  -webkit-transform: rotateX(70deg) rotateZ(35deg);
          transform: rotateX(70deg) rotateZ(35deg);
}

.wave {
  filter: blur(0.1vw);
  width: 2.5vw;
  height: 2.5vw;
  background: green;
  -webkit-transform: translateZ(0px) rotateX(90deg);
          transform: translateZ(0px) rotateX(90deg);
  -webkit-transform-origin: top;
          transform-origin: top;
  margin: -22px 3px;
  -webkit-animation: wave 1s ease-in-out infinite alternate;
          animation: wave 1s ease-in-out infinite alternate;
  opacity: .7;
  border-radius: 0 0 2px 2px;
}

.wave:nth-child(121) {
  -webkit-animation-delay: 1.694s;
          animation-delay: 1.694s;
}

.wave:nth-child(120) {
  -webkit-animation-delay: 1.68s;
          animation-delay: 1.68s;
}

.wave:nth-child(119) {
  -webkit-animation-delay: 1.666s;
          animation-delay: 1.666s;
}

.wave:nth-child(118) {
  -webkit-animation-delay: 1.652s;
          animation-delay: 1.652s;
}

.wave:nth-child(117) {
  -webkit-animation-delay: 1.638s;
          animation-delay: 1.638s;
}

.wave:nth-child(116) {
  -webkit-animation-delay: 1.624s;
          animation-delay: 1.624s;
}

.wave:nth-child(115) {
  -webkit-animation-delay: 1.61s;
          animation-delay: 1.61s;
}

.wave:nth-child(114) {
  -webkit-animation-delay: 1.596s;
          animation-delay: 1.596s;
}

.wave:nth-child(113) {
  -webkit-animation-delay: 1.582s;
          animation-delay: 1.582s;
}

.wave:nth-child(112) {
  -webkit-animation-delay: 1.568s;
          animation-delay: 1.568s;
}

.wave:nth-child(111) {
  -webkit-animation-delay: 1.554s;
          animation-delay: 1.554s;
}

.wave:nth-child(110) {
  -webkit-animation-delay: 1.54s;
          animation-delay: 1.54s;
}

.wave:nth-child(109) {
  -webkit-animation-delay: 1.526s;
          animation-delay: 1.526s;
}

.wave:nth-child(108) {
  -webkit-animation-delay: 1.512s;
          animation-delay: 1.512s;
}

.wave:nth-child(107) {
  -webkit-animation-delay: 1.498s;
          animation-delay: 1.498s;
}

.wave:nth-child(106) {
  -webkit-animation-delay: 1.484s;
          animation-delay: 1.484s;
}

.wave:nth-child(105) {
  -webkit-animation-delay: 1.47s;
          animation-delay: 1.47s;
}

.wave:nth-child(104) {
  -webkit-animation-delay: 1.456s;
          animation-delay: 1.456s;
}

.wave:nth-child(103) {
  -webkit-animation-delay: 1.442s;
          animation-delay: 1.442s;
}

.wave:nth-child(102) {
  -webkit-animation-delay: 1.428s;
          animation-delay: 1.428s;
}

.wave:nth-child(101) {
  -webkit-animation-delay: 1.414s;
          animation-delay: 1.414s;
}

.wave:nth-child(100) {
  -webkit-animation-delay: 1.4s;
          animation-delay: 1.4s;
}

.wave:nth-child(99) {
  -webkit-animation-delay: 1.386s;
          animation-delay: 1.386s;
}

.wave:nth-child(98) {
  -webkit-animation-delay: 1.372s;
          animation-delay: 1.372s;
}

.wave:nth-child(97) {
  -webkit-animation-delay: 1.358s;
          animation-delay: 1.358s;
}

.wave:nth-child(96) {
  -webkit-animation-delay: 1.344s;
          animation-delay: 1.344s;
}

.wave:nth-child(95) {
  -webkit-animation-delay: 1.33s;
          animation-delay: 1.33s;
}

.wave:nth-child(94) {
  -webkit-animation-delay: 1.316s;
          animation-delay: 1.316s;
}

.wave:nth-child(93) {
  -webkit-animation-delay: 1.302s;
          animation-delay: 1.302s;
}

.wave:nth-child(92) {
  -webkit-animation-delay: 1.288s;
          animation-delay: 1.288s;
}

.wave:nth-child(91) {
  -webkit-animation-delay: 1.274s;
          animation-delay: 1.274s;
}

.wave:nth-child(90) {
  -webkit-animation-delay: 1.26s;
          animation-delay: 1.26s;
}

.wave:nth-child(89) {
  -webkit-animation-delay: 1.246s;
          animation-delay: 1.246s;
}

.wave:nth-child(88) {
  -webkit-animation-delay: 1.232s;
          animation-delay: 1.232s;
}

.wave:nth-child(87) {
  -webkit-animation-delay: 1.218s;
          animation-delay: 1.218s;
}

.wave:nth-child(86) {
  -webkit-animation-delay: 1.204s;
          animation-delay: 1.204s;
}

.wave:nth-child(85) {
  -webkit-animation-delay: 1.19s;
          animation-delay: 1.19s;
}

.wave:nth-child(84) {
  -webkit-animation-delay: 1.176s;
          animation-delay: 1.176s;
}

.wave:nth-child(83) {
  -webkit-animation-delay: 1.162s;
          animation-delay: 1.162s;
}

.wave:nth-child(82) {
  -webkit-animation-delay: 1.148s;
          animation-delay: 1.148s;
}

.wave:nth-child(81) {
  -webkit-animation-delay: 1.134s;
          animation-delay: 1.134s;
}

.wave:nth-child(80) {
  -webkit-animation-delay: 1.12s;
          animation-delay: 1.12s;
}

.wave:nth-child(79) {
  -webkit-animation-delay: 1.106s;
          animation-delay: 1.106s;
}

.wave:nth-child(78) {
  -webkit-animation-delay: 1.092s;
          animation-delay: 1.092s;
}

.wave:nth-child(77) {
  -webkit-animation-delay: 1.078s;
          animation-delay: 1.078s;
}

.wave:nth-child(76) {
  -webkit-animation-delay: 1.064s;
          animation-delay: 1.064s;
}

.wave:nth-child(75) {
  -webkit-animation-delay: 1.05s;
          animation-delay: 1.05s;
}

.wave:nth-child(74) {
  -webkit-animation-delay: 1.036s;
          animation-delay: 1.036s;
}

.wave:nth-child(73) {
  -webkit-animation-delay: 1.022s;
          animation-delay: 1.022s;
}

.wave:nth-child(72) {
  -webkit-animation-delay: 1.008s;
          animation-delay: 1.008s;
}

.wave:nth-child(71) {
  -webkit-animation-delay: 0.994s;
          animation-delay: 0.994s;
}

.wave:nth-child(70) {
  -webkit-animation-delay: 0.98s;
          animation-delay: 0.98s;
}

.wave:nth-child(69) {
  -webkit-animation-delay: 0.966s;
          animation-delay: 0.966s;
}

.wave:nth-child(68) {
  -webkit-animation-delay: 0.952s;
          animation-delay: 0.952s;
}

.wave:nth-child(67) {
  -webkit-animation-delay: 0.938s;
          animation-delay: 0.938s;
}

.wave:nth-child(66) {
  -webkit-animation-delay: 0.924s;
          animation-delay: 0.924s;
}

.wave:nth-child(65) {
  -webkit-animation-delay: 0.91s;
          animation-delay: 0.91s;
}

.wave:nth-child(64) {
  -webkit-animation-delay: 0.896s;
          animation-delay: 0.896s;
}

.wave:nth-child(63) {
  -webkit-animation-delay: 0.882s;
          animation-delay: 0.882s;
}

.wave:nth-child(62) {
  -webkit-animation-delay: 0.868s;
          animation-delay: 0.868s;
}

.wave:nth-child(61) {
  -webkit-animation-delay: 0.854s;
          animation-delay: 0.854s;
}

.wave:nth-child(60) {
  -webkit-animation-delay: 0.84s;
          animation-delay: 0.84s;
}

.wave:nth-child(59) {
  -webkit-animation-delay: 0.826s;
          animation-delay: 0.826s;
}

.wave:nth-child(58) {
  -webkit-animation-delay: 0.812s;
          animation-delay: 0.812s;
}

.wave:nth-child(57) {
  -webkit-animation-delay: 0.798s;
          animation-delay: 0.798s;
}

.wave:nth-child(56) {
  -webkit-animation-delay: 0.784s;
          animation-delay: 0.784s;
}

.wave:nth-child(55) {
  -webkit-animation-delay: 0.77s;
          animation-delay: 0.77s;
}

.wave:nth-child(54) {
  -webkit-animation-delay: 0.756s;
          animation-delay: 0.756s;
}

.wave:nth-child(53) {
  -webkit-animation-delay: 0.742s;
          animation-delay: 0.742s;
}

.wave:nth-child(52) {
  -webkit-animation-delay: 0.728s;
          animation-delay: 0.728s;
}

.wave:nth-child(51) {
  -webkit-animation-delay: 0.714s;
          animation-delay: 0.714s;
}

.wave:nth-child(50) {
  -webkit-animation-delay: 0.7s;
          animation-delay: 0.7s;
}

.wave:nth-child(49) {
  -webkit-animation-delay: 0.686s;
          animation-delay: 0.686s;
}

.wave:nth-child(48) {
  -webkit-animation-delay: 0.672s;
          animation-delay: 0.672s;
}

.wave:nth-child(47) {
  -webkit-animation-delay: 0.658s;
          animation-delay: 0.658s;
}

.wave:nth-child(46) {
  -webkit-animation-delay: 0.644s;
          animation-delay: 0.644s;
}

.wave:nth-child(45) {
  -webkit-animation-delay: 0.63s;
          animation-delay: 0.63s;
}

.wave:nth-child(44) {
  -webkit-animation-delay: 0.616s;
          animation-delay: 0.616s;
}

.wave:nth-child(43) {
  -webkit-animation-delay: 0.602s;
          animation-delay: 0.602s;
}

.wave:nth-child(42) {
  -webkit-animation-delay: 0.588s;
          animation-delay: 0.588s;
}

.wave:nth-child(41) {
  -webkit-animation-delay: 0.574s;
          animation-delay: 0.574s;
}

.wave:nth-child(40) {
  -webkit-animation-delay: 0.56s;
          animation-delay: 0.56s;
}

.wave:nth-child(39) {
  -webkit-animation-delay: 0.546s;
          animation-delay: 0.546s;
}

.wave:nth-child(38) {
  -webkit-animation-delay: 0.532s;
          animation-delay: 0.532s;
}

.wave:nth-child(37) {
  -webkit-animation-delay: 0.518s;
          animation-delay: 0.518s;
}

.wave:nth-child(36) {
  -webkit-animation-delay: 0.504s;
          animation-delay: 0.504s;
}

.wave:nth-child(35) {
  -webkit-animation-delay: 0.49s;
          animation-delay: 0.49s;
}

.wave:nth-child(34) {
  -webkit-animation-delay: 0.476s;
          animation-delay: 0.476s;
}

.wave:nth-child(33) {
  -webkit-animation-delay: 0.462s;
          animation-delay: 0.462s;
}

.wave:nth-child(32) {
  -webkit-animation-delay: 0.448s;
          animation-delay: 0.448s;
}

.wave:nth-child(31) {
  -webkit-animation-delay: 0.434s;
          animation-delay: 0.434s;
}

.wave:nth-child(30) {
  -webkit-animation-delay: 0.42s;
          animation-delay: 0.42s;
}

.wave:nth-child(29) {
  -webkit-animation-delay: 0.406s;
          animation-delay: 0.406s;
}

.wave:nth-child(28) {
  -webkit-animation-delay: 0.392s;
          animation-delay: 0.392s;
}

.wave:nth-child(27) {
  -webkit-animation-delay: 0.378s;
          animation-delay: 0.378s;
}

.wave:nth-child(26) {
  -webkit-animation-delay: 0.364s;
          animation-delay: 0.364s;
}

.wave:nth-child(25) {
  -webkit-animation-delay: 0.35s;
          animation-delay: 0.35s;
}

.wave:nth-child(24) {
  -webkit-animation-delay: 0.336s;
          animation-delay: 0.336s;
}

.wave:nth-child(23) {
  -webkit-animation-delay: 0.322s;
          animation-delay: 0.322s;
}

.wave:nth-child(22) {
  -webkit-animation-delay: 0.308s;
          animation-delay: 0.308s;
}

.wave:nth-child(21) {
  -webkit-animation-delay: 0.294s;
          animation-delay: 0.294s;
}

.wave:nth-child(20) {
  -webkit-animation-delay: 0.28s;
          animation-delay: 0.28s;
}

.wave:nth-child(19) {
  -webkit-animation-delay: 0.266s;
          animation-delay: 0.266s;
}

.wave:nth-child(18) {
  -webkit-animation-delay: 0.252s;
          animation-delay: 0.252s;
}

.wave:nth-child(17) {
  -webkit-animation-delay: 0.238s;
          animation-delay: 0.238s;
}

.wave:nth-child(16) {
  -webkit-animation-delay: 0.224s;
          animation-delay: 0.224s;
}

.wave:nth-child(15) {
  -webkit-animation-delay: 0.21s;
          animation-delay: 0.21s;
}

.wave:nth-child(14) {
  -webkit-animation-delay: 0.196s;
          animation-delay: 0.196s;
}

.wave:nth-child(13) {
  -webkit-animation-delay: 0.182s;
          animation-delay: 0.182s;
}

.wave:nth-child(12) {
  -webkit-animation-delay: 0.168s;
          animation-delay: 0.168s;
}

.wave:nth-child(11) {
  -webkit-animation-delay: 0.154s;
          animation-delay: 0.154s;
}

.wave:nth-child(10) {
  -webkit-animation-delay: 0.14s;
          animation-delay: 0.14s;
}

.wave:nth-child(9) {
  -webkit-animation-delay: 0.126s;
          animation-delay: 0.126s;
}

.wave:nth-child(8) {
  -webkit-animation-delay: 0.112s;
          animation-delay: 0.112s;
}

.wave:nth-child(7) {
  -webkit-animation-delay: 0.098s;
          animation-delay: 0.098s;
}

.wave:nth-child(6) {
  -webkit-animation-delay: 0.084s;
          animation-delay: 0.084s;
}

.wave:nth-child(5) {
  -webkit-animation-delay: 0.07s;
          animation-delay: 0.07s;
}

.wave:nth-child(4) {
  -webkit-animation-delay: 0.056s;
          animation-delay: 0.056s;
}

.wave:nth-child(3) {
  -webkit-animation-delay: 0.042s;
          animation-delay: 0.042s;
}

.wave:nth-child(2) {
  -webkit-animation-delay: 0.028s;
          animation-delay: 0.028s;
}

@-webkit-keyframes wave {
  from {
    height: 8px;
  }
  to {
    height: 40px;
  }
}

@keyframes wave {
  from {
    height: 8px;
  }
  to {
    height: 40px;
  }
}

Simply Clone the Complete Project from Github Repository

Downloading Files/Media in Flutter – flutter_media_downloader

0
How to Implement Download Option in Flutter
How to Implement Download Option in Flutter

Downloading files in flutter is must required feature to be added into any flutter where their are document or any kind of files that the user want to download & store if for later usage.

Media download in flutter is seamless bring media content to your flutter application.

Flutter Downloader – How to implement files downloading in flutter application

To add download feature in flutter application we will make use of a package called flutter_media_downloader, This package has capability of downloading any kind of files like, Images, Videos, Document like pdf, docx etc.

Video Tutorial

Download Files in Flutter

1. Create a Flutter Project or Open Existing

Create a new Flutter Project or Open any Existing Flutter in your favorite IDE VSCode or Android Studio. I use android studio for building flutter application.


2. Add flutter_media_downloader package.

In your flutter project open pubspec.yaml files and under dependencies section add the flutter media downloader package as shown below

#screenshot

and then run flutter pub get to download the package as external libraries.


3. Add permission for Android & IOS

As the files or media get downloaded from Internet We need Internet Permission & to store the downloaded files locally in mobile devices we need Storage Permission.

Android: Open AndroidManifest.xml file and add below lines

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

iOS: Open info.plist files and add below lines

<dict>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>We need access to Photo library</string>
</dict>

4. How to Implement flutter media downloader

Complete Source Code

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_media_downloader/flutter_media_downloader.dart';

void main() async{
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(

        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _flutterDownload = MediaDownload();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () async{
            _flutterDownload.downloadMedia(context, 'https://32net.id/bukaheula/share/otQ9czP4vdLTyiJdmlAXaNK76xKtu38ykwnTm8q0.pdf');
          }, child: Text('Download'),

        ),
      ),
    );
  }
}