Implement touch device friendly background videos with canvid.js

By subtly adjusting the position of the focal point of a still image, and repeating this cycle, an optical illusion known as "apparent movement", creates the sense that the image is moving.

Normally, an image that displays more than 10 frames per second is recognized a video. Video is played at 24 frames per second. Increasing the frames also increases the required about of data, but this allows for a more natural video experience.

The same principle applies to HTML 5 videos and GIF animation used in web applications, repeatedly displaying still images will result contents that have movement.

Auto play for videos on touch devices

Nonetheless, it is not possible to have the same experience on all devices. In order to prevent the transmission of data that has not been requested by users, beginning with smart phones, touch devices disable automatic play of videos. In the interface, a disabled state is displayed for videos. Usually, the video is presented as a reference image, with a play button overlaid on top.

The video will play by clicking on the play button, but depending on the iOS or Android device in use, it may cause a screen transition. Therefore, it may not be possible to adhere to the vision of the designer. For example, on a web site that uses a video as the background of the screen, developers often choose to substitute images, or make use GIF animation as an alternative on touch devices. This is in order to avoid the play button overlapping with other content or elements, or behavior where the video will open in a new screen.

Drawbacks of GIF animation

Here we try thinking of a helpful idea for using full screen background video in web site designs on both PC and touch devices. Reflecting on the apparent movement that we introduced earlier, it was a concept of displaying videos with static images in sequence. By using Photoshop, multiple still images can be created as GIF animations.

GIF animation appears to be an effective medium at first glance, but there is a limitation on the number of colors and a noticeable deterioration of quality once the video has been converted. The difficult issue of restricting the file size while maintaining a balance between picture quality and number of frames left me feeling that display of a video in full-screen is unachievable. Moreover, GIF animation frame rate limits differ depending on the browser, and there are restrictions preventing playback controls such as cueing and pausing. This further limits the mediums usage scenarios.

canvid.js and sprite images to play video

After spending some time for reserch, we came up with the method of using canvid.js and sprite images. canvid.js is a lightweight open source Javascript library that plays short videos via canvas. It provides playback, pause, rewind functionality, as well as frame rate, looping and more. canvid is designed to work with sprite image. JPG is better working to create compactly-sized videos. It uses FFmpeg, an audio/video encoder, and ImageMagick, a set of image processing libraries, to enable converting a video into a single sprite with the use of just two commands. A detailed explanation can be found on the official web site. Below is a sample created with the tool to explain the process.

The div below is marked up in order to act as a container for storing the canvas to be created.

<div class="canvid-wrapper"></div>

canvid.js is imported, and the following descriptor can be utilized.

var canvidControl = canvid({
    videos: {
        clip1: {
            src: 'video.jpg',
            frames: 150,
            cols: 6,
            fps: 10,
            loops: 1,
        }
    },
    loaded: function() {
        canvidControl.play('clip1');
    }
});

The frames, which are a required option, place the multiple images that have been converted into ffmpeg format into columns with the ffmpeg command.

You can also set frame rate or playback loop counts as the example below. This time, the page background has a full screen video set, therefore we built out the code as follows:

function calcRatio() {
    var w = $(window).width(),
        h = $(window).height();
    if (h >= w * 9 / 16) {
        $('.canvid-wrapper').addClass('nallow');
    } else {
        $('.canvid-wrapper').removeClass('nallow');
    }
}
function resizeFunc() {
    var timer = false;
    $(window).resize(function() {
        if (timer !== false) {
            clearTimeout(timer);
        }
        timer = setTimeout(function() {
            calcRatio();
        }, 200);
    });
}
var canvidControl = canvid({
    videos: {
        clip1: {
            src: 'video.jpg',
            frames: 150,
            cols: 6,
            fps: 10,
            loops: 0,
        }
    },
    loaded: function() {
        canvidControl.play('clip1');
        calcRatio();
        resizeFunc();
    }
});

The calcRatio function is used to branch the aspect ratio of the image against the original video aspect ratio in two patterns and switch between the style class used. The original image had an aspect ratio of 16:9, so this is multiplied against the width of the screen and compared against the screen height. The resizeFunc function is used to recalculate the image when resizing. Both functions are executed after the video has been processed.

The CSS is as follows.

.canvid-wrapper,
.canvid-wrapper::after {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
}
.canvid-wrapper::after {
    display: block;
    content: '';
    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFUlEQVQIW2NkYGCoZ2BgaGRkgIB6AAyoAYKa0AhQAAAAAElFTkSuQmCC) repeat;
}
.canvid {
    position: relative;
    top: 50%;
    left: 50%;
    width: 100%;
    height: auto;
    transform: translateY(-50%) translateX(-50%);
}

First, the .canvid-wrapper is set to be fixed its position and to fill 100% of a browser’s width and height. The transform property is used to give the .canvid an absolute center-aligned position. By default, the width is set at 100%, but where the nallow class is applied to the calcRatio function, it will adjust to the height and cover the same area of the screen even as the screen is resized. In order to keep the image from artifacting and looking crisp even on large displays, pseudo after elements are used to overlay semi-transparent pixels over the video.

You can see the finished sample here.