As a creative developer at Adobe, I am charged with showcasing the creative potential of the web and inspiring designers and developers through innovative applications and experiences.
A few months ago, my colleagues and I designed an experimental presentation called The Quest for the Graphical Web that tells the story of how the web is evolving from a graphical perspective. Vincent Hardy, director of engineering for the Web Platform group at Adobe, delivered the presentation to a live audience in San Francisco, California, during the Create the Web event. The open-source version of the presentation is also available on github.
For the presentation, we wanted to show some key graphical features of the web along with newer features being implemented by the Adobe Web Platform team. Some of these features are still in the specification process, so implementations can currently only be found in experimental or preview browser builds, such as Chrome Canary.
In this article, I explain how we approached the project and put together a cast of unique characters to represent each of the technologies used.
Div, the protagonist in our story, travels through an evolving landscape where he meets CSS, who makes things colorful, and SVG, who makes things more shapely. His journey then continues into outer space where he encounters 3D Transforms, who brings a new perspective to things; 2D Canvas, who shows some particle tricks; and an enigmatic WebGL. He then returns home to explore several upcoming characters like Blend Modes, who offers some ghostly overlay effects, and Shader Princess, who shows off the power of CSS custom filters. Each character explains how it makes the web a more graphical place.
It turns out that getting manually drawn shapes to interpolate smoothly can be quite tricky. There are methods you can use to make this more reliable, but ultimately the more complex the shapes, the more difficult this process will be. We generated the start and end shapes dynamically to have full control and ensure a smooth transition between the two shapes.
Most of our characters are SVG elements that blink and move using CSS animations and transformations. These properties are applied to paths and elements inside the inline SVG (currently supported only by certain browsers). This allowed us to trigger animations and transition attributes of a character simply by appending or removing a class to the root element.
We used SASS, a meta-language on top of CSS that compiles into CSS, which allowed us to use variables and mixins, and to break our CSS out into different files.
We used this in conjunction with Compass, which provides a useful set of built-in mixins and variables that are specifically helpful for CSS3 prefixed features. This enabled us to write one line and have all the prefix variants taken care of. So instead of writing this:
-webkit-transition: transform .2s ease-in; -moz-transition: transform .2s ease-in; -o-transition: transform .2s ease-in; -ms-transition: transform .2s ease-in; transition: transform .2s ease-in;
we just wrote this:
@include transition(transform .2s ease-in);
For 2D Canvas, we used Processing.js to render a particle system, which switches between arrays of points to create animated transitions between shapes. We created a crude tool to draw target shapes, which enabled us to easily manipulate them for smooth transitions. Processing.js then exported these points in a format we could use. That is how we created a talking face animation made up of star particles.
We created several custom GLSL shaders for this project. For example, we wrote a custom fragment shader to create the ambient glowing background of our WebGL scene. This fragment shader, along with the geometry in the scene, was easily implemented with the Three.js library.
We also wrote a custom vertex shader for the Custom Filters character to create wave-like oscillations similar to a stingray.
The CSS for this element is as follows:
-webkit-filter: custom(url(../assets/shaders/jelly.vs) mix(url(../assets/shaders/jelly.fs) multiply source-atop), 50 50 filter-box, transform translateY(-10px) rotateY(0deg) rotateX(60deg) rotateZ(170deg) scale(0.55), delta 1.0, backface 0.0);
It references the individual vertex and fragment shaders as well as sets the attributes within them. We used CSS animations to interpolate the states back and forth with easing for smooth motion. These shaders can be difficult to write, so having a tool like CSS Filter Lab is really helpful in creating custom shaders.
We built a camera to manage the viewable HTML area by translating our scene element relative to the camera position with 3D transforms. This allowed us to slide, rotate, and zoom the camera on all three axes. We managed the position and rotation of Div within the scene with this same approach.
Not all browsers completely support 3D. For example, we found some implementation issues with Safari where rendered nested content in some scenarios didn't respect its transformation. In addition, Internet Explorer 10 does not currently support
transform-style: preserve-3d, meaning content within a container always layers based on the z-index of the attribute. So proper depth sorting with translate3d is out of the question.
We tried to pack a lot of different features into a colorful, creative demo to show some fun uses of the technology. Feel free to check out the source on github to see how we put it together. Given the nature of the content, it obviously doesn't work well in every browser, but we thought it was a good test case to see how far the open web has come as a design medium.
We believe there are still many cool things on the way. We're excited to see how the web community will continue to innovate with these graphical features as the web platform continues to grow.
CJ Gammon is a creative developer at Adobe working with the Web Platform team to help push the creative possibilities of the web.