Mozilla

Articles by Paul Rouget

Sort by:

View:

  1. Firefox 4 Demos: 3 new demos!

    Firefox 4 RC is here!

    And as promised last week, more demos are coming on our Web O’ Wonder website! Here is another round with 3 new demos. Take a look!

    360° Video

    Navigate into a panoramic video.

    Try it yourself

    Source code

    Motivational Poster Editor

    Create your own motivationnal poster.

    Try it yourself

    Source code

    Letter Heads

    By @simurai

    Human silhouette built with CSS3 shadows.

    Try it yourself

    Source code

  2. Firefox 4 Web Demos: announcing Web O' Wonder

    Firefox 4 is almost here. Check out some awesome Web demos on our brand new demo web site: Web’O Wonder. Screencast here.

    Update: 3 more demos: https://hacks.mozilla.org/2011/03/webowonder-round/

    Web ‘O Wonder

    Firefox 4 is almost here, and comes with a huge list of awesome features for web developers.

    In order to illustrate all these new technical features, we put together several Web demos. You’ll see a couple of demos released every week until the final version of Firefox 4. You can see the first 3 demos online now on our brand new demo web site: Web’O Wonder:

    Web O Wonder

    Note: Some of these demos use WebGL, and will work only on compatible hardware. Make sure you are using the latest drivers for your graphics card.

    Open Demos

    These demos haven’t been designed exclusively for Firefox 4. We believe that the Web is not the property of any single browser, which is why we made sure that these demos work on other modern browsers, like Chrome, when possible.

    The other big step forward for HTML5 demos is that these are Open Source. Help us improve them! The source code of every single demo is available on Github and we encourage you to fork them and play.

    New technologies and new horizons for 400 million users

    In these demos, we are experimenting with new technologies, trying to imagine what could be the future of the Web. HTML5, CSS3, WebGL, SVG, blazing fast JavaScript and new APIs. Sounds exciting, but what does it really mean for the user?

    It means new possibilities, new ways to interact with web applications. It means richer and more beautiful applications. It means a smoother and faster experience and this is what we want to demonstrate with these demos.

    We hope to inspire web developers to use these new technologies. This is just the beginning of a new generation of websites. Web developers now have the tools to change the face of the internet and here you have a few blueprints to start from.

    Thank you!

    A lot of people were involved in the development of these demos. The Mozilla community is full of talented people that did a lot of incredible work to make these demos happen. I just want to say a big thank you to all these talented people (and make sure to check out the credits on the demos!).

    Oh, look! A screencast:

  3. HTML5 Guitar Tab Player with the Firefox 4 Audio Data API

    Greg Jopa, an Illinois State University grad student studying web development, built a web-based guitar tab player using Firefox’s Audio Data API and Vexflow (HTML5 music notation rendering API). Here is some details from Greg. You can also read more about this experiment on his blog.

    I created a mashup using the Firefox 4 Audio Data API, MusicXML, and Vexflow to create a HTML 5 Guitar Tab Player.

    This is a Youtube video. It uses the HTML5 <video> tag if you activate it here.

    Using JavaScript, this guitar tab player converts the music note data from a MusicXML file to frequencies playable by the Audio Data API. This note data is also converted to a format that can be read by Vexflow to display the guitar tab.

    I have broken down this functionality into 4 steps. Here’s how the HTML5 Guitar Tab Player works:

    MusicXML

    When a tab (a tablature) is selected, the jQuery ajax() function loads the MusicXML file, parses through the contents, and appends all the formatted note data to a <script> tag. The format for each note is: playNote(note, octave, duration).

    playNote(notes.C, 4, 1);

    The tablature notation information in the MusicXML file is also processed and appended to a <div> tag for Vexflow.

    Here is the structure of the nodes I am using from the MusicXML file:

    <measure number="1">
        <attributes>
            <divisions>1024</divisions>
        </attributes>
        <note>
            <pitch>
                <step>C</step>
                <octave>4</octave>
            </pitch>
            <duration>1024</duration>
            <notations>
                <technical>
                    <fret>1</fret>
                    <string>2</string>
                </technical>
            </notations>
        </note>
        the note node repeats for the rest of the notes in the measure…
    </measure>

    And here is the generated source that is produced by the ajax() function.

    For the audio:

    <script id="audio" type="text/javascript">
    	function loadAudio(){
    	  playNote(notes.C, 4, 1);
    	  playNote(notes.C, 4, 1);
    	  playNote(notes.G, 4, 1);
    	  playNote(notes.G, 4, 1);
    	  …
    	}
    </script>

    For the tab:

    <div id="tab" class="vex-tabdiv" width=780 scale=1.0 editor="false">
    tabstave notation=true
    	notes :q 1/2 :q 1/2 :q 3/1 :q 3/1 | :q 5/1
       …
    </div>

    Frequency Calculation

    When the Play button is clicked the music data <script id=”audio”> tag is evaluated and the note information is converted to frequencies using the following formula (assumes equal temperament):

    frequency = 440 * 2^(n/12)

    440 is the frequency for the note A at the 4th octave.

    n = distance away from A4 (440)

    I am using an array to store the distance between a certain note and the base note “A”

    notes = {C:-9, Cs:-8, D:-7, Ds:-6, E:-5, F:-4, Fs:-3, G:-2, Gs:-1, A:0, As:1, B:2};

    And to incorporate that a note can be played at different octaves I have adapted the above formula to the following:

    frequency = 440 * 2^((octave-4) * 12 + distance)/12);

    Audiodata.js

    I am using the Audiodata.js library in the guitar tab player which makes it easy to play continuous audio using a single array. This library encapsulates the Audio Data API methods. Audiodata.js is available on GitHub here: https://github.com/notmasteryet/audiodata. The Audiodata.js project contains a score example with “Twinkle, Twinkle, Little Star” which inspired me to build this guitar tab player.

    Vexflow and the Animated Cursor

    Vexflow is an open-source web-based music notation rendering API based on the HTML5 canvas element (http://www.vexflow.com/). I am using Vexflow to display the tab for each MusicXML file. I have added an additional canvas element on top of the Vexflow canvas to control the red cursor that links the audio to the tablature. The speed of the audio is controlled by the tempo which is measured in beats per minute. By converting this tempo to milliseconds I am able to use it for the redraw speed of the second canvas. Every time this canvas is redrawn the red cursor is moved 5 pixels to the right to highlight which note is currently being played.
    Keep in mind that this HTML5 Guitar Tab Player is just a proof of concept and can only play single notes.

    If you have recommendations on how to make this tab player better or would like to contribute to this project check out the following post: http://www.gregjopa.com/2010/12/html5-guitar-tab-player-with-firefox-audio-data-api/

  4. How to develop a HTML5 Image Uploader

    HTML5 comes with a set of really awesome APIs. If you combine these APIs with the <canvas> element, you could create a super/modern/awesome Image Uploader. This article shows you how.

    All these tips work well in Firefox 4. I also describe some alternative ways to make sure it works on Webkit-based browsers. Most of these APIs don’t work in IE, but it’s quite easy to use a normal form as a fallback.

    Please let us know if you use one of these technologies in your project!

    Retrieve the images

    Drag and drop

    To upload files, you’ll need an <input type=”file”> element. But you should also allow the user to drag and drop images from the desktop directly to your web page.

    I’ve written a detailed article about implementing drag-and-drop support for your web pages.

    Also, take a look at the Mozilla tutorial on drag-and-drop.

    Multiple input

    Allow the user the select several files to upload at the same time from the File Picker:

    <input type="file" multiple>

    Again, here is an article I’ve written about multiple file selection.

    Pre-process the files

    Use the File API

    (See the File API documentation for details.)

    From drag-and-drop or from the <input> element, you have a list a files ready to be used:

    // from an input element
    var filesToUpload = input.files;
    // from drag-and-drop
    function onDrop(e) {
      filesToUpload = e.dataTransfer.files;
    }

    Make sure these files are actually images:

    if (!file.type.match(/image.*/)) {
      // this file is not an image.
    };

    Show a thumbnail/preview

    There are two options here. You can either use a FileReader (from the File API) or use the new createObjectURL() method.

    createObjectURL()

    var img = document.createElement("img");
    img.src = window.URL.createObjectURL(file);

    FileReader

    var img = document.createElement("img");
    var reader = new FileReader();
    reader.onload = function(e) {img.src = e.target.result}
    reader.readAsDataURL(file);

    Use a canvas

    Once you have the image preview in an <img> element, you can draw this image in a <canvas> element to pre-process the file.

    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);

    Resize the image

    People are used to uploading images straight from their camera. This gives high resolution and extremely heavy (several megabyte) files. Depending on the usage, you may want to resize such images. A super easy trick is to simply have a small canvas (800×600 for example) and to draw the image tag into this canvas. Of course, you’ll have to update the canvas dimensions to keep the ratio of the image.

    var MAX_WIDTH = 800;
    var MAX_HEIGHT = 600;
    var width = img.width;
    var height = img.height;
     
    if (width > height) {
      if (width > MAX_WIDTH) {
        height *= MAX_WIDTH / width;
        width = MAX_WIDTH;
      }
    } else {
      if (height > MAX_HEIGHT) {
        width *= MAX_HEIGHT / height;
        height = MAX_HEIGHT;
      }
    }
    canvas.width = width;
    canvas.height = height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, width, height);

    Edit the image

    Now, you have your image in a canvas. Basically, the possibilities are infinite. Let’s say you want to apply a sepia filter:

    var imgData = ctx.createImageData(width, height);
    var data = imgData.data;
    var pixels = ctx.getImageData(0, 0, width, height);
    for (var i = 0, ii = pixels.data.length; i < ii; i += 4) {
        var r = pixels.data[i + 0];
        var g =pixels.data[i + 1];
        var b = this.pixels.data[i + 2];
        data[i + 0] = (r * .393) + (g *.769) + (b * .189);
        data[i + 1] = (r * .349) + (g *.686) + (b * .168)
        data[i + 2] = (r * .272) + (g *.534) + (b * .131)
        data[i + 3] = 255;
    }
    ctx.putImageData(imgData, 0, 0);

    Upload with XMLHttpRequest

    Now that you have loaded the images on the client, eventually you want to send them to the server.

    How to send a canvas

    Again, you have two options. You can convert the canvas to a data URL or (in Firefox) create a file from the canvas.

    canvas.toDataURL()

    var dataurl = canvas.toDataURL("image/png");

    Create a file from the canvas

    var file = canvas.mozGetAsFile("foo.png");

    Atomic upload

    Allow the user to upload just one file or all the files at the same time.

    Show progress of the upload

    Use the upload events to create a progress bar:

    xhr.upload.addEventListener("progress", function(e) {
      if (e.lengthComputable) {
        var percentage = Math.round((e.loaded * 100) / e.total);
        // do something
    }, false);

    Use FormData

    You probably don’t want to just upload the file (which could be easily done via: xhr.send(file)) but add side information (like a key and a name).

    In that case, you’ll need to create a multipart/form-data request via a FormData object. (See Firefox 4: easier JS form handling with FormData.)

    var fd = new FormData();
    fd.append("name", "paul");
    fd.append("image", canvas.mozGetAsFile("foo.png"));
    fd.append("key", "××××××××××××");
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "http://your.api.com/upload.json");
    xhr.send(fd);

    Open your API

    Maybe you want to allow other websites to use your service.

    Allow cross-domain requests

    By default, your API is only reachable from a request created from your own domain. If you want to allow people use your API, allow Cross-XHR in your HTTP header:

    Access-Control-Allow-Origin: *
    

    You can also allow just a pre-defined list of domains.

    Read about Cross-Origin Resource Sharing.

    postMessage

    (Thanks to Daniel Goodwin for this tip.)

    Also, listen to messages sent from postMessage. You could allow people to use your API through postMessage:

    document.addEventListener("message", function(e){
        // retrieve parameters from e.data
        var key = e.data.key;
        var name = e.data.name;
        var dataurl = e.data.dataurl;
        // Upload
    }
    // Once the upload is done, you can send a postMessage to the original window, with URL

    That’s all. If you have any other tips to share, feel free to drop a comment.

    Enjoy ;)

  5. Firefox 4 Beta: Latest Update is Here, with WebGL

    The new Firefox 4 Beta is here, and comes with WebGL activated by default. You can download this new beta here: http://firefox.com/beta.

    Flight of the Navigator is a WebGL + Audio API demo developed by a team of Mozilla volunteers.

    You can see the demo online here (you need a WebGL compatible browser).

    More information about this demo on David Humphrey’s blog (one of the developer of this demo) and more about WebGL in Firefox Beta8 on Vlad’s blog.

    The screencast:

  6. Firefox 4: recent changes in Firefox

    I’ve been really busy these days, and I didn’t have a chance to keep you updated, and a lot happened:

    These changes should be available in the next beta.

  7. Firefox 4: hardware acceleration

    The latest Firefox 4 beta has just been released. It comes with Direct2D acceleration activated by default.

    What is hardware acceleration?

    Hardware acceleration” is basically using the GPU when it’s possible (instead of the CPU). This makes page-drawing operations faster.

    There’s two different levels of acceleration going on:

    • Content acceleration speeds up rendering the actual page content, such as the text, images, CSS borders, etc. Content acceleration is also used to speed up the 2D HTML canvas. On Windows Vista/7, we use Direct2D for this and it has been activated in this new beta.
    • Compositing acceleration speeds up putting together chunks of already-rendered content (layers) together for final display in the window, potentially applying effects such as transforms along the way. For example, if you had a HTML5 video that was playing, and it had CSS effects applied to it that was making it rotate and fade in and out, that would be using compositing acceleration to make that go fast. (This feature is not activated by default yet.)

    >> Run the test yourself: Hardware Acceleration Stress Test. <<
    Credits for the photos: Paul (dex).

    Hardware Acceleration by operating system:

    These optimizations are available only if you have compatible hardware and the associated drivers.

    Operation Linux Windows XP Windows Vista/7 Mac OS X
    Content XRender None Direct2D Quartz1
    Compositing OpenGL Direct 3D Direct 3D OpenGL

    [1]: Quartz is basically CPU-only. QuartzGL (GPU acceleration for the Quartz 2D API) is not activated in Firefox for now (nor in other browsers).

    Important note: Don’t confuse hardware acceleration with WebGL. WebGL is an OpenGL-like API for Javascript to draw 3D objects into a <canvas> element. Obviously, WebGL is itself hardware accelerated since it uses OpenGL (or Direct3D through ANGLE on Windows if no OpenGL drivers are present).

    We need help!


    Help us to improve hardware acceleration in Firefox: Install the Grafx Bot extension (details here and add-on here).

    Firefox’s hardware acceleration interacts with a machine’s graphics hardware via DirectX or OpenGL, depending on platform. These interactions tend to be very sensitive to the graphics environment on the system (e.g., the specific video card(s) on the system, how much VRAM is available, the version of the video driver, the OS version, etc). In fact, there are so many permutations of the relevant factors that we can’t test them all internally.

    Grafx Bot runs a suite of automatic tests on your machine that exercises interesting aspects of hardware acceleration (for about 5 to 20 minutes). At the end of the tests, you can send your results to Mozilla (with anonymous video configuration information), where the data will be collected and analyzed, and hopefully lead to bug fixes and more reliable code for hardware acceleration than we’d otherwise have.

    We need help from the community, so we can get exposure on as many unique hardware environments as possible.

  8. Firefox 4 Beta: Latest update is here — what’s in it for web developers?

    The latest Firefox 4 Beta has just been released. Here is a quick overview of the new features for web developers.

    David’s Audio API demo:

    (try the audio demo )

    Myself about Hardware acceleration:

    (try the hardware acceleration demo )

    We need help!


    Help us to improve hardware acceleration in Firefox: Install the Grafx Bot extension (read details and get the add-on ).

    Firefox’s hardware acceleration interacts with a machine’s graphics hardware via DirectX or OpenGL, depending on platform. These interactions tend to be very sensitive to the graphics environment on the system (e.g., the specific video card(s) on the system, how much VRAM is available, the version of the video driver, the OS version, etc). In fact, there are so many permutations of the relevant factors that we can’t test them all internally.

    Grafx Bot runs a suite of automatic tests on your machine that exercises interesting aspects of hardware acceleration (for about 5 to 20 minutes). At the end of the tests, you can send your results to Mozilla (with anonymous video configuration information), where the data will be collected and analyzed, and hopefully lead to bug fixes and more reliable code for hardware acceleration than we’d otherwise have.

    We need help from the community, so we can get exposure on as many unique hardware environments as possible.

  9. Firefox 4: HTTP Strict Transport Security (force HTTPS)

    This article is about a new HTTPS header: Strict-Transport-Security, which force a website to be fetched through HTTPS. This feature will be part of Firefox 4.

    How do you type URLs?

    Do you prefix them with http:// or https:// systematically? Or do you just type example.com and let your browser add http://, like most of the people do?

    If a web page provide has an https version but you access it through http, what happens? The http version of the Website re-direct you to the https, but you first talked to the non-encrypted version of the website.

    These behaviors can be exploited to run a man-in-the-middle attack.

    To avoid this, you may want to force your website to be visited through https to transform any http://x.com request to https://x.com (with no client-server dialog).

    Sid Stamm recently integrated HTTP Strict Transport Security (HSTS) into
    Firefox. HSTS, specified in an IETF draft, allows sites to specify when they wish to be accessed only over https.

    A website can specify strict transport security for their domain via an HTTP header sent by the server set during an HTTPS response:

    Strict-Transport-Security: max-age=15768000

    or

    Strict-Transport-Security: max-age=15768000 ; includeSubDomains

    max-age sets how long to remember the forced HTTPS (seconds). If
    includeSubDomains is set, then this rule will apply to all the sub-domains too.

    In the future, any requests to x.com are modified to be via https if they are attempted through http before the request hits the network.

    This header is not considered during a non-encrypted HTTP transaction because the User-Agent doesn’t know if the https actually exists and also because the header can be injected by an attacker.

  10. Firefox 4: Drawing arbitrary elements as backgrounds with -moz-element


    This is a guest post by Markus Stange. Markus usually works on the Firefox Mac theme implementation, but this time he went on a small side trip through the Gecko layout engine in order to implement -moz-element.

    In Firefox Beta 4 we’re introducing a new extension to the CSS background-image property: the ability to draw arbitrary elements as backgrounds using -moz-element(#elementID).

    <p id="myBackground1" style="background: darkorange; color: white;  width: 300px; height: 40px;">
      This element will be used as a background.
    </p>
    <p style="background: -moz-element(#myBackground1); padding: 20px 10px; font-weight: bold;">
      This box uses #myBackground1 as its background!
    </p>



    A -moz-element() image works just like a normal url() image. That means it’s subject to all the familiar background properties like background-position, background-repeat, and even background-size.

    Using background-size you can create a thumbnail of the referenced element, for example:

    <ul id="thumbnails">
      <li style="background-image: -moz-element(#slide-0)"></li>
      <li style="background-image: -moz-element(#slide-1)"></li>
      <li style="background-image: -moz-element(#slide-2)"></li>
      <li style="background-image: -moz-element(#slide-3)"></li>
    </ul>
    #thumbnails li {
      width: 160px;
      height: 120px;
      background-repeat: no-repeat;
      background-size: contain;
    }



    There are three things to keep in mind about -moz-element:

    1. It’s live: whenever something happens in the referenced element, the -moz-element background image will be updated. It will also show things like text selection or blinking carets.

    2. It’s purely visual. That means you can’t “click through” to the original element. That’s by design.

    3. It works with any HTML element. Even with <iframe>



      <video>



      … and <canvas>.



    Canvas-as-background is in fact useful for some applications. For example, if you’re applying sepia tone to CSS background images in the browser, you now no longer have to convert the processed canvas image into a data URI. Instead, you can just set the canvas itself as the background image.

    Using a canvas as a background image is supported by Webkit, too, using -webkit-canvas().

    Painting loops

    A quick note on recursive references: If you try to paint an element that is already being painted via -moz-element, a painting loop will be detected and prevented. So you’ll need to think of a different way of drawing your Sierpinski carpets.

    Hiding the Referenced Element

    Sometimes you don’t want the original referenced element to be visible, only the -moz-element background image. So what do you do? You can’t just set display: none or visibility: hidden on the element, because then there’s nothing to draw in the -moz-element background image either – it will be transparent.

    Instead, you need to prevent the element from being rendered on the screen without really hiding it. One way of doing that is to wrap it with another element that has height: 0; overflow: hidden; set on it.

    There are three types of elements that are exempt from this rule: images, canvases and videos. These kinds of elements can have display: none and still be used in -moz-element. In fact, they don’t even need to be in the DOM.

    New DOM API:
    document.mozSetImageElement

    We added a new method to the document object: document.mozSetImageElement(<elementID>, <element>).

    Consider this piece of code:

    var slide5 = document.getElementById("slide-5");
    document.mozSetImageElement("current-slide", slide5);

    Now all elements with background-image: -moz-element(#current-slide) will draw the element with the ID slide-5, even if there is a real element with the ID current-slide!

    Calling document.mozSetImageElement("current-slide", null) will stop the override.

    This API can be handy in a variety of use cases. I already alluded to one of them in the previous section: with mozSetImageElement you can use canvas and image elements that aren’t part of the DOM tree.

    var img = new Image();
    img.src = "my_image.png";
    document.mozSetImageElement("image", img);
     
    var canvas = document.createElement("canvas");
    canvas.width = canvas.height = 100;
    var ctx = canvas.getContext("2d");
    // ... draw into ctx ...
    document.mozSetImageElement("canvas", canvas);

    View Demo

    Another scenario that benefits from mozSetImageElement involves JavaScript utility libraries. You might have a function like this:

    var runningNumber = 0;
    function addReflectionToElement(reflectedElement) {
      var referenceID = "reflected-element-" + runningNumber++;
      var reflection = document.createElement("div");
      reflection.className = "reflection";
      reflection.style.backgroundImage =
        "-moz-element(#" + referenceID + ")";
      document.mozSetImageElement(referenceID, reflectedElement);
      // ... insert reflection into the DOM ...
    }

    This way you can minimize the impact of your utility function because you don’t have to manipulate the ID of the element that was passed in.

    Finally, mozSetImageElement also allows you to reference elements from other documents, for example from inside iframes – obeying same origin restrictions, of course.

    -moz-element for SVG paint servers: patterns and gradients

    If you’ve ever written any SVG by hand you’re familiar with the concept of paint servers: those are the things you can use in your fill and stroke attributes when you don’t just want a single solid color. Now you can use them on HTML elements, too, using -moz-element:

    <p style="background: -moz-element(#pattern),
                          -moz-element(#gradient);
              padding: 10px; color: white">
      This element has both types of SVG paint servers
      in its background: a pattern and a gradient.
    </p>
     
    <svg height="0">
      <linearGradient id="gradient" x2="0" y2="1">
        <stop stop-color="black" offset="0%"/>
        <stop stop-color="red" offset="100%"/>
      </linearGradient>
      <pattern id="pattern" patternUnits="userSpaceOnUse"
               width="60" height="60">
        <circle fill="black" fill-opacity="0.5"
                cx="30" cy="30" r="10"/>
      </pattern>
    </svg>


    Note that we didn’t even have to use XHTML in order to be able to embed SVG thanks to our new HTML5 parser.

    This feature overlaps the functionality of CSS gradients and SVG images, but is very useful in some situations, such as animations. For example, say you want to create a progress bar with an animated gradient like this:

    You could do this with a CSS gradient and some JavaScript that periodically updates the background-position property. But you could also use an SVG gradient that’s animated with SMIL, requiring no JavaScript whatsoever:

    <div style="background: -moz-element(#animated-gradient);">
    </div>
     
    <svg height="0">
     
      <linearGradient id="animated-gradient" spreadMethod="reflect"
                      gradientUnits="userSpaceOnUse"
                      x1="16" x2="24" y2="0">
        <animate attributeName="x1" values="16; 0" dur="350ms"
                 repeatCount="indefinite"/>
        <animate attributeName="x2" values="24; 8" dur="350ms"
                 repeatCount="indefinite"/>
     
        <stop stop-color="#0F0" offset="0"/>
        <stop stop-color="#0D0" offset="100%"/>
      </linearGradient>
     
    </svg>

    View Demo

    The same could be achieved with CSS animations, but as long as they’re not implemented in Gecko you can use this.

    Support for SVG as a CSS background (bug 276431) will be added soon.

    Also, here’s a CSS + SVG Pacman for you.

    Applications

    I have two more suggestions for -moz-element usage:

    Reflections

    What is a reflection?

    #reflection {
      /* It's a copy of the original element... */
      background: -moz-element(#reflected-element)
                  bottom left no-repeat;
     
      /* ... turned upside down ... */
      -moz-transform: scaleY(-1);
     
      /* ... with a gradual fade-out effect towards the bottom. */
      mask: url(#reflection-mask);
    }



    Because we can apply arbitrary styles to the reflection, we can produce effects like animated water ripples.

    Fancy Slide Transitions

    In this demo I’d like to have a slideshow transition that looks like the upper half of the previous slide gets folded down to reveal the next slide:

    How would you implement this? You’ll obviously need to use some kind of transform, but on what element? The upper half of the slide needs to have a different transform than the lower half, so you can’t just set the transform on the slide itself.

    I ended up creating four new elements: #previousUpper, #previousLower, #nextUpper and #nextLower. I put them into a separate container called #transition which is only made visible while a transition is in progress. Then I gave them the right size and assigned the corresponding subimage of the previous / next slides to them using background-image: -moz-element(#previous/nextSlide) and the right background-position. And finally I set the transform on these helper elements.

    The code for it gets quite complex, though, so I’ll just direct you to the finished demo.

    More?

    My ideas for -moz-element demos have run out for the moment, but there’s bound to be more stuff one can do with it. Now it’s your turn!

    Credits

    Most of the credit here should go to Robert O’Callahan who cooked up the initial implementation back in 2008. After his initial experiments he had to work on more important things, though, so his patches lay dormant for about a year until he started a newsgroup thread to work out the right API in July 2009. Shortly after that, Ryo Kawaguchi revived roc’s work and spent the last weeks of his internship at Mozilla on it. Another year later I made the patch ready for review and drove it through the final stages until checkin.

    The same warnings as for mozRequestAnimationFrame apply: -moz-element and document.mozSetImageElement are experimental APIs. We do not guarantee to support them forever, and we wouldn’t evangelize sites to depend on them. We’ve implemented them so that people can experiment with them and we can collect feedback. We’ll propose it as a standard (minus the moz prefix, obviously), and author feedback on our implementation will help us make a better standard.