Animating with Velocity.js - Web Animation using JavaScript: Develop and Design (2015)

Web Animation using JavaScript: Develop and Design (2015)

Chapter 2. Animating with Velocity.js

In this chapter, you’ll learn the features, commands, and options provided by Velocity.js. If you’re familiar with jQuery-based animation, you already know how to use Velocity; it functions nearly identically to jQuery’s $.animate() function.

But regardless of your existing knowledge, the methodical feature breakdowns in this chapter will introduce you to the nuances of animation engine behavior. Mastering these nuances will help take you from novice to professional. Even if you’re already intimately familiar with JavaScript animation and Velocity.js, do yourself a favor and skim this chapter. You’re bound to discover something you didn’t realize you could do.

Types of JavaScript animation libraries

There are many types of JavaScript animation libraries. Some replicate physics interactions in the browser. Some make WebGL and Canvas animations easier to maintain. Some focus on SVG animation. Some improve UI animation—this last type is the focus of this book.

The two popular UI animation libraries are GSAP (download it at GreenSock.com) and Velocity (download it at VelocityJS.org). You’ll work with Velocity throughout this book since it’s free under the MIT license (GSAP requires licensing fees depending on a site’s business model), plus it boasts incredibly powerful features for writing clean and expressive animation code. It’s in use on many popular sites, including Tumblr, Gap, and Scribd.

Oh, and it was created by the author of this book!

Installing jQuery and Velocity

You can download jQuery from jQuery.com, and Velocity from VelocityJS.org. To use them on your page—as with any JavaScript library—simply include <script></script> tags pointing toward the respective libraries before your page’s </body> tag. If you’re linking to pre-hosted versions of the libraries (as opposed to local copies on your computer), your code might look like this:

<html>
<head>My Page</head>
<body>
My content.
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="//cdn.jsdelivr.net/velocity/1.1.0/velocity.min.js"> </script>
</body>
</html>

When using jQuery and Velocity together, include jQuery before Velocity.

That’s it! Now you’re ready to roll.

Using Velocity: Basics

To get oriented to Velocity, we’ll start with the basic components: arguments, properties, values, and chaining. Since jQuery is so ubiquitous, it is also important to look at the relationship between Velocity and jQuery.

Velocity and jQuery

Velocity functions independently of jQuery, but the two can be used in combination. It’s often preferable to do so to benefit from jQuery’s chaining capabilities: When you’ve preselected an element using jQuery, you can extend it with a call to .velocity() to animate it:

// Assign a variable to a jQuery element object
var $div = $("div");
// Animate the element using Velocity
$div.velocity({ opacity: 0 });
This syntax is identical to jQuery's own animate function:
$div.animate({ opacity: 0 });

All the examples in this book use Velocity in combination with jQuery, and therefore follow this syntax.

Arguments

Velocity accepts multiple arguments. Its first argument is an object that maps CSS properties to their desired final values. The properties and their accepted value types correspond directly to those used in CSS (if you’re unfamiliar with basic CSS properties, pick up an introductory HTML and CSS book before reading this one):

// Animate an element to a width of "500px" and to an opacity of 1.
$element.velocity({ width: "500px", opacity: 1 });


Image Tip

In JavaScript, if you’re providing a property value that contains letters (instead of only integers), put the value in quotes.


You can pass in an object specifying animation options as a second argument:

$element.velocity({ width: "500px", opacity: 1 }, { duration: 400, easing: "swing" });

There’s also a shorthand argument syntax: Instead of passing in an options object as a second argument, you can use comma-separated argument syntax. This entails listing values for duration (which accepts an integer value), easing (a string value), and complete (a function value) in any comma-separated order. (You’ll learn what all of these options do momentarily.)

// Animate with a duration of 1000ms (and implicitly use the default easing value of "swing")
$element.velocity({ top: 50 }, 1000);
// Animate with a duration of 1000ms and an easing of "ease-in-out"
$element.velocity({ top: 50 }, 1000, "ease-in-out");
// Animate with an easing of "ease-out" (and implicitly use the default duration value of 400ms)
$element.velocity({ top: 50 }, "ease-out");
// Animate with a duration of 1000ms and a callback function to be triggered upon animation completion
$element.velocity({ top: 50 }, 1000, function() { alert("Complete.") });

This shorthand syntax is a quick way of passing in animation options when you only need to specify the basic options (duration, easing, and complete). If you pass in an animation option other than these three, you must switch all options to the object syntax. Hence, if you want to specify a delay option, change the following syntax:

$element.velocity({ top: 50 }, 1000, "ease-in-out");

to this syntax:

// Re-specify the animation options used above, but include a delay value of 500ms
$element.velocity({ top: 50 }, { duration: 1000, easing: "ease-in-out", delay: 500 });

You can’t do this:

// Incorrect: Divides animation options between the comma-separated syntax and the object syntax
$element.velocity({ top: 50 }, 1000, { easing: "ease-in-out", delay: 500 });

Properties

There are two differences between CSS-based and JavaScript-based property animation.

First, unlike in CSS, Velocity accepts only a single numeric value per CSS property. So, you can pass in:

$element.velocity({ padding: 10 });

or

$element.velocity({ paddingLeft: 10, paddingRight: 10 });

But you can’t pass in:

// Incorrect: The CSS property is being passed more than one numeric value.
$element.velocity({ padding: "10 10 10 10" });

If you do want to animate all four padding values (top, right, bottom, and left), list them out as separate properties:

// Correct
$element.velocity({
paddingTop: 10,
paddingRight: 10,
paddingBottom: 10,
paddingLeft: 10
});

Other common CSS properties that can take multiple numeric values include margin, transform, text-shadow, and box-shadow.

Breaking up compound properties into their sub-properties for the purposes of animation gives you increased control over easing values. In CSS, you can specify only one property-wide easing type when animating multiple sub-properties within the parent padding property, for example. In JavaScript, you can specify independent easing values for each sub-property—the advantages of this will become apparent during the discussion of CSS transform property animation later in this chapter.

Listing out independent sub-properties can also make your animation code easier to read and easier to maintain.

The second difference between CSS-based and JavaScript-based property animation is that JavaScript properties drop the dashes between words and all words past the first must be capitalized. For example, padding-left becomes paddingLeft, and background-colorbecomes backgroundColor. Further note that JavaScript property names should not be in quotes:

// Correct
$element.velocity({ paddingLeft: 10 });
// Incorrect: Uses a dash and doesn't capitalize
$element.velocity({ padding-left: 10 });
// Incorrect: Uses quotes around the JavaScript-formatted property name
$element.velocity({ "paddingLeft": 10 });

Values

Velocity supports the px, em, rem, %, deg, vw, and vh units. If you don’t provide a unit type with a numeric value, an appropriate one is automatically assigned based on the CSS property type. For most properties, px is the default unit, but a property that expects a rotation angle, such asrotateZ for example, would be automatically assigned the deg (degree) unit:

$element.velocity({
top: 50, // Defaults to the px unit type
left: "50%", // We manually specify the % unit type
rotateZ: 25 // Defaults to the deg unit type
});

Explicitly declaring unit types for all property values increases your code’s legibility by making the contrast between the px unit and its alternatives more obvious when quickly eyeballing your code.

Another advantage of Velocity over CSS is that it supports four value operators that can be optionally prefixed to a property value: +, -, *, and /. These directly correspond to their math operators in JavaScript. You can combine these value operators with an equals sign (=) to perform relative math operations. Refer to the inline code comments for examples:

$element.velocity({
top: "50px", // No operator. Animate toward 50 as expected.
left: "-50", // Negative operator. Animate toward -50 as expected.
width: "+=5rem", // Convert the current width value into its rem equivalent and add 5 more units.
height: "-10rem", // Convert the current height value into its rem equivalent and subtract 10 units.
paddingLeft: "*=2" // Double the current paddingLeft value.
paddingRight: "/=2" // Divide the current paddingLeft value into two.
});

Velocity’s shorthand features, such as value operators, retain animation logic entirely within the animation engine. This not only keeps the code more concise by eliminating manual value calculation, but also improves performance by telling Velocity more about how you plan to animate your elements. The more logic that is performed within Velocity, the better Velocity can optimize your code for higher frame rates.

Chaining

When multiple Velocity calls are chained back-to-back on an element (or a series of elements), they automatically queue onto one another. This means that each animation begins once the preceding animation has completed:

$element
// Animate the width and height properties
.velocity({ width: "100px", height: "100px" })
// When width and height are done animating, animate the top property
.velocity({ top: "50px" });

Using Velocity: Options

To round out this introduction to Velocity, let’s run through the most commonly used options: duration, easing, begin and complete, loop, delay, and display.

Duration

You can specify the duration option, which dictates how long an animation call takes to complete, in milliseconds (1/1000th of a second) or as one of three shorthand durations: "slow" (equivalent to 600ms), "normal" (400ms), or "fast" (200ms). When specifying a duration value in milliseconds, provide an integer value without any unit type:

// Animate with a duration of 1000ms (1 second)
$element.velocity({ opacity: 1 }, { duration: 1000 });

or

$element.velocity({ opacity: 1}, { duration: "slow" });

The advantage to using the named shorthand durations is that they express the tempo of an animation (is it slow or is it fast?) when you’re reviewing your code. If you use these shorthands exclusively, they’ll also naturally lead to more uniform motion design across your site, since all of your animations will fall into one of three speed categories instead of each being passed an arbitrary value.

Easing

Easings are the mathematical functions that define how fast or slow animations occur in different parts of an animation’s total duration. For example, an easing type of "ease-in-out" indicates that the animation should gradually accelerate (ease in) during the first part then gradually decelerate (ease out) during the final part. In contrast, an easing type of "ease-in" produces an animation that accelerates up to a target speed during the first part of an animation but thereafter remains at a constant speed until the animation completes. An easing type of "ease-out" is the converse of this: the animation starts and continues at a constant speed before it gradually decelerates during the final part of the animation.

Much like the physics-based motion discussed in Chapter 1, “Advantages of JavaScript Animation,” easings give you the power to inject personality into your animations. Take, for example, how robotic an animation that uses the linear easing feels. (A linear easing produces an animation that starts, runs, and ends at the same velocity.) The robotic feel is the result of an association with linear robotic motion in the real world: Self-guided mechanical objects typically move in straight lines and operate at constant speeds because there’s neither an aesthetic nor an organic reason for them to do otherwise.

In contrast, living things—whether it’s the human body or trees blowing in the wind—never move at constant speed in the real world. Friction and other external forces cause them to move at varying speeds.

Great motion designers pay homage to organic motion because it gives the impression that the interface is responding fluidly to the user’s interaction. In mobile apps, for example, you expect a menu to quickly accelerate away from your fingers when you swipe it off-screen. If the menu were to instead move away from your fingers at a constant speed—like a robotic arm—you’d feel as if the swipe merely set off a chain of motion events that were outside your control.

You’ll learn more about the power of easing types in Chapter 3, “Motion Design Theory.” For now, let’s run through all of Velocity’s available easing values:

Image jQuery UI’s trigonometric easings. For a complete listing of these easing equations, as well as interactive demonstrations of their acceleration profiles, refer to the demos on easings.net.

$element.velocity({ width: "100px" }, "easeInOutSine");

Image CSS’s easings: "ease-in", "ease-out", "ease-in-out", and "ease" (a subtler version of "ease-in-out").

$element.velocity({ width: "100px" }, "ease-in-out");

Image CSS’s Bézier curves: The Bézier curve easing allows complete control over the structure of an easing’s acceleration curve. A Bézier curve is defined by specifying the height of four equidistant points on a chart, which Velocity accepts in the format of a four-item array of decimal values. Visit cubic-bezier.com for an interactive guide to creating Bézier curves.

$element.velocity({ width: "100px" }, [ 0.17, 0.67, 0.83, 0.67 ]);

Image Spring physics: This easing type mimics the bouncy behavior of a spring that’s been stretched then suddenly released. As with the classical physics equation that defines the motion of a spring, this easing type lets you pass in a two-item array in the form of [ tension, friction ]. A higher tension (default: 500) increases total speed and bounciness. A lower friction (default: 20) increases ending vibration speed.

$element.velocity({ width: "100px" }, [ 250, 15 ]);

Image "spring" easing is a predefined implementation of the spring physics easing that’s handy to use when you don’t want to experiment with tension and friction values.

$element.velocity({ width: "100px" }, "spring");

Remember that you can also pass in the easing option as an explicitly defined property in an options object argument:

$element.velocity({ width: 50 }, { easing: "spring" });

Do not be overwhelmed by the number of easing options available to you. You’ll most often rely on the CSS easing types and the “spring” easing, which suit the vast majority of animation use cases. The most complex easing type, the Bézier curve, is most often employed by developers who have a highly specific easing style in mind and aren’t afraid to get their hands dirty.


Image Note

The rest of the Velocity options in this section must be explicitly passed into an options object. Unlike those already described, these additional options cannot be supplied to Velocity in the shorthand comma-separated syntax.


Begin and Complete

The begin and complete options allow you to specify functions to be triggered at certain points in an animation: Pass the begin option a function to be called prior to the start of an animation. Conversely, pass the complete option a function to be called at the completion of an animation.

With both options, the function is called once per animation call, even if multiple elements are being animated at once:

var $divs = $("div");
$divs.velocity(
{ opacity: 0 },
// Open an alert box right before the animation begins
{
begin: function () { console.log("Begin!"); },
// Open an alert box once the animation completes
complete: function () { console.log("Complete!"); }
}
);


Callback Functions

These options are commonly referred to as “callback functions” (or “callbacks”) since they are “called” when certain events occur in the future. Callbacks are useful for firing events that are dependent on the visibility of elements. For example, if an element starts at invisible then animates toward an opacity of 1, it may be appropriate to subsequently trigger a UI event that modifies the new content once users are able to see it.

Remember that you don’t need to use callbacks to queue animations onto one another; animations automatically fire sequentially when more than one is assigned to a single element or set of elements. Callbacks are for the queuing of non-animation logic.


Loop

Set the loop option to an integer to specify the number of times an animation should alternate between the values in the call’s property map and the element’s values prior to the call:

$element.velocity({ height: "10em" }, { loop: 2 });

If the element’s original height was 5em, its height would alternate between 5em and 10em twice.

If the begin or complete options are used with a looped call, they are triggered once each—at the very beginning and end of the total loop sequence, respectively; they are not retriggered for each loop alternation.

Instead of passing in an integer, you can also pass in true to trigger infinite looping:

$element.velocity({ height: "10em" }, { loop: true });

Infinite loops ignore the complete callback since they don’t naturally end. They can, however, be manually stopped via Velocity’s stop command:

$element.velocity("stop");

Non-infinite loops are useful for animation sequences that would otherwise require the repetition of chained animation code. For example, if you were to bounce an element up and down twice (perhaps to alert the user of a new message awaiting them), the non-optimized code would look like this:

$element
// Assume translateY starts at "0px"
.velocity({ translateY: "100px" })
.velocity({ translateY: "0px" })
.velocity({ translateY: "100px" })
.velocity({ translateY: "0px" });

The more compact and easier to maintain version of this code would look like this:

// Repeat (loop) this animation twice
$element.velocity({ translateY: "100px" }, { loop: 2 });

With this optimized version, if you have a change of heart about how much the top value should be changed by (currently "100px"), you need only change the top value in one part of the code. If there are many such instances of repetition in your code, it quickly becomes obvious how much looping benefits your workflow.

Infinite looping is tremendously helpful for loading indicators, which typically animate indefinitely until data has finished loading.

First, make the loading element appear to pulsate by infinitely looping its opacity from visible to invisible:

// Assume opacity starts at 1 (fully visible)
$element.velocity({ opacity: 0 }, { loop: true });

Later, once the data has finished loading, you can stop the animation, then hide the element:

$element
// First stop the infinite loop...
.velocity("stop")
// ... so you can give the element a new animation,
// in which you can animate it back to invisibility
.velocity({ opacity: 0 });

Delay

Specify the delay option in milliseconds to insert a pause before an animation begins. The delay option’s purpose is to retain an animation’s timing logic entirely within Velocity—as opposed to relying on jQuery’s $.delay() function to change when a Velocity animation starts:

// Wait 100ms before animating opacity toward 0
$element.velocity({ opacity: 0 }, { delay: 100 });

You can set the delay option with the loop option to create a pause between loop alternations:

// Loop four times, waiting 100ms between each loop
$element.velocity({ height: "+=50px" }, { loop: 4, delay: 100 });

Display and Visibility

Velocity’s display and visibility options correspond directly to their CSS counterparts, and accept the same values, including: "none", "inline", "inline-block", "block", "flex", and so on. In addition, Velocity allows for a value of "auto", which instructs Velocity to set the display property to the element’s default value. (For reference, anchors and spans default to "inline", whereas divs and most other elements default to "block".) Velocity’s visibility option, like its CSS counterpart, accepts the "hidden", "visible", and"collapse" values.

Within Velocity, when the display option is set to "none" (or when visibility is set to "hidden"), the element’s CSS property is set accordingly once the animation has completed. This effectively works to hide an element upon completion of an animation, and is useful in conjunction with animating an element’s opacity down to 0 (where the intention is to fade an element off the page):

// Fade an element to opacity:0 then remove it from the page's flow
$element.velocity({ opacity: 0 }, { display: "none" });


Image Note

The code above effectively replaces the jQuery equivalent:

$element
.animate({ opacity:0 })
.hide();



Quick Review of Visibility and Display

For reference, the CSS display property dictates how an element affects the positioning of the elements surrounding it and contained within it. In contrast, the CSS visibility property exclusively affects whether an element can be seen. If an element is set to "visibility: hidden", it will continue to take up space on the page, but its space will simply be represented by an empty gap—no part of the element will be seen. If an element is instead set to "display: none", the element will be fully removed from the page’s flow, and all elements within and around it will fill into the removed element’s space as if the element never existed.


Note that, instead of removing an element from the page’s flow, you can simply mark the element as both invisible and non-interactive by setting its visibility to "hidden". This is useful for when you want a hidden element to continue taking up space on the page:

// Fade an element to opacity:0 then make it non-interactive
$element.velocity({ opacity: 0 }, { visibility: "hidden" });

Now, let’s consider animations in the opposite direction (showing elements instead of hiding elements): When display or visibility is set to a value other than "none" or "hidden", the value is set before the animation begins so the element is visible throughout the duration of the ensuing animation. In other words, you’re undoing the hiding that occurred when the element was previously removed from view.

Below, display is set to "block" before the element begins fading in:

$element.velocity({ opacity: 1 }, { display: "block" });

This effectively replaces the jQuery equivalent:

$element
.show()
.animate({ opacity: 0 });


Image Tip

For a complete overview of Velocity’s animation options, consult the documentation at VelocityJS.org.



Containing Animation Logic

As with Velocity’s delay option, Velocity’s incorporation of CSS display and visibility setting allows for animation logic to be fully contained within Velocity. In production code, whenever an element is faded into or out of view, it’s almost always accompanied by a change in display or visibility. Leveraging Velocity shorthands like these helps you keep your code clean and maintainable, since it’s less dependent on external jQuery functions and free of repetitive helper functions that commonly bloat animation logic.

Note that Velocity includes shorthands for the opacity toggling animations demonstrated above. They function identically to jQuery’s fadeIn and fadeOut functions. You simply pass the corresponding command into Velocity as the first argument, and you pass in an options object, if desired, as normal:

$element.velocity(“fadeIn”, { duration: 1000 });
$element.velocity(“fadeOut”, { duration: 1000 });


Using Velocity: Additional features

Additional Velocity.js features that are worthy of note include: the reverse command, scrolling, colors, and transforms (translation, rotate, and scale).

Reverse Command

To animate an element back to the values prior to its last Velocity call, pass in "reverse" as Velocity’s first argument. The reverse command behaves identically to a standard Velocity call; it can take options and is queued up with other chained Velocity calls.

Reverse defaults to the options (duration, easing, etc.) used in the element’s prior Velocity call. However, you can override these options by passing in a new options object:

// Animate back to the original values using the prior Velocity call's options
$element.velocity("reverse");

or

// Do the same as above, but replace the prior call's duration with a value of 2000ms
$element.velocity("reverse", { duration: 2000 });


Image Note

The previous call’s begin and complete options are ignored by the reverse command; reverse never re-calls callback functions.


Scrolling

To scroll the browser to the top edge of an element, pass in "scroll" as Velocity’s first argument. The scroll command behaves identically to a standard Velocity call; it can take options and is queued up with other chained Velocity calls:

$element
.velocity("scroll", { duration: 1000, easing: "spring" })
.velocity({ opacity: 1 });

This scrolls the browser to the top edge of the element using a 1000ms duration and a "spring" easing. Then, once the element has scrolled into view, it fades in fully.

To scroll toward an element inside a parent element with scrollbars, you can use the container option, which accepts either a jQuery object or a raw element. Note that the container element of the CSS position property must be set to either relative, absolute, or fixed—static won’t do the trick:

// Scroll $element into view of $("#container")
$element.velocity("scroll", { container: $("#container") });

In both cases—whether scrolling is relative to the browser window or to a parent element—the scroll command is always called on the element that’s being scrolled into view.

By default, scrolling occurs on the y-axis. Pass in the axis: "x" option to scroll horizontally instead of vertically:

// Scroll the browser to the *left* edge of the targeted div.
$element.velocity("scroll", { axis: "x" });

Finally, the scroll command also uniquely takes an offset option, specified in pixels, which offsets the target scroll position:

// Scroll to a position 50px *above* the element's top edge.
$element.velocity("scroll", { duration: 1000, offset: "-50px" });
// Scroll to a position 250px *beyond* the element's top edge.
$element.velocity("scroll", { duration: 1000, offset: "250px" });

Colors

Velocity supports color animation for these CSS properties: color, backgroundColor, borderColor, and outlineColor. In Velocity, color properties accept only hex strings as inputs, for example, #000000 (black) or #e2e2e2 (light gray). For more granular color control, you can animate the individual red, green, and blue components of a color property, as well as the alpha component. Red, green, and blue range in value from 0 to 255, and alpha (which is equivalent to opacity) ranges from 0 to 1.

Refer to the inline comments below for examples:

$element.velocity({
// Animate backgroundColor to the hex value for black
backgroundColor: "#000000",
// Simultaneously animate the alpha (opacity) of the background to 50%
backgroundColorAlpha: 0.5,
// Also animate the red component of the element's text color to half its total value
colorRed: 125
});

Transforms

The CSS transform property performs translation, scale, and rotation manipulations to elements in both 2D and 3D space. It consists of several subcomponents, of which Velocity supports the following:

Image translateX: Move an element along the x-axis.

Image translateY: Move an element along the y-axis.

Image rotateZ: Rotate an element along the z-axis (effectively clockwise or counter-clockwise on a 2D surface).

Image rotateX: Rotate an element along the x-axis (effectively toward or away from the user in 3D space).

Image rotateY: Rotate an element along the y-axis (effectively leftward or rightward in 3D space).

Image scaleX: Multiply the width dimension of an element.

Image scaleY: Multiply the height dimension of an element.

In Velocity, you animate these components as individual properties within a property object:

$element.velocity({
translateZ: "200px",
rotateZ: "45deg"
});

Using Velocity: Without jQuery (intermediate)

If you’re an intermediate developer who prefers to work in JavaScript without the aid of jQuery, you’ll be happy to know that Velocity also works when jQuery is not present on the page. Accordingly, instead of chaining an animation call onto a jQuery element object—as shown in the previous examples in this chapter—the targeted element(s) are passed directly into the animation call as the first argument:

Velocity(element, { opacity: 0.5 }, 1000); // Velocity

Velocity retains the same syntax as jQuery’s $.animate() even when it’s used without jQuery; the difference is that all arguments are shifted one position to the right to make room for passing in the targeted elements in the first position. Further, the global Velocity object is used to invoke animations instead of specific jQuery element objects.

When you’re using Velocity without jQuery, you’re no longer animating jQuery element objects, but rather raw Document Object Model (DOM) elements. Raw DOM elements can be retrieved using the following functions:

Image document.getElementByID(): Retrieve an element by its ID attribute.

Image document.getElementsByTagName(): Retrieve all elements with a particular tag name (e.g. a, div, p).

Image document.getElementsByClassName(): Retrieve all elements with a particular CSS class.

Image document.querySelectorAll(): This function works nearly identically to jQuery’s selector engine.

Let’s further explore document.querySelectorAll() since it will probably be your weapon of choice when selecting elements without the aid of jQuery. (It’s a performant function that’s widely supported across browsers.) As with jQuery’s element selector syntax, you simply pass querySelectorAll a CSS selector (the same selectors you use in your stylesheets for targeting elements), and it will return all matched elements in the form of an array:

document.querySelectorAll("body"); // Get the body element
document.querySelectorAll(".squares"); // Get all elements with the "square" class
document.querySelectorAll("div"); // Get all divs
document.querySelectorAll("#main"); // Get the element with an id of "main"
document.querySelectorAll("#main div"); // Get all divs within "main"

If you assign the result of one of these lookups to a variable, you can then reuse that variable to animate the targeted element(s):

// Get all div elements
var divs = document.querySelectorAll("div");
// Animate all the divs
Velocity(divs, { opacity: 0 }, 1000);

Since you’re no longer extending jQuery element objects, you may be wondering how to chain animations back-to-back, like this:

// These chain onto one another
$element
.velocity({ opacity: 0.5 }, 1000)
.velocity({ opacity: 1 }, 1000);

To reenact this pattern without the aid of jQuery, simply call animations one after another:

// Animations on the same element automatically chain onto one another.
Velocity(element, { opacity: 0 }, 1000);
Velocity(element, { opacity: 1 }, 1000);

Wrapping up

Now that you’re armed with an understanding of the benefits of using JavaScript for web animation, plus a grasp of the basics of Velocity, you’re ready to explore the fascinating theoretical foundation that underlies professional motion design.