Grolsch 400

At Nation we were asked to display the artworks of 400 artists to celebrate 400 years of Grolsch. You can see the mini site over here - Grolsch 400.

During this build, a few things stood out as ‘niceties’ to me which I will go through in a bit of detail; one of them being the "Explore the art gallery" button.

It looks like an obvious choice to go through exactly how the artwork grid works, but half way through building that grid, there were some unexpected bumps in the road and some of those bumps I didn’t have time to fully get my head around. Something something transform scale / transform translate something something. That part of the site ended up needing some extra attention to meet the 400 year deadline.


The "Explore the art gallery" button.

This had to work back to IE9 so it was important to find a solution that would work cross-browser. Above is the SVG solution I went with, and here is the code for that:

<div class="explore">
  <a href="#">
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" class="button">
      <defs>
        <pattern id="background" patternUnits="userSpaceOnUse" width="469" height="1991" >
          <image xlink:href="explore-cta.jpg" class="image" width="469" height="1991"></image>
        </pattern>
      </defs>
      <text fill="#6ec049" x="35" y="50">Explore the art gallery</text>
    </svg>
    <svg class="border border-top">
      <rect fill="#6ec049" width="100%" height="100%"></rect>
    </svg>
    <svg class="border border-right">
      <rect fill="#6ec049" width="100%" height="100%"></rect>
    </svg>
    <svg class="border border-bottom">
      <rect fill="#6ec049" width="100%" height="100%"></rect>
    </svg>
    <svg class="border border-left">
      <rect fill="#6ec049" width="100%" height="100%"></rect>
    </svg>
  </a>
</div>

Each element inside our button (borders and text) has a starting fill of #6ec049, then on 'mouseover', this fill is set to use our <pattern> we have defined inside the <defs> tag.

The pattern we defined contains the image that we will be flicking through on hover. This is essentially a sprite sheet. Here is it slowed down and animated so we can see what is actually happening (ironically this little demo does not work in IE9, despite me bangin' on about it)

At the same time the new fill is set on 'mouseover', we start an interval to display each frame. I think what you can also see in the animation is a miscalculation of frame heights on the jpg, you didn't see that

Here is the interval code:

__LINK.addEventListener('mouseover', function(e) { startCtaEffect(e); });

function startCtaEffect() {
  setCtaFill();
  ctaFrameInterval = setInterval(function() {
    // Increment ctaCurrentFrame
    ctaCurrentFrame++;
    // Move to the next frame based on
    // the ctaCurrentFrame index
    ctaMoveFrame();
  }, ctaFrameRate);
}

function setCtaFill() {
  // Only store one of the elements' fill, these colours 
  // should always stay the same
  originalFill = __LINK.querySelector('text').getAttribute('fill');
  // Set new fill, which is the svg pattern #background id
  var i = 0, borders = __LINK.querySelectorAll('svg rect');
  for (; i < borders.length; i++) {
    borders[i].setAttribute('fill', 'url(#background)');
  }
  __LINK.querySelector('svg text').setAttribute('fill', 'url(#background)');
}

...then finally we move the image:

function ctaMoveFrame() {
  // Set top to 0
  var newTop = 0;
  // If we are at the end of the frames
  // set the current frame back to the beginning
  if (ctaCurrentFrame === ctaTotalFrames) {
    ctaCurrentFrame = 0;
    // ...otherwise, continue by multiplying the
    // ctaCurrentFrame index with the frameHeight
  } else {
    newTop = ctaCurrentFrame * ctaFrameHeight;
  }
  // Set newTop at each interval
  var value = ' translate(0, -' +newTop+ ')';
  __LINK.querySelector('.image').setAttribute('transform', value);
}

The 'transform' attribute is being set on the svg image tag, not a CSS transform. Just something to note, super nice article about SVG transforms over here.


Want to tell me how much you hate my solution and that you want me to stop doing front-end as a full-time job - @tomsansome