Unlimited Wordpress themes, plugins, graphics & courses! Unlimited asset downloads! From $16.50/m
Dismiss
Sign In
  • How-To Tutorials
    • Design & Illustration
    • Code
    • Web Design
    • Photo & Video
    • Business
    • Music & Audio
    • 3D & Motion Graphics
    • Game Development
    • Computer Skills
  • Courses
    Design & Illustration
    Code
    Web Design
    Photo & Video
    Business
    Music & Audio
    3D & Motion Graphics
    Free Courses
  • Guides
    Design & Illustration
    Code
    Web Design
    Photo & Video
    Business
    Music & Audio
    3D & Motion Graphics
    Game Development
    Computer Skills
  • eBooks
    Design & Illustration
    Code
    Web Design
    Photo & Video
    Business
    Music & Audio
    3D & Motion Graphics
  • Student Pricing
  • Envato Elements
  • Envato Studio
  • Community
  • Help
envato-tuts+
  • Envato Elements
  • Envato Studio
  • Community
  • Forum
  • Help
  • Subscribe
  • Sign In
  • How-To Tutorials
    • Design & Illustration
      • Adobe Photoshop
      • Adobe Illustrator
      • Drawing
      • Adobe InDesign
      • Photo Manipulation
      • Graphic Design
      • Text Effects
      • Vector
      • Photoshop Actions
      • Icon Design
      More Categories...Learning Guides
    • Code
      • JavaScript
      • WordPress
      • Mobile Development
      • PHP
      • Laravel
      • CMS
      • Swift
      • Android SDK
      • React
      • Angular 2+
      More Categories...Learning Guides
    • Web Design
      • CSS
      • HTML & CSS
      • Animation
      • UI Design
      • Adobe Photoshop
      • Sketch
      • Workflow
      • Design Theory
      • JavaScript
      • UX
      More Categories...Learning Guides
    • Photo & Video
      • Photography
      • Video
      • Editing
      • How-To
      • Inspiration
      • Lighting
      • Adobe Photoshop
      • Adobe After Effects
      • Adobe Premiere Pro
      • Adobe Lightroom
      More Categories...Learning Guides
    • Business
      • Small Business
      • Entrepreneurship
      • Freelance
      • Careers
      • Marketing
      • Finance
      • Productivity
      • Planning
      • Communication
      • How-To
      More Categories...Learning Guides
    • Music & Audio
      • Audio Production
      • Logic Pro
      • General
      • Mixing & Mastering
      • Sound Design
      • Workshops
      • Reason
      • Recording
      • Ableton Live
      • Cubase
      More Categories...Learning Guides
    • 3D & Motion Graphics
      • Adobe After Effects
      • 3D
      • 3D Studio Max
      • Motion Graphics
      • Maya
      • Cinema 4D
      • Workflow
      • Blender
      • Visual Effects
      • Roundups
      More Categories...Learning Guides
    • Game Development
      • Game Design
      • Platform Agnostic
      • Game Mechanics
      • Business
      • Programming
      • Game Art
      • Level Design
      • From Scratch
      • Unity
      • HTML5
      More Categories...Learning Guides
    • Computer Skills
      • OS X
      • App Training
      • Productivity
      • How-To
      • Tips & Shortcuts
      • Customization
      • Automation
      • Security
      • Hardware
      • Microsoft Powerpoint
      More Categories...Learning Guides
  • Courses
    • Design & Illustration
    • Code
    • Web Design
    • Photo & Video
    • Business
    • Music & Audio
    • 3D & Motion Graphics
    • Free CoursesNEW
  • Guides
    • Design & Illustration
    • Code
    • Web Design
    • Photo & Video
    • Business
    • Music & Audio
    • 3D & Motion Graphics
    • Game Development
    • Computer Skills
  • eBooks
    • Design & Illustration
    • Code
    • Web Design
    • Photo & Video
    • Business
    • Music & Audio
    • 3D & Motion Graphics
  • Student Pricing
Advertisement
  1. Web Design
  2. JavaScript

Completing Our Draggable Off-Canvas Menu with GreenSock

Advertisement
Advertisement
Advertisement
Advertisement
by Dennis Gaebel3 Nov 2015
Difficulty:AdvancedLength:MediumLanguages:
JavaScriptGreenSock Animation Platform
This post is part of a series called The Beginner’s Guide to TimelineMax.
Building a Draggable Off-Canvas Menu with GreenSock
Final product image
What You'll Be Creating

In the first part of this Draggable journey, we discussed how to include scripts, investigated the ThrowPropsPlugin, including the requirements to jump start our project in hopes of taking it to eleven! Now, get ready to make an off-canvas menu system which reacts to keyboard and touch.

The Demo

The full demo that we’ll be building and discussing for the remainder of this tutorial is also available on CodePen.

I encourage you to test this for yourself across as many devices as possible, especially keyboard navigation. Each interaction–whether touch, keyboard or mouse–has been accounted for, but as you’ll find in our current landscape you can’t detect a touchscreen and at times trying to do so even results in false positives.

The Setup

Using the markup from part I we’ll begin by adding a container div for structural purposes along with correlating classes for CSS and JavaScript hooks.

… …
…

Classes that begin with the ”js” prefix signify that these classes only appear in JavaScript; removing them would hinder functionality. They’re never used in CSS, helping to isolate the focus of concerns. The surrounding container will help to control scrolling behavior which is discussed in the upcoming CSS section.

Accessibility

With the the foundation in place it’s time to add a layer of ARIA on top to lend semantic meaning to screen readers and keyboard users.

…

Since the menu will be hidden by default the aria-hidden attribute is labeled true and will be updated accordingly depending on the menu’s state; false for open, true for closed. Here’s an explanation of the attribute aria-hidden per the W3C specification:

> Indicates that the element and all of its descendants are not visible or perceivable to any user as implemented by the author. […] Authors MUST set aria-hidden=”true” on content that is not displayed, regardless of the mechanism used to hide it. This allows assistive technologies or user agents to properly skip hidden elements in the document. ~W3C WAI-ARIA Spec

Authors should be careful what content they hide, making this attribute a separate discussion outside the scope of this article. For those curious, the specification defines the attribute in further length and is somewhat grokkable; something I don’t usually say that often about specification jargon.

The CSS

Our CSS is where the magic really begins. Let’s take the important parts from the demo that bear meaning and break it down.

body {
  // scroll fix
  height: 100%;
  overflow: hidden;
  // end scroll fix
}
.app {
  // scroll fix
  overflow-y: scroll;
  height: 100vh;
  // end scroll fix
}
.dragaebel-nav {
  height: 100vh;
  overflow-y: auto;
  position: fixed;
  top: 0;
  right: 0;
}

Setting the body height to 100% allows the container to stretch the entire viewport, but it’s also playing a more important part; allowing us to hide its overflow.

The overflow scroll fix helps to control how the primary container and navigation behave when either one contains overflowing content. For example, If the container is scrolled—or the menu—the other will not scroll when the user reaches the end of the intially scrolled element. It’s a weird behavior, not typically discussed, but makes for a better user experience.

Viewport Units

Viewport units are really powerful and play a vital role in how the primary container holds overflowing content. Viewport units have wonderful support across browsers these days and I highly suggest you start using them. I’ve used vh units on the nav, but I could have used a percentage instead. During development it was discovered that div.app must use vh units since percentage won’t allow for the overflowing content to maintain typical scrolling behavior; the content results in being clipped. Overflow is set to scroll in preparation in case the menu items exceeed the height of the menu or the height of the viewport becomes narrow.

// Allow nav to open when JS fails
.no-js .dragaebel-nav:target {
  margin-right: 0;
}

.dragaebel-nav {
  margin-right: -180px;
  width: 180px;
}

The .no-js .nav:target provides access to our menu regardless if JavaScript fails or is turned off, hence the reason we added the ID value to the href attribute of the menu trigger.

The primary navigation is moved to the right via a negative margin which is also the same as the nav’s width. For the sake of brevity I’m writing Vanilla CSS, but I’m sure you could write something fancier in a pre-processor of your choice.

The JavaScript

JavaScript is the last stop of this draggable menu journey, but before we write one line of JS we’ll need to write a module pattern setup.

var dragaebelMenu = (function() {
  function doSomething() {…}
  return {
    init: function() {…}
  }
})();

dragaebelMenu.init(); // start it!

Variables

For the configuration setup we’ll define some variables for future reference.

var dragaebelMenu = (function() {

  var container   = document.querySelectorAll('.js-dragsurface')[0],
      nav         = document.querySelectorAll('.js-dragnav')[0],
      nav_trigger = document.querySelectorAll('.js-dragtoggle')[0],
      logo        = document.querySelectorAll('.js-draglogo')[0],
      gs_targets  = [ container, nav, logo, nav_trigger ],
      closed_nav  = nav.offsetWidth + getScrollBarWidth();

})();

Most of these variables are simply grabbing DOM elements, with the exception of the last two that define our GreenSock targets plus the width of the navigation menu. The utility function getScrollBarWidth() (outside our discussion today) retrieves the width of the scroll bar so we can position the nav just beyond the width of the bar itself in order to see it when the menu opens. The targets are what we move when the menu opens in order to allow adjacent content to be pushed.

Methods

To keep things short I’ll only discuss methods that are extremely important to the functionality of the menu behavior. Everything else that you’ll see in the demo not discussed here is the “sugar on top” stuff that makes the menu even more powerful.

function menu(duration) {
  container._gsTransform.x === -closed_nav ? 
    TweenMax.to(gs_targets, duration, { x: 0, ease: Linear.easeIn }) : 
    TweenMax.to(gs_targets, duration, { x: -closed_nav, ease: Linear.easeOut });
}

The menu function detects whether the container’s x coordinate equals the closed nav state. If so it sets the targets back to their starting position, otherwise sets them to their open position.

function isOpen() {
  return container._gsTransform.x < 0;
}

This is a utility function to check the menu’s state. This will return 0 if the menu is closed, or a negative value if it’s open.

function updateNav(event) {
  TweenMax.set([nav, logo, nav_trigger], { x: container._gsTransform.x });
}

This is another utility function which sets the target’s x coordinate inside the array parameter of the .set() method to the container’s x position everytime the onDrag or onThrowUpdate event happens. This is part of the Draggable object instance.

function enableSelect() {
  container.onselectstart = null; // Fires when the object is being selected.
  TweenMax.set(container, { userSelect: 'text' });
}

function disableSelect() {
  TweenMax.set(container, { userSelect: 'none' });
}

function isSelecting() {
  // window.getSelection: Returns a Selection object representing
  // the range of text selected by the user or the current position
  // of the caret.
  return !!window.getSelection().toString().length;
}

These functions help to determine if someone is really selecting text in order to enable / disbale selection capabilities when someone drags across the screen. This is not the most ideal behavior for mouse events, but again, as we already mentioned, you can’t detect a touch screen.

Draggable Instance

Draggable.create([targets], {options})

As we discussed in the previous tutorial about Draggable, this will create the instance of the Draggable object and target the DOM objects of our choice that can be passed as as an array.

Draggable.create([container], {
  type: 'x',
  dragClickables: false,
  throwProps: true,
  dragResistance: 0.025,
  edgeResistance: 0.99999999,
  maxDuration: 0.25,
  throwResistance: 2000,
  cursor: 'resize',
  allowEventDefault: true,
  bounds: {…},
  onDrag: updateNav,
  onDragEnd: function(event) {…},
  liveSnap: function(value) {…},
  onPress: function(event) {…},
  onClick: function(event) {…},
  onThrowUpdate: function() {…}
});

This is our entire Draggable instance and the properties used. The actual demo code contains comments I’ve left in order to understand and gain a better persepective on what each one is responsible for. I encourage you to look into the demo code and even challenge you to deconstruct the why and how.

So Long, But Not Goodbye

This is the end to our GreenSock journey and I hope you learned a ton along the way. A special thanks to Jack and Carl at GreenSock, along with the entire GreenSock community, for their incredible help throughout this series. Last, but not least, a huge thanks to you, the reader for reaching the end of this series; congrats! I hope this series helped gain a better look into the powerful benefits and capabilites of an awesome JavaScript animation library. Build awesome things and stay creative!

Advertisement
Advertisement
Dennis Gaebel
Dennis Gaebel
Developer & Designer - Rochester NY
Design Technologist passionate for Open Source, SVG, Typography, Web Animation, Interaction Development & Pattern Based Design. http://droidpinkman.io.
DroidPinkman
  • Feed
  • Like
  • Follow
Weekly email summary

Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.

Update me weekly
Advertisement
View Online Demo
Translations

Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!

Translate this post
Powered byNative
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.
WordPress Themes
From $13
Magento Themes
From $17
ECommerce Websites
From $16
HTML5 Templates
From $4
×

Envato Tuts+ is now part of Envato Elements

One subscription provides unlimited access to:

1,200+ courses and ebooks
Design, code, video editing, business, and much more.
  • Adobe Photoshop, Illustrator and InDesign
  • Graphic, Logo and Print Design
  • Sketch, Adobe XD & Figma
  • WordPress
  • Javascript, PHP & Python
  • Adobe After Effects & Premiere Pro
  • Much More
Millions of creative assets
Design templates, stock videos, photos & audio, and much more.
  • Graphic Templates
  • Stock Photos
  • Music Tracks
  • Video Templates
  • Web Templates
  • Design Assets
  • Wordpress Themes & Plugins
  • Much More
From
$16.50/m
Subscribe now
Unlimited Downloads
From $16.50/month
Get access to over one million creative assets on Envato Elements.
Over 9 Million Digital Assets
Everything you need for your next creative project.
Create Beautiful Logos, Designs
& Mockups in Seconds
Design like a professional without Photoshop.
Join the Community
Share ideas. Host meetups. Lead discussions. Collaborate.
Quick LinksExplore popular categories
  • Curated Design Assets
  • Best Cool Fonts
  • InDesign Magazine Templates
  • Photoshop Actions
  • InDesign Newsletter Templates
  • InDesign Templates
  • Curated Web Design Assets
  • Responsive WordPress Themes
  • WordPress Themes for Consultants
  • Wireframe Templates
  • Best Shopify Themes
  • Masonry WordPress Themes
  • Web Themes & Templates
  • WP Themes
  • HTML Templates
  • Shopify Themes
  • Bootstrap Themes
  • Free WordPress Themes
  • Video
  • After Effects Templates
  • Apple Motion Templates
  • Video Effects
  • Lower Thirds
  • Stock Footage
  • Placeit
  • Logo Maker
  • Video Maker
  • Design Templates
  • Free Templates
  • Mockups
  • Curated Video Assets
  • After Effects Slideshow Templates
  • Premiere Pro Video Intro Templates
  • Final Cut Pro Templates
  • Final Cut Pro Title Templates
  • Premiere Pro Video Effects
  • Curated Presentation Assets
  • Keynote Pitch Deck Templates
  • Google Slides Business Templates
  • PowerPoint Pitch Deck Templates
  • Best Shopify Mobile Themes
  • Best Presentation Templates
  • Free Tools
  • Image Resizer
  • Video Cropper
  • Video To Gif Converter
  • Elements
  • WordPress Themes
  • Stock Images
  • Website Templates
  • Logos
  • Fonts
  • Tuts+
  • Learn JavaScript
  • Photoshop Tutorials
  • How to Draw
  • How to Use WordPress
  • How to Use PowerPoint
Envato Tuts+
About Envato Tuts+
Terms of Use
Advertise
Join our Community
Teach at Envato Tuts+
Translate for Envato Tuts+
Forums
Help
FAQ
Help Center
envato-tuts+
29,584
Tutorials
1,299
Courses
46,247
Translations
  • Envato.com
  • Our products
  • Careers
  • Sitemap
© 2021 Envato Pty Ltd. Trademarks and brands are the property of their respective owners.
  • Follow Envato Tuts+
  • Facebook
  • Twitter
  • Pinterest