Create Countdown Timer in Efficient Way Using JavaScript

In some projects, We need a countdown timer like recently I want. I googled almost three hours to create Countdown Timer but in an efficient way. Why did I call efficient way? Just be with us you'll know the reason.

The requirement of the project is to implement more than one countdown timer in a single page. But some of the following challenges I have to face like:

  • The date was in UnixTimestamp format. So I've to convert it into a readable format.
  • Multiple countdown timers need on a single page.
  • Don't want to put javascript code in a loop for multiple timers.
  • Want very clean and simple code.

If you're also facing any of these types of problem to implement Countdown timer then you're in the right place. Now let's dive in the code and I’ll show you the code and then explain, line-by-line. 🙂

Do you know the difference between:

See More:
Promise Vs Callback function in Javascript
Difference between a promise and a callback in Javascript: Lets...

Library to implement Countdown Timer

First of all, you've to add two libraries in your <head> section.

Create Countdown Timer using JavaScript
Create Countdown Timer using JavaScript
<script type="text/javascript" src="http://code.jquery.com/jquery-git.js"></script>
<scripttype="text/javascript"src="http://cdn.rawgit.com/hilios/jQuery.countdown/2.1.0/dist/jquery.countdown.min.js"></script>
After that add the magic code above of </head> section.
Magical code to Create Countdown Timer using JavaScript
Magical code to Create Countdown Timer using JavaScript
<script type="text/javascript">
    $(function(){
        $('.countdown').each(function(){
            $(this).countdown($(this).attr('value'), function(event) {
            $(this).text(event.strftime('%D:%H:%M:%S')
         );
            });
        });
    });
</script>
That's it !! Yes, coders its that simple. Now let show our countdown timer in our UI section. For that what you've to so.

Looking for Javascript animation engine:

See More:
AnimeJs a Javascript animation engine
Animejs is a lightweight JavaScript animation engine library. It can...
See More:
ScrollReveal Js A javascript library to reveal elements
ScrollReveal Js is a library used to reveal elements when...
You just need to add a single line of code:
Beauty of this code
The beauty of this code
<span class="countdown" value="2018/10/18 11:09:36"></span>
Hope you like this tutorial. Try this and comment us where you add this countdown timer in your project. You can see a demo here.
Recommended articles:
See More:
Difference between equality operators == and === in Javascript
Comparison operators in Javascript. This is equality operators. == and...

Let Vs Var : Battle between modern javascript keywords

Let Vs Var : Let's the battle begins

There are two important javascript keywords ( let and const ) introduced by ECMAScript 2015. These two keywords provide Block scope in Javascript.

Before this, Javascript had only two type of scopes i) Global Scope and ii) Local Scope

JavaScript Block Scope

Variables declared with the var keyword inside a block {} can be accessed from outside the block.


{ 
    var x = 2; 
}
// x CAN be used here

Variables declared with the let keyword can have Block Scope and can't be accessed from outside of the block.


{ 
    let x = 2;
}
// x can NOT be used here

 

Let's check out some examples:


var x = 10;
// Here x is 10
{ 
    var x = 2;
    // Here x is 2
}
// Here x is 2

Here var x can not have block scope. That'why the value of x of line 1  overwrites by the value of x of line 4.


var x = 10;
// Here x is 10
{ 
    let x = 2;
    // Here x is 2
}
// Here x is 10

Here let x can have block scope. It means the value of x with prefix let has scope inside block only. This value doesn't available outside of the block.

Let keyword with Loop Scope


var i = 5;
for (var i = 0; i < 10; i++) {
    // some statements
}
// Here i is 10

Here, using var,  variable declared on line number 1. Then redeclared inside the loop. Value of var i overwrites everytime loop runs.

Using let in a loop:


let i = 5;
for (let i = 0; i < 10; i++) {
    // value of available inside this loop only
}
// Here i is 5

Here, using let,  variable declared on line number 1 has scope globally. Then variable redeclared inside the loop has scope inside the loop.

Redeclaring a var variable with let, in the same scope, or in the same block, is not allowed:

Example


var x = 2;       // Allowed
let x = 3;       // Not allowed

{
    var x = 4;   // Allowed
    let x = 5   // Not allowed
}

Redeclaring a variable with let, in the same scope, or in the same block, is not allowed:

Example


let x = 2;       // Allowed
let x = 3;       // Not allowed

{
    let x = 4;   // Allowed
    let x = 5;   // Not allowed
}

Redeclaring a variable with let, in another scope, or in another block, is allowed:

Example


let x = 2;       // Allowed

{
    let x = 3;   // Allowed
}

{
    let x = 4;   // Allowed
}

With the above explanation, I can surely tell that now you have the total idea about the difference between let and var variables.

Promise Vs Callback function in Javascript

Difference between a promise and a callback in Javascript:

Let's start the battle. Promise Vs Callback

Everything you can do with promises you can do with callbacks.
The deep reason why promises are often better is that
the combination of multiple promises just works, while combining multiple callbacks often doesn't.

Check this link: Promises: A complete explanation of modern JavaScript

For the example you gave of a single callback versus a single promise, it's true there's no significant difference. It's when you have a combination of callbacks (Callback Hell) versus a combination of promises that the promise-based code tends to look much nicer.

Let's check out an example of Callback Hell:

  
fs.readdir(source, function (err, files) {
  if (err) {
    console.log('Error finding files: ' + err)
  } else {
    files.forEach(function (filename, fileIndex) {
      console.log(filename)
      gm(source + filename).size(function (err, values) {
        if (err) {
          console.log('Error identifying file size: ' + err)
        } else {
          console.log(filename + ' : ' + values)
          aspect = (values.width / values.height)
          widths.forEach(function (width, widthIndex) {
            height = Math.round(width / aspect)
            console.log('resizing ' + filename + 'to ' + height + 'x' + height)
            this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
              if (err) console.log('Error writing file: ' + err)
            })
          }.bind(this))
        }
      })
    })
  }
})

It's not easily maintainable.

Promise has an advantage over callback is by the uniform handling of return values and uncaught exceptions. With callbacks, how an exception gets handled may depend entirely on which of the many nested callbacks threw it.

Arrow Function : A concise and fat form of javascript function

Arrow Function both make your code more concise while also making the “this” keyword more manageable. It allows having implicit return without having return keyword.

Benefits of Arrow Function:

  1. It has a shorter syntax than a function expression.
  2. It does not have its own this, super, arguments, new.target.

Read also: How to use Conditional/Ternary Operator in Javascript

Let's see the first benefit:

Let's take a look at the traditional function with one parameter:

 function functionName(arg) {
   return arg + 3;
 }
funcName(2); 

OR


var func = function functionName(arg) {
  return arg + 3;
};
func(2);

Now the same example using arrow function


var func = (arg) => { arg + 2 }
funcName(2);

If { } contains single statement. You can omit the parentheses and write


var func = (arg) => arg + 2 
funcName(2);

Let's take a look at the traditional function with multiple parameters:

 function functionName(x,y) {
   return x + y;
 }
funcName(2,3); 

OR


var funcName = function (x,y) {
  return x + y;
}
funcName(2,3);

Let's check out the same example using arrow functions:


var funcName = (x,y) =>  x + y  
funcName(2,3);

Now I am taking another example of a function with no parameter:

 function functionName() {
   return "Arrow function by DasJs";
 }
funcName(); 

OR


var funcName = function () {
  return "Arrow function by DasJs";
}
funcName();

The same example using Arrow functions:


var funcName = () =>  "Arrow function by DasJs"  
funcName();

 

If you have a single parameter, you can remove parenthesis of the parameter. You can also write as below:


var funcName = arg => arg + 2  
funcName();

 

Signature Pad JS: How to use in websites or apps

Signature Pad is a javascript library using for drawing smooth signature. It works on HTML canvas. It is compatible with all modern browsers. No need to add any external libraries.
It has an ability to record the drawn signature in JSON for later use.

How to use Signature Pad JS:

Include CSS file before closing tag of 'head'. Download

 <link rel='stylesheet'  href='path to css/signature-pad-1.css' type='text/css' media='all' /> 

It has some styles for the body tag. Maybe not suitable for your project. You can change it as per your requirement.

Include this library just before the closing tag of 'body'. Download

 <script src="js/signature_pad.umd.js"></script> 

Now you have included all files required for its working.

Now write some HTML code to run.


<div id="signature-pad" class="signature-pad">
  <div class="signature-pad--body">
    <canvas></canvas>
  </div>
  <div class="signature-pad--footer">
    <div class="description">Sign above</div>

    <div class="signature-pad--actions">
      <div>
        <button type="button" class="button clear" data-action="clear">Clear</button>
        <button type="button" class="button" data-action="change-color">Change color</button>
        <button type="button" class="button" data-action="undo">Undo</button>
      </div>
      <div>
        <button type="button" class="button save" data-action="save-png">Save as PNG</button>
        <button type="button" class="button save" data-action="save-jpg">Save as JPG</button>
        <button type="button" class="button save" data-action="save-svg">Save as SVG</button>
      </div>
    </div>
  </div>
</div>

It's time to make it live. So, write some javascript code make this working.

 


var wrapper = document.getElementById("signature-pad");
var clearButton = wrapper.querySelector("[data-action=clear]");
var changeColorButton = wrapper.querySelector("[data-action=change-color]");
var undoButton = wrapper.querySelector("[data-action=undo]");
var savePNGButton = wrapper.querySelector("[data-action=save-png]");
var saveJPGButton = wrapper.querySelector("[data-action=save-jpg]");
var saveSVGButton = wrapper.querySelector("[data-action=save-svg]");
var canvas = wrapper.querySelector("canvas");
var signaturePad = new SignaturePad(canvas, {
  // It's Necessary to use an opaque color when saving image as JPEG;
  // this option can be omitted if only saving as PNG or SVG
  backgroundColor: 'rgb(255, 255, 255)'
});

// Adjust canvas coordinate space taking into account pixel ratio,
// to make it look crisp on mobile devices.
// This also causes canvas to be cleared.
function resizeCanvas() {
  // When zoomed out to less than 100%, for some very strange reason,
  // some browsers report devicePixelRatio as less than 1
  // and only part of the canvas is cleared then.
  var ratio =  Math.max(window.devicePixelRatio || 1, 1);

  // This part causes the canvas to be cleared
  canvas.width = canvas.offsetWidth * ratio;
  canvas.height = canvas.offsetHeight * ratio;
  canvas.getContext("2d").scale(ratio, ratio);

  // This library does not listen for canvas changes, so after the canvas is automatically
  // cleared by the browser, SignaturePad#isEmpty might still return false, even though the
  // canvas looks empty, because the internal data of this library wasn't cleared. To make sure
  // that the state of this library is consistent with visual state of the canvas, you
  // have to clear it manually.
  signaturePad.clear();
}

// On mobile devices it might make more sense to listen to orientation change,
// rather than window resize events.
window.onresize = resizeCanvas;
resizeCanvas();

function download(dataURL, filename) {
  if (navigator.userAgent.indexOf("Safari") > -1 && navigator.userAgent.indexOf("Chrome") === -1) {
    window.open(dataURL);
  } else {
    var blob = dataURLToBlob(dataURL);
    var url = window.URL.createObjectURL(blob);

    var a = document.createElement("a");
    a.style = "display: none";
    a.href = url;
    a.download = filename;

    document.body.appendChild(a);
    a.click();

    window.URL.revokeObjectURL(url);
  }
}

// One could simply use Canvas#toBlob method instead, but it's just to show
// that it can be done using result of SignaturePad#toDataURL.
function dataURLToBlob(dataURL) {
  // Code taken from https://github.com/ebidel/filer.js
  var parts = dataURL.split(';base64,');
  var contentType = parts[0].split(":")[1];
  var raw = window.atob(parts[1]);
  var rawLength = raw.length;
  var uInt8Array = new Uint8Array(rawLength);

  for (var i = 0; i < rawLength; ++i) {
    uInt8Array[i] = raw.charCodeAt(i);
  }

  return new Blob([uInt8Array], { type: contentType });
}

clearButton.addEventListener("click", function (event) {
  signaturePad.clear();
});

undoButton.addEventListener("click", function (event) {
  var data = signaturePad.toData();

  if (data) {
    data.pop(); // remove the last dot or line
    signaturePad.fromData(data);
  }
});

changeColorButton.addEventListener("click", function (event) {
  var r = Math.round(Math.random() * 255);
  var g = Math.round(Math.random() * 255);
  var b = Math.round(Math.random() * 255);
  var color = "rgb(" + r + "," + g + "," + b +")";

  signaturePad.penColor = color;
});

savePNGButton.addEventListener("click", function (event) {
  if (signaturePad.isEmpty()) {
    alert("Please provide a signature first.");
  } else {
    var dataURL = signaturePad.toDataURL();
    download(dataURL, "signature.png");
  }
});

saveJPGButton.addEventListener("click", function (event) {
  if (signaturePad.isEmpty()) {
    alert("Please provide a signature first.");
  } else {
    var dataURL = signaturePad.toDataURL("image/jpeg");
    download(dataURL, "signature.jpg");
  }
});

saveSVGButton.addEventListener("click", function (event) {
  if (signaturePad.isEmpty()) {
    alert("Please provide a signature first.");
  } else {
    var dataURL = signaturePad.toDataURL('image/svg+xml');
    download(dataURL, "signature.svg");
  }
});

That's it. If you face any problem in adding this in your project. Feel free to comment here. I will try to reply you as soon as possible.

Check following demo:

 

Promises: A complete explanation of modern JavaScript

JavaScript Promises: Allow us to first discuss JavaScript and its concurrency. JavaScript is single-threaded. It means all the things happen in a sequence as it's written, line-by-line. What do you think the results of the following example:

console.log("I am first");
setTimeout(function(){console.log("I am second");},3000);
console.log("I am third");
setTimeout(function(){console.log("I am fourth");},1000);

Your expected answer: 

  1. I am first
  2. I am second
  3. I am third
  4. I am fourth

But actual answer: 

  1. I am first
  2. I am third
  3. I am fourth
  4. I am second

The explanation above example without Promises:

Actually, 1st executed immediately. But the 2nd line has to wait for 3 seconds. So, 3rd line executed after 1st line. 4th line follow this sequence because it has to wait for 1 second. At the end 2nd line executed.

In a web app, You could use multiple asynchronous tasks and any if any task depends on early executed task's response, then you could get unexpected results.

Check this link:  Promise Vs Callback function in Javascript

A promise is a javascript object, represents a value may not available but will be available at some point in the future. It wraps an async task and notifies when it's completed. If you use the promise API for an asynchronous call to a remote web service. You will create a javascript object of promise that holds the data available in the future.

var promise = new Promise(function(resolve, reject) {
// do a thing, possibly async, then…

if (/* everything turned out fine */) {
resolve("Stuff worked!");
}
else {
reject(Error("It broke"));
}
});

This constructor has an argument, is a callback with two parameters i.e. resolve and reject.
When you perform any async task successfully then call resolve otherwise call reject.

promise.then(function(result) {
console.log(result); // "Stuff worked!"
}, function(err) {
console.log(err); // Error: "It broke"
});

Now promise object has data. It may be resolved data or rejected data.

Check the following demo for a better explanation.

See the Pen An Overview of JavaScript Promises

ScrollReveal Js A javascript library to reveal elements

ScrollReveal Js is a library used to reveal elements when elements enter in the viewport. When you scroll a web page, then you can see the elements appear with some animations. It creates awesome effects. Today we create awesome effects using CSS but Javascript also has been used to create nice animation. There are lots of javascript libraries dedicated to creating animations. ScrollReveal.Js is one of them.

Features of ScrollReveal.Js

  1. It is very small about 3 KB in size.
  2. No dependency. No need to use any dependency js library like jQuery.
  3. Very easy to install
  4. Very simple coding syntax

Install ScrollReveal.Js

Firstly you need this library file. For this, You can download from its GitHub repositories. If you don't want to take it from GitHub you can also use Bower to download.

bower install scrollReveal.js

Now you have a library. You have to add this library in your project before closing tag of the body (</body>).

<script src="path/to/scrollReveal.min.js"></script>

It's time to make a web page animated. Actually, ScrollReveal Js searches elements having attribute "data-src'. So, you just add 'data-src' in all elements in which you want scrollReveal animation working. See the following example of code.

<body>
<div data-sr>first div to animate</div>
<div data-sr>second div to animate</div>
<div data-sr>yet another div to animate</div>
</body>

 

It's time to add a single line of javascript code to make this animation live.

new scrollReveal();

That's it. Run your page and see the magic.

Check out another example on jsfiddle:

Quill WYSIWYG Rich Text Editor

Quill: An API Driven Rich Text Editor

Content creation has been at the core of the web since its beginning. The <textarea> provides a native and essential solution to almost any web application. But at some point, you may need to add formatting to text input. This is where rich text editors come in. There are many solutions to choose from, but QuillJs brings a few modern ideas to consider.

Quill Rich Text Editor DasJs
Quill Rich Text Editor DasJs

The best way to get started is by trying a simple example. It is initialized with a DOM element to contain the editor. The contents of that element will become the initial contents of it.

<!-- Include stylesheet -->
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">

<!-- Create the editor container -->
<div id="editor">
<p>Hello World!</p>
<p>Some initial <strong>bold</strong> text</p>
<p><br></p>
</div>

<!-- Include the  library -->
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>

<!-- Initialize editor -->
<script>
var quill = new Quill('#editor', {
theme: 'snow'
});
</script>

And that's all there is to it!

Next Steps
The real magic of this library comes in its flexibility and extensibility.

SelectizeJs hybrid of text field and select dropdown

SelectizeJs is a combination of Text field and Select dropdown. It depends on Jquery and it has an input field with autocomplete feature. You can use it for tagging dropdown data. It is very small in size about 7KB.

The objective is to offer a stable & usable expertise with a clear and highly effective API.

SelectizeJs hybrid of text field and select dropdown
SelectizeJs hybrid of the text field and select dropdown

In order to use Selectize Js, You need to include jQuery and jQuery UI along with selectize.js in your project.

How to use SelectizeJs in the project:

Add jQuery and selectizejs before closing tag of 'body' (</body>): 

When you adding jquery in your project. Make sure that any version of jquery is not added before in your project. If it exists then don't include jquery library. In this case, only include selectize file.

<script src="/path/to/jquery.min.js"></script>
<script src="/path/to/selectize.js"></script>

Add CSS file before closing tag of 'head' (</head>)

<link rel="stylesheet" href="selectize.css">

Add Input field in HTML

Now add input field inside the body where you want this feature.

<input type="text" id="input-tags" class="demo-default" value="awesome,neat">

 

Enable selectizeJs feature in this input field

Use id ("input-tags")  of the input field as a reference.

$('#input-tags').selectize({

  // An array of the initial options available to select; array of objects. 
  // By default this is populated from the original input element. 
  // If your element is a <select> with <option>s specified this property gets populated automatically. 
  // Setting this property is convenient if you have your data as an array and want to automatically generate the <option>s.
  options: [],

  // Initial selected values.
  items: []

  // Option groups that options will be bucketed into. 
  // If your element is a <select> with <optgroup>s this property gets populated automatically. 
  // Make sure each object in the array has a property named whatever optgroupValueField is set to.
  optgroups: [],

  // Custom delimiter character to separate items
  delimiter: ',',
  splitOn: null, // regexp or string for splitting up values from a paste command

  // If false, items created by the user will not show up as available options once they are unselected.
  persist: true,

  // Enable or disable international character support.
  diacritics: true,

  // Allows the user to create new items that aren't in the initial list of options. 
  // This setting can be any of the following: true, false (disabled), or a function to process input. 
  // The function can take one of two forms: synchronous (with signature function(input){} or asynchronous (with signature function(input, callback). 
  // In the synchronous case, the function should return an object for the options (eg, with defaults: return { 'value': value, 'text': text };). 
  // The asynchronous version should invoke the callback with the result in the same format as the object above (eg, callback( { 'value': value, 'text': text});)
  create: false,

  // If true, when user exits the field (clicks outside of input), a new option is created and selected (if create setting is enabled).
  createOnBlur: false,

  // Specifies a RegExp or a string containing a regular expression that the current search filter must match to be allowed to be created. 
  // May also be a predicate function that takes the filter text and returns whether it is allowed.
  createFilter: null,

  // Toggles match highlighting within the dropdown menu.
  highlight: true,

  // Show the dropdown immediately when the control receives focus.
  openOnFocus: true,

  // The max number of items to render at once in the dropdown list of options.
  maxOptions: 1000,

  // The max number of items the user can select. Null allows an unlimited number of items
  maxItems: 1,

  // If true, the items that are currently selected will not be shown in the dropdown list of available options.
  hideSelected: false,

  // If true, the "Add..." option is the default selection in the dropdown.
  addPrecedence: false,

  // If true, the tab key will choose the currently selected item.
  selectOnTab: false,

  // If true, the load function will be called upon control initialization (with an empty search). Alternatively it can be set to 'focus' to call the load function when control receives focus.
  preload: false,

  // Allows empty options.
  allowEmptyOption: false,

  // If true, the dropdown will be closed after a selection is made.
  closeAfterSelect: false,

  // The animation duration (in milliseconds) of the scroll animation triggered when going [up] and [down] in the options dropdown.
  scrollDuration: 60,

  // The number of milliseconds to wait before requesting options from the server or null. 
  // If null, throttling is disabled. Useful when loading options dynamically while the user types a search / filter expression.
  loadThrottle: 300,

  // The class name added to the wrapper element while awaiting the fulfillment of load requests.
  loadingClass: 'loading',

  // The placeholder of the control (displayed when nothing is selected / typed). 
  // Defaults to input element's placeholder, unless this one is specified.
  placeholder: undefined,

  // The <option> attribute from which to read JSON data about the option.
  dataAttr: 'data-data',

  // The name of the property to group items by.
  optgroupField: 'optgroup',

  // The name of the property to use as the value when an item is selected.
  valueField: 'value',

  // The name of the property to render as an option / item label (not needed when custom rendering functions are defined).
  labelField: 'text',

  // The name of the property to disabled option and optgroup.
  disabledField: 'disabled',

  // The name of the property to render as an option group label (not needed when custom rendering functions are defined).
  optgroupLabelField: 'label',

  // The name of the option group property that serves as its unique identifier.
  optgroupValueField: 'value',

  // If truthy, Selectize will make all optgroups be in the same order as they were added (by the `$order` property). 
  // Otherwise, it will order based on the score of the results in each.
  lockOptgroupOrder: false,

  // A single field or an array of fields to sort by. 
  // Each item in the array should be an object containing at least a field property. 
  // Optionally, direction can be set to 'asc' or 'desc'. 
  // The order of the array defines the sort precedence.
  sortField: '$order',

  // An array of property names to analyze when filtering options.
  searchField: ['text'],

  // When searching for multiple terms (separated by space), this is the operator used. Can be 'and' or 'or' .
  searchConjunction: 'and',

  // multi or single
  mode: null,

  // Default classes
  wrapperClass: 'selectize-control',
  inputClass: 'selectize-input',
  dropdownClass: 'selectize-dropdown',
  dropdownContentClass: 'selectize-dropdown-content',

  // The element the dropdown menu is appended to. This should be 'body' or null. If null, the dropdown will be appended as a child of the Selectize control.
  dropdownParent: null,

  // Copy the original input classes to the dropdown element.
  copyClassesToDropdown: true,

  //  Custom rendering functions. Each function should accept two arguments: data and escape and return HTML (string or DOM element) with a single root element. 
  // The escape argument is a function that takes a string and escapes all special HTML characters. This is very important to use to prevent XSS vulnerabilities.
  render: {
    /*
    item: null,
    optgroup: null,
    optgroup_header: null,
    option: null,
    option_create: null
    */
  }

});



That's it. Now your input field works as autocomplete tag.

See the Pen Selectize JS Library Demo

VelocityJs a Javascript animation engine

VelocityJs is an animation engine with the identical API as jQuery's $.animate(). It really works with and without jQuery. It is extremely quick, and it options shade animation, transforms, loops, easings, SVG help, and scrolling. It's the better of jQuery and CSS transitions mixed.

Download Velocity, include it on your page, and replace all instances of jQuery's $.animate() with $.velocity(). You will immediately see a performance boost across all browsers and devices — especially on mobile.
Compatibility
VelocityJs works everywhere — back to IE8 and Android 2.3. Under the hood, it mimics jQuery's $.queue(), and thus interoperates seamlessly with jQuery's $.animate(), $.fade(), and $.delay(). Since Velocity's syntax is identical to $.animate(), your code doesn't need to change.

Velocity (CDN, choose one of them):

<script src="//cdn.jsdelivr.net/npm/[email protected]/velocity.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/velocity/2.0.3/velocity.min.js"></script>

Velocity UI pack (CDN, choose one of them):

<script src="//cdn.jsdelivr.net/npm/[email protected]/velocity.ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/velocity/2.0.3/velocity.ui.min.js"></script>

Please note that JSDelivr can automatically supply the latest release, while CloudFlare needs to ask for a specific version.

Automagic chaining:
If using the .velocity(...) chained function in libraries such as jQuery or Zepto you need to ensure that Velocity is loaded after them. If you wish to add it to anything loaded afterward then look at the Velocity.patch() method.