After our thorough study of different web animation techniques for thehalvening.com, we finally opted for displaying a video.
The H264 encoding squeezes our 10s loop animation in 1MB with an HD resolution.
The web integration is direct thanks to the video
HTML5 tag:
<video preload='auto' autoplay='true' loop poster='img/phase1-large.png'>
<source src='anim/phase1_1080.mp4' type='video/mp4' /></video>
The video is displayed over a uniform background to give a fullscreen-like rendering.
At the first test though, we noticed a slight but annoying color difference between the background and the video:
Damned!
Looking at the RGB values, we understood that H264 compression has modified the colors. The beginning of a long walk in the valley of the shadow of death…
1st attempt: Laziness. We replaced the background color by the one of the compressed video. Worked well on a PC but not on a Mac.
2nd attempt: We tried a little javascript trick to set a specific background color for Mac users:
var isMacLike = navigator.platform.match(/Mac/i)?true:false;
if (isMacLike){
$('.main section.page1').css('background','#6C9EEB');
}
else{
$('.main section.page1').css('background','rgba(90, 144, 236,1.0)');
}
It worked…until the bug appeared again on another PC. No escape, this time we’re gonna have to use our neurons..!
3rd attempt: After a little bit of googling, we understood that the H264 implementation varies between browsers, and that there are as many renderings as there are web browsers. Worst, we noticed that video rendering varies between different versions of the same browser, between OS (win8 v.s. win8.1), and evan between two seemingly identical configurations..!
We implemented a universal solution: draw the video on a canvas, read RGB value of a single pixel and update the background color:
var vid = document.getElementsByTagName("video")[0];
vid.onplay = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(vid,0,0);
var imgData=ctx.getImageData(0,0,1,1);
r = imgData.data[0];
g = imgData.data[1];
b = imgData.data[2];
$('.main section.page1').css('background','rgba('+r+', '+g+', '+b+',1.0)');
};
That worked…on almost all configurations. There were still some cases where the RGB values returned by getImageData
didn’t match the actual video color. (I now think it might come from a misuse of drawImage
).
4th attempt: Copy and paste. This time we tried the most direct technique by drawing a portion of the video over a canvas that is then spread over the entire page to fill all the background. The following code reads a 1×1 pixel portion in the upper left corner of the video and draws it with drawImage
over an HTML canvas
. The background filling is done in CSS.
css:
canvas {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
}
js:
var vid = document.getElementsByTagName("video")[0];
vid.onplay = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(vid,0,0,1,1,0,0,canvas.width, canvas.height);
};
Did it work? Not quite. We still had a color mismatch on some Chrome configurations. We could solve it by disabling hardware acceleration, but that’s not something we could impose on our kind visitors…
5th attempt: A little help from above. We tried again the previous technique, but with a bigger portion of the video of 300×300 pixels (of uniform color).
var vid = document.getElementsByTagName("video")[0];
vid.onplay = function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(vid,0,0,300,300,0,0,canvas.width, canvas.height);
};
Success, this was it! It seems that working on a single pixel that is spread to cover the entire background causes a color distortion. However the color is stable with a 300×300 portion. To do: check if this works with a smaller portion (10×10 for instance).
The final result: thehalvening.com
As a final word: a really pain-in-the-ass bug to solve, notably because all worked well on my PC. I couldn’t see the bug with my own eyes, which slows down debugging a lot.
A few ressources that saved me:
–html5doctor.com/video-canvas-magic/ for the « copy & paste video on a canvas » trick
–browserstack for testing a website across a wide range of configurations. The trial version include a 30-min remote acces to a real session with the selected config, which is quite a thing..!