24. April 2015

Sticky Bar With CSS Popup Animation

I was tasked with making a Google Adwords landing page for our company. Our designer Alex Benson decided he wanted a contact form to stick to the bottom of the page and popup when you click it.

 

See the Pen Sticky contact bar with popup animation by Josh Fabean (@fabean) on CodePen.

 

You can poke around the code yourself but I'll break down the main thing I did to accomplish this.

First there is the easy part, I did a couple CSS animations.

.fadeout {
  opacity: 0;
  transition: opacity 1s ease;
}
.fadein {
  opacity: 1;
  transition: opacity 1s ease;
}
.contact {
  position: fixed;
  bottom: 0;
  margin-bottom: 0;
  padding: 10px 0;
  width: 100%;
  height: auto;
  transition: all 400ms cubic-bezier(0, 0, 0.32, 1.50);
}

I was able to do that crazy transition simply by playing with the new Chrome Dev tools easy popup thingy.

alt text

After getting the CSS out of the way all that was left was to adjust the height of that bar based on the content we need to show and the CSS animation should do the rest.

Here's the js, cut up to only show the important part

// get all our elements we're going to be playing with.
var contact = document.getElementById('sticky-contact');
var formEl = document.getElementsByClassName('with-form')[0];
var getStarted = document.getElementById('get-started');

// when you click the first button do this thing!
getStarted.addEventListener('click', function(){
  var initHeight = contact.scrollHeight; // quick grab the current height
  contact.style.height = initHeight + 'px'; // set that height on the element
  formEl.classList.remove('hide'); // show the next step
  var withForm = formEl.scrollHeight; // find what new height would be
  contact.style.height = (withForm + 20) + 'px'; // set that height on the element
  document.getElementsByClassName('initial')[0].classList.add('hide'); // hide the first section of the bar
}, false);

If reading that code isn't enough here is the written out version.

When you click the 'Get Started' button we first grab the current height of the sticky bar. We take that height and set that as the height of the element instead of just height: auto;. Take the part that will show next and remove the class of hide so now it's visible. Grab the height of that element, now reset the height of the sticky bar to the height of the next step. Finally we take the first step that we just clicked and hide that.

Doing that allows for the CSS animation to take over and animate the height giving us the cool effect.

Overall nothing crazy complicated here just a bunch of simple things put together to make a good end result.

06. April 2015

The Selectinator 3000

On Friday Blake and I were asked how to take a list of people and in a fun way choose a random winner.

For fun, here's the finalized pen.

 

See the Pen The Selectinator 3000 by Josh Fabean (@fabean) on CodePen.

 

There you can see all the code but I'll break some of the cooler parts for you. Worth noting I wrote all the code in ES6 and used Traceur on CodePen to compile it to ES5 and work for people.


Below is a nice helper function I created the other day trying to make something useful but under 140bytes of data. It takes an element query array and turns it into an actual usable array. Not sure if you've ran into that issue before but you cannot simply say document.getElementsByClass('my-class') then loop through them, it needs to be made into an actual array for it to be usable.

// helper functions
function makeArray(r){return[].slice.call(r,0)};

To get the lightup effect I probably could have made a sass mixin based on class but doing it with javascript seemed cooler. So I grab everything with a class of light, use math to grab a random one, then each 300 milliseconds run the function lightUp. Then we're simply just toggling a class and the CSS animation is doing the rest.

let lights = makeArray(document.getElementsByClassName('light'));
/* figure out what block we're going to light up next */
(function nextLight() {
  let index = [Math.floor(Math.random() * lights.length)]; // math to grab a random element
  let light = lights[index];
  lightUp(light);
  setTimeout(nextLight,300);
})();

// take the el passed in an toggle a class
function lightUp(light) {
  light.classList.add('on');
  setTimeout(function(){
    light.classList.remove('on');
  },1000);
}

Finally is my favorite, the function where you pass it in a string and it types it out slowly to get the cool typing effect. All I'm doing for that is you pass in the string, and time in milliseconds between each letter and it appends it to the end of the element we're typing in.

// get passed in a string, delay, and current iterator
// based on that output text to the screen
// in future we should pass in element we are rendering to, that would make this more reusable
// also you can remove the first if, that's pretty specific to this situation
function typeText(text, time, i = 0) {
  if (terminal.style.bottom === '') {
    // if bottom isn't defined see if we need to start the scrolling effect
    screenScroll();
  }
  setTimeout(function(){
    // on first iteration of the string I'm making a new line
    // else we add to the line
    if (i === 0 && terminal.innerHTML != '' && text != ' you lose') {
      terminal.innerHTML += `<br /> ${text.charAt(i)}`;
    } else {
      terminal.innerHTML += text.charAt(i);
    }
    i++;
    if (text.length >= i) {
      typeText(text, time, i);
    }
  }, time);
}

 


This was my favorite pen I've made so far I really hope you enjoyed it.