Archive for May, 2013

studio_title

We recently updated ShowCaster Studio to give users the ability to customise how they embed the ShowCaster player. This has become a common feature amongst some online services, however everyone seems to have their own interpretation of how to present this information to the user.

We approached this task as we do all of our user interface designs: the goal is to only present critical information to users and minimise their cognitive load. This combined with traditional UI design principles forced us to consider presenting the embed code alongside a responsive preview of the embed itself. The idea was to add a few options that would tweak the look and feel of the player and have the preview automatically update to reflect those settings. We also added tabs to differentiate between the major layouts, giving the user quick access to a variety of common embed types. The result of this design looks like this:

embedBuidler

A crucial part of the work was to make our embed player flexible in terms of its layout and presentation, however in this post I only focus on the builder and not the embed. A follow up post will touch on how we implemented a flexible embed player.

The main technical challenge of this implementation came from the interactive preview that we chose to implement as an iframe pointing to our embed player. In order to keep a consistent feel and not throw off the page layout, the iframe width should remain the same at all times but we also wanted the preview to be interactive in terms of size. This can be easily be achieved through dynamic scaling of the iframe to always fit the allocated space using CSS3.

.embedPreview iframe {
  transform-origin: top left;
  -moz-transform-origin: top left;
  -webkit-transform-origin: top left;
  -o-transform-origin: top left;
  -ms-transform-origin: top left;
}
var scale = (iframeContainer.width()) / iframe.width();
iframe.css("transform", "scale(" + scale + ")");
iframe.css("-webkit-transform", "scale(" + scale + ")");
...
iframe.css("-o-transform", data);
// Resize height of the container to fit the transform
iframeContainer.css("height", height * scale);

The main problem now came from detecting the new width and height of the iframe once its contents had been reloaded. This was slightly more complex since we cannot query the contents of an iframe on a different domain to adjust the scaling and height of the preview.

We used HTML5 messages to pass the size parameters of the iframe contents once it had finished loading.

// Code on the embed client page (embed player)
// Fire load event to parent once the document is loaded
$(window).load(function() {
  var data = new Object();
  data.type = "embedLoaded";
  data.eventId = ;
  data.contentWidth = $(document).width();
  data.contentHeight = $(document).height();
  data.layout = "";

  window.parent.postMessage(JSON.stringify(data), "*");
});

We can then listen for those messages on our Studio page and adjust the scaling and height accordingly.

// Code on the Studio page (embed buidler)
$(document).ready(function() {
 // IE8 handle
 if (typeof window.addEventListener != 'undefined') {
   // Add event listener for onLoad event of the embedded iframe
   window.addEventListener("message", onIframeLoad, false);
 } else if (typeof window.attachEvent != 'undefined') {
   window.attachEvent("onmessage", onIframeLoad);
 }
});

function onIframeLoad (pEvent) {
  var data = JSON.parse(pEvent.data);
  var width = data.contentWidth;
  var height = data.contentHeight;
  ...
}

It is important to note here that we are passing the object as a string and not simply as an extended JSON object. The reason for that being due to IE not having access to any other attributes than the event data, i.e. the string.

Hope you guys found this post useful and you now have a better idea of how to improve your embedding experience. Happy coding! :)

ShowCaster