Recently I have been working on a small web application which uses Javascript to animate and interact with a SVG. I wanted to fullscreen the SVG with the animation running. To do this, I used the fullscreen API, but quickly discovered differences between browsers. In particular, while Firefox would provide a true full screen for a given element - that is, scale the element to the fullscreen - Chrome would turn off all other elements, but leave the element being fullscreened the same size, as pictured.

Chrome version of fullscreen

Since that wasn’t acceptable, the next thing I did was write CSS to make fullscreen actually be fullscreen. Unfortunately, changing the positioning type broke the Javascript variables, forcing me to reload all pointers to elements in the SVG whenever coming into or out of fullscreen.

I spent quite a bit of time figuring this out, and couldn’t find much online about it, so I’ve created a simple example of an animated SVG with full screen capability to demonstrate the solution.

Try it out in Chrome and Firefox (No Internet Explorer support yet), then I’ll break down the various aspects to making it work.

HTML

The only HTML you’ll require is for the fullscreen button and the SVG object.

<script>
    /* Add script here */
</script>

<style>
    /* Add CSS here */
</style>

<button id="full-scrn-btn" type="button">Fullscreen</button>
<object id="example-svg" type="image/svg+xml" data="example.svg"></object>

SVG

The next thing to create is the SVG. It’s very simple in this case - just a black rectangle for the background, and a white circle.

<svg viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <rect id="background" x="0" y="0" width="100" height="100" fill="black" />
    <circle id="circle" cx="0" cy="0" r="15" fill="white" />
</svg>

This needs to be saved into a file, example.svg.

Animating It

Next we need to animate the circle so it moves across the screen. We’ll grab the various elements (SVG, SVG document and circle), and set a timer to animate the circle. Either add this as a script element or as a separate file.

addEventListener("load", function()
{
    // Get elements
    var scene = document.getElementById("example-svg");
    var sceneDoc = scene.contentDocument;
    var circle = sceneDoc.getElementById("circle");

    // Setup coordinate variables
    var x = 0;
    var y = 0;
    
    // Timer for moving circle
    moveTimer = setInterval(function()
    {
        circle.setAttribute("transform", "translate(" + x + ", " + y + ")");
        
        // Update circle location
        x++;
        y++;
        
        // If we've gone past the end of the SVG, restart
        if (x === 100)
        {
            x = 0;
            y = 0;
        }
    }, 50);
}

Fullscreen

Now that we’ve got our SVG and animation, we need to make it fullscreen. Add the following code into the addEventListener function

 // Register user clicking on fullscreen button - include Firefox for comparisons
document.getElementById("full-scrn-btn").addEventListener("click", function()
{   	
	if (scene.requestFullscreen) 
	{
	    scene.requestFullscreen();
	}
	else if (scene.mozRequestFullScreen) 
	{
	    scene.mozRequestFullScreen();
	}
	else if (scene.webkitRequestFullScreen) 
	{
	    scene.webkitRequestFullScreen();
	}
});

I’ve added various vender-prefix versions to improve support, but if the browser isn’t new enough, we’ll ignore it. For a production application, you’d need a fallback or an alert for the user.

If we open this in Firefox, it should now work. However, in Chrome you’ll get the issue I discussed above, where the element doesn’t grow to fill the screen.

Chrome Fullscreen

Now we’ll make the element fill the screen in Chrome by using CSS. We set the position to fixed and top to 0 - which will put it at the top of the browser. Set the height and width to 100% so it’ll fill the screen, and make background none to make everything uniformly black.

/* Adding this breaks the animation on Chrome, so we have to reset */
#example-svg:-webkit-full-screen {
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    background: none;

Now you’ll find that if you fullscreen it, it’ll fill the screen, but it will no longer animate. This will hold true even after you exit fullscreen - resetting the position breaks the element variables.

Fixing Chrome’s Animations

To fix the Javascript animation, you’ll have to reinitialize all the impacted element variables (elements that are outside of the fullscreened element are still fine). Add the following code into the addEventListener function.

// Register screen change operation in webkit
addEventListener("webkitfullscreenchange", function()
{  
    // After 200 ms, reset all the elements to make Chrome happy
    setTimeout(function() 
    {	
        scene = document.getElementById("example-svg");
        sceneDoc = scene.contentDocument;
        circle = sceneDoc.getElementById("circle");			
    }, 200);
});

We register to the webkit version of the fullscreenchange event, so that every time we enter or leave fullscreen our code enters. Updating the variables immediately doesn’t work however, as this function will trigger before fullscreen renders. Instead we have to add a timeout, and update the variables there. I found that the amount of time required to wait for the screen to update was variable. 50 ms probably would have been sufficient, but for potentially slower devices I bumped it up to 200. This will result in a glitch as the SVG goes from its initial positions to where everything has been animated to, so there may be a better way to handle it.

Putting It All Together

Assuming you have SVG saved in the same directory as example.svg, the resulting HTML (with embedded CSS and JS) should work in Chrome and Firefox.

<script>
addEventListener("load", function()
{
    // Get elements
    var scene = document.getElementById("example-svg");
    var sceneDoc = scene.contentDocument;
    var circle = sceneDoc.getElementById("circle");

    // Setup coordinate variables
    var x = 0;
    var y = 0;
    
    // Timer for moving circle
    moveTimer = setInterval(function()
    {
        circle.setAttribute("transform", "translate(" + x + ", " + y + ")");
        
        // Update circle location
        x++;
        y++;
        
        // If we've gone past the end of the SVG, restart
        if (x === 100)
        {
            x = 0;
            y = 0;
        }
    }, 50);
    
     // Register user clicking on fullscreen button - include Firefox for comparisons
    document.getElementById("full-scrn-btn").addEventListener("click", function()
    {   	
        if (scene.requestFullscreen) 
        {
            scene.requestFullscreen();
        }
        else if (scene.mozRequestFullScreen) 
        {
            scene.mozRequestFullScreen();
        }
        else if (scene.webkitRequestFullScreen) 
        {
            scene.webkitRequestFullScreen();
        }
    });

    // Register screen change operation in webkit
    addEventListener("webkitfullscreenchange", function()
    {  
        // After 200 ms, reset all the elements to make Chrome happy
        setTimeout(function() 
        {	
            scene = document.getElementById("example-svg");
            sceneDoc = scene.contentDocument;
            circle = sceneDoc.getElementById("circle");			
        }, 200);
    });
});
</script>

<style>
    #example-svg {
        width: 50%;
        height: 50%;
    }
    
  /* Adding this breaks the animation on Chrome, so we have to reset */
  #example-svg:-webkit-full-screen {
      position: fixed;
      width: 100%;
      height: 100%;
      top: 0;
      background: none;
    }
</style>

<button id="full-scrn-btn" type="button">Fullscreen</button>
<object id="example-svg" type="image/svg+xml" data="example.svg"></object>