Fullstack Digital Website Development

Fullstackdigital.com is one of my favorite projects to date. In collaboration with Allen Djal (branding director at Fullstack Digital), I implemented the design from scratch on a static site generator I had never used before.

I built the website using the Jekyll static site generator with Forestry.io as the CMS for simple content changes.

This website was particularly challenging due to the number of interactive elements, the page structure, and the animations between pages.

Home Page

The home page features a logo load-in animation and animations on scroll.

Logo load-in animation and tilt effect

On page load, the logo animates in using CSS animations and minor JS.

The logo is an SVG, allowing animation of the path to create the initial load-in animation.

On the home page, the logo tilts on hover:

I used GSAP to transform the SVG based on the mouse position over the wrapping div:

setTimeout(function() {
// Tilt the hero container
TweenLite.to('#poster', 0.2, {
  rotationY:10xPos, 
  rotationX:10yPos, 
  ease:Power0.easeInOut, 
  transformPerspective:900, 
  transformOrigin:"center"
  });
}, 0);

Animating on scroll

As the user scrolls down the page, the background image changes to the image that corresponds to the section in the viewport.

I created an image masking effect using CSS clipPaths to achieve the logo-overlay effect. Although it was more complicated, I opted to use an SVG and clipPath with a background-image for each section on the page. Then, I used GSAP and Scroll Magic to trigger the background image and contact color change based on the scroll position.

...
var fadeSImage = new TimelineMax();
  fadeSImage
  .to($slash1, 0.5, {
    fill:"{{ page.hero.slash.c_1 }}",
    opacity: 1, 
    ease: Power4.easeInOut
    }, 0)
  .to($slash2, 0.5, {
    fill:"{{ page.hero.slash.c_2 }}",
    opacity: 1, 
    ease: Power4.easeInOut
    }, 0)
  .to($slash3, 0.5, {
    fill:"{{ page.hero.slash.c_3 }}",
    opacity: 1, 
    ease: Power4.easeInOut
    }, 0)
  .setTween(fadeSImage)
  .addTo(controller);
...

Ajax-powered animations between pages

One of the most complicated aspects of the website is the use of Ajax to enable seamless page transitions. Page content is loaded via Ajax in the <main> div, meaning the user never sees a page refresh when navigating around the site:

Clicking a link in the footer fades in the next page and relocates the scroll position to the top of the next page during the transition:

For example, when a grid item on the work page is clicked, the grid thumbnail expands to the full size of the container and then the work page content is loaded:

The tricky part of this animation is matching the width, height, and offset.Top positions of the grid image (at the start of the animation) and the corresponding work page featured image. These values must mach exactly to achieve a seamless transition with the main image.

I originally used jQuery animate to handle the grow effect for the image, but realized that the animation was too choppy due to the low frame rate support. I switched to Velocity JS, which utilizes a much higher frame rate (60FPS).

Sorting and filtering

Filtering and sorting are used in various areas across the site. The work page, for example, uses JS to sort the masonary grid:

Each work grid item contains data-attributes based on the tags in use. Tags are specified in the front matter of the page:

tags:
- Web Design
- Web Development
- Web Experience

Client logos are animated in from various directions based on the scroll position of the user:

PDF-style page designs

The design of the normal pages required meticulous spacing, alignment, and perspective asjustments (for 3D style elements):

Developing a framework for easy page updates

Development of the Fullstack website led me to create a builder framework that allows users to build pages with front-matter. This means that a non-technical user can quickly update and build content using a content management system like Forestry.io.

Instead of creating a unique page layout for every unique page, a user can simply add pre-built sections using a content management system:

Front matter is then generated with values like the template name, padding, break points, and text color:

sections:
- template: section-column-background-image
  type: section-row-blocks
  background-color: "#ffffff"
  background_position: right
  background_repeat: no-repeat
  size: container
  background_image: "/uploads/2018/05/01/q-mark.png"
  rows:
  - template: row
    stack-columns: tablet-s
    cols:
    - template: column
      padding-top: xl
      padding-bottom: xl
      align-self-vertical: center
      text-align-class: left
      color-class: oil
      column-size: '6'
      subtitle: Discovery
      title: 'The goal: positioning & awareness.'
      html: |-
        <p>The purpose of the campaign was clear: to not only educate existing
        customers and strengthen the perception of DDN as the leader in HPC Storage,
        but also help inform and create further market awareness among prospects and
        those new to DDN. <br><br>
        We used this premise to inspire the name of the campaign:
        “Did You Know?” With a simple question, we would arouse curiosity and draw
        attention to the company. Behind it would be a list of carefully organized
        facts about DDN. Since DDN is in a highly specialized and technical market
        niche, we needed to ensure these facts were both engaging and compelling.</p>
      maxwidth: s
      animate: fade-left
    - template: column
      image: "/uploads/2018/05/01/q-mark.png"
      column-size: '6'
      align-self-vertical: center

I use nested partial files to create one flexible section:

    ├── section
    │   ├── row
    │   ├── ├---column
    │   └── ├---├------element
Since static websites are typically maintained and updated by developers, the content update and creation process is usually inefficient.

Implementing a builder framework allowed multiple non-technical employees to assist with content updates while reducing the complexity of future page updates.