Mozilla

Demos

Sort by:

View:

  1. animating SVG with canvas and burst

    Today’s demo is short, but it also includes a long screencast that describes how it’s put together. The demo’s author, Alistair MacDonald (@F1LT3R), is one of the maintainers of Processing.js and the Burst engine, which is the basis for today’s demo and tutorial.

    If you haven’t clicked through to his site, I strongly suggest that you do so. You’ll notice that the site is animated and slick-looking with sections that slide in and out and lots of graphics. It’s the kind of thing that you normally would see written in flash, but there’s no flash on the main page. It’s all CSS, canvas and animation in the DOM. Pretty amazing.

    On to the demo. There have been some demos done with animating SVG but there’s one thing that stands out about this one that makes it different. Instead of loading SVG natively into the DOM, which is how SVG was originally designed, the Burst engine loads the SVG, parses it and creates some JS objects around it which you can then use to render it to a canvas. From there you can quickly animate it with the Burst engine and mix it with other content on a canvas.

    I also strongly suggest that you watch the tutorial on how this demo was put together. He shows how easy it is to take inkscape, the Burst engine and other simple JS to take a simple drawing and animate it. It’s worth the length of the video.

  2. the tristan washing machine

    This is another demo from Paul Rouget. It’s a very simple demonstration of what you can do when you combine video, SVG and some fun transformations.

    View the Demo in Firefox 3.5
    tristan

    This puts a HTML5-based <video> element into an SVG document like so:

    <svg:svg xmlns:svg="http://www.w3.org/2000/svg"
                   width="194" height="194">
      <svg:foreignObject x="1" y="1" width="192" height="192">
        <html:video src="tristan3.ogv" ontimeupdate="rotateMePlease()"/>
      </svg:foreignObject>
    </svg:svg>
    Lots of code and many attributes removed for clarity. Please view the source for more details.

    If you look at the rest of the source code you will also see that the rest of the player is also defined and controlled from SVG. And we’re also using some of the CSS and SVG capabilities that are in Firefox 3.5 to define the player as well. For example if you look at the CSS you will see:

    #video {
        filter: url(#filter);
        clip-path: url(#circle);
    }

    The clip-path property lets you define a clip path for any element – html, svg or otherwise. This can be extremely powerful and can be any arbitrary path defined in SVG. Much like a cookie cutter this cuts out the center of the otherwise square video and uses that for display. Here’s what our clip path looks like:

    <svg:clipPath id="circle" clipPathUnits="objectBoundingBox">
       <svg:circle cx="0.5" cy="0.5" r="0.5"/>
    </svg:clipPath>

    The filter property lets you define an SVG filter to use in the same way as a clip path. In our case we use a feColorMatrix:

    <svg:filter id="filter">
      <svg:feColorMatrix values="0.3 0.3 0.3 0 0 0.3 0.3 0.3 0 0 0.3 0.3 0.3 0 0 0 0 0 1 0"/>
    </svg:filter>

    Although it is not used in this demo note that you can also use SVG to define gradient masks for any element in Firefox 3.5 as well.

    When the video runs it uses the transformation property to rotate the video while it’s playing:

    function rotateMePlease() {
        // Sure
        if (!video) return;
        video.style.MozTransform='rotate(' + i + 'deg)';
        i += 3;
    }

    You will notice that Paul built this into an XHTML document, carefully using namespaces and XML syntax. But most people would probably want to use SVG in plain-old-HTML. In Firefox 3.5 there is a way to do this using SVG External Document References. What this means is that instead of defining your SVG in the HTML file directly you can define it in its own file and refer to it through CSS like this:

    .target { clip-path: url(resources.svg#c1); }

    What this does is load the SVG from the resources.svg file and then use the object with the ID “c1″ as the clip path for the target. This is a very easy way to add SVG to your document without making the full switch to XHTML.

    I hope that this gives you a taste of what’s possible when mixing SVG, HTML, video and CSS all together. Enjoy!

  3. HTML5 context menus in Firefox (Screencast and Code)

    You may not know it, but the HTML5 specifications go beyond what we put in the pages and also define how parts of the browser should become available to developers with HTML, CSS and JavaScript. One of these parts of the specs are context menus, or “right click menus”. Using HTML5 and a menu element you can add new options to these without having to write a browser add-on. In Firefox 8 (the current one) we have support for those. See the following screencast for a context menu demo.

    The image example is pretty simple and was actually written by Paul Rouget as a demo in the original Firefox bug request. The main core is the HTML of it:

    <section id="noninteractive" contextmenu="imagemenu">
     
      <img src="html5.png" alt="HTML5" id="menudemo">
     
        <menu type="context" id="imagemenu">
          <menuitem label="rotate" onclick="rotate()"
                    icon="arrow_rotate_clockwise.png">
          </menuitem>
          <menuitem label="resize" onclick="resize()"
                    icon="image-resize.png">
          </menuitem>
          <menu label="share">
            <menuitem label="twitter" onclick="alert('not yet')"></menuitem>
            <menuitem label="facebook" onclick="alert('not yet')"></menuitem>
          </menu>
        </menu>
     
    </section>

    As you can see you link the menu element to an element via its ID. The contextmenu attribute then points to this one. Each menu can have several menuitems. Each of those gets a textual label and a possible icon. You can also nest menu elements to create multiple layer menus. Here, we add inline onclick handlers to point to different JavaScript functions to call when the menu item gets activated. The resulting context menu looks like this:

    image with a context menu

    The functionality is simple, all the rotate() and resize() functions do is add class names to the image using querySelector and classList:

    function rotate() {
      document.querySelector('#menudemo').classList.toggle('rotate');
    }
    function resize() {
      document.querySelector('#menudemo').classList.toggle('resize');
    }

    The real effect is in CSS transforms and transitions. As the image has an ID of menudemo here is what is needed in CSS to rotate and resize:

    #menudemo {
      -moz-transition: 0.2s;
      width:200px;
    }
    #menudemo.rotate {
      -moz-transform: rotate(90deg);
    }
    #menudemo.resize {
      -moz-transform: scale(0.7);
    }
    #menudemo.resize.rotate {
      -moz-transform: scale(0.7) rotate(90deg);
    }

    Notice that in a real product we should of course add the other browser prefixes and go prefix-less but as the functionality now only works in Firefox, this is enough for this demo.

    Detecting support and visual hinting

    Now, as this is extending the normal user offerings in the browser we need to make it obvious that there is a right-click menu available. In CSS3, there is a context-menu cursor available to us. When context menus are available, this should be shown:

    .contextmenu #menudemo, .contextmenu .demo {
      cursor: context-menu;
    }

    We test the browser for support by checking for contextmenu on the body element and for HTMLMenuItemElement in the window (this has been added as a pull request to Modernizr, too).

    if ('contextMenu' in document.body && 'HTMLMenuItemElement' in window) {
      document.documentElement.classList.add('contextmenu');
    } else {
      return;
    }

    Wouldn’t HTMLMenuItemElement be enough? Yes, but a real context menu should only offer functionality when it is sensible, and that is where contextMenu comes in.

    Turning menuitems on and off depending on functionality

    As a slightly more complex example, let’s add a “count words” functionality to the document. For this, we generate a counter element that will become a tooltip when the words were counted:

    var counter = document.createElement('span');
    counter.id = 'counter';
    counter.className = 'hide';
    document.body.appendChild(counter);
     
    counter.addEventListener('click', function(ev){
      this.className = 'hide';
    },false);

    This one is hidden by default and becomes visible when the hide class is removed. To make it smooth, we use a transition:

    #counter{
      position: absolute;
      background: rgba(0,0,0,0.7);
      padding:.5em 1em;
      color: #fff;
      font-weight:bold;
      border-radius: 5px;
      -moz-transition: opacity 0.4s;
    }
    #counter.hide{
      opacity: 0;
    }

    We start with two sections with context menus:

    <section id="noninteractive" contextmenu="countmenu">
      <menu type="context" id="countmenu">
          <menuitem class="wordcount" label="count words"></menuitem>
      </menu>
    </section>
     
    <section id="interactive" contextmenu="countmenuinteractive">
      <menu type="context" id="countmenuinteractive">
          <menuitem class="wordcount" label="count words"></menuitem>
      </menu>
    </section>

    We then loop through all the menuitems with the class wordcount and apply the functionality.

    var wordcountmenus = document.querySelectorAll('.wordcount'),
        i = wordcountmenus.length;
     
    while (i--) {
      wordcountmenus[i].addEventListener('click', function(ev){
        // add functionality
      }, false);
    }

    We need to find out what has been selected in the page. We do this by using getSelection() and splitting its string version at whitespace. We then show the counter by removing the hide class name.

    var wordcountmenus = document.querySelectorAll('.wordcount'),
        i = wordcountmenus.length;
     
    while (i--) {
      wordcountmenus[i].addEventListener('click', function(ev){
        var text = document.getSelection(),
            count = text.toString().split(/s/).length;
        counter.innerHTML = count + ' words';
        counter.className = '';
      }, false);
    }

    You can see this in action in the second context menu demo. Now, the issue with this (as explained in the screencast) is that it always counts the words, regardless of the user having selected some text. What we want is the menu only to be active when there is text selected.

    context menu item available or not available depending on selection

    So in order to make our menu only become available when it makes sense we check if there is a selection in the document. Every context menu fires an event called contextmenu when it opens. So all we need to do is to subscribe to this event.

    When something is selected in the document document.getSelection().isCollapsed is true. Otherwise it is false, so all we need to do is to enable or disable the menu item accordingly:

    document.querySelector('#interactive').addEventListener(
      'contextmenu', function(ev) {
        this.querySelector('.wordcount').disabled =
        document.getSelection().isCollapsed;
      },
    false);

    The last thing to solve is the position of the mouse to position the counter element. As the menu selection event doesn’t give us the mouse position we need to add a contextmenu handler to the whole document that positions the counter invisibly behind the menu when it is opened:

    document.body.addEventListener(
      'contextmenu', function(ev) {
        counter.style.left = ev.pageX + 'px';
        counter.style.top = ev.pageY + 'px';
        counter.className = 'hide';
      },
    false);

    Further reading and resources

  4. Firefox 3.6 FileAPI demo: reading EXIF data from a local JPEG file

    Paul Rouget has put together a great demo of the new FileAPI we’re including in Firefox 3.6. It lets you drag a JPG from the desktop into the browser that includes EXIF data and it can extract the GPS coordinates in the image and then load the location of where the photo was taken, entirely from JavaScript.

    If you have the Firefox 3.6 beta, you can view the demo or you can just watch the video below.

  5. The shortest image uploader – ever!

    A couple of line of JavaScript. That’s all you need.

    This is a very short Image Uploader, based on imgur.com API. If you want to do more complex stuff (like resize, crop, drawing, colors, …) see my previous post.

    Back-story. I’ve been talking to Imgur.com‘s owner (Hi Alan!). He recently added Drag’n Drop support to his image sharing website. But also, Alan allows Cross-Domain XMLHttpRequest (thank you!). So basically, you can use his API to upload pictures to his website, from your HTML page, with no server side code involved – at all.

    And here is an example of what you can do:

    (see the full working code on github – live version there )

    (also, you’ll need to understand FormData, see here)

    function upload(file) {
     
      // file is from a <input> tag or from Drag'n Drop
      // Is the file an image?
     
      if (!file || !file.type.match(/image.*/)) return;
     
      // It is!
      // Let's build a FormData object
     
      var fd = new FormData();
      fd.append("image", file); // Append the file
      fd.append("key", "6528448c258cff474ca9701c5bab6927");
      // Get your own key: http://api.imgur.com/
     
      // Create the XHR (Cross-Domain XHR FTW!!!)
      var xhr = new XMLHttpRequest();
      xhr.open("POST", "http://api.imgur.com/2/upload.json"); // Boooom!
      xhr.onload = function() {
        // Big win!
        // The URL of the image is:
        JSON.parse(xhr.responseText).upload.links.imgur_page;
       }
       // Ok, I don't handle the errors. An exercice for the reader.
       // And now, we send the formdata
       xhr.send(fd);
     }

    That’s all :)

    Works on Chrome and Firefox 4 (Edit:) and Safari.

  6. a multi-touch drawing demo for Firefox 3.7

    Firefox Multitouch at MozChile – Drawing Canvas Experiment from Marcio Galli on Vimeo.

    A couple of months ago we featured a video that had some examples of multi-touch working in Firefox. At a recent event in South America, Marcio Galli put together a quick and fun drawing program based on the multi-touch code that we’ll have in a later release of Firefox. What’s really great is that he was able to put this together in just a couple of hours based on the web platform.

    There are three main components to the touch support in Firefox:

    1. Touch-based scrolling and panning for the browser. This allows you, as a user, to scroll web pages, select text, open menus, select buttons, etc. This is part of Firefox 3.6.

    2. Implement a new CSS selector that will tell you if you’re on a touch-enabled device. This is -moz-system-metric(touch-enabled). You can use this in your CSS to adjust the size of UI elements to fit people’s fingers. This is part of Firefox 3.6.

    3. Exposing multi-touch data to web pages. This takes the form of DOM events much like mouse events you can catch today. This isn’t part of Firefox 3.6, but is likely to be part of Firefox 3.7.

    Although not all of this will be in our next release we thought it would be fun for people to see what will be possible with the release after 3.6.

    Note: You can find the sample code on Marcio’s page for the demo.

  7. bringing multi-touch to Firefox and the web

    The ever-energetic Felipe Gomes was nice enough to intern with Mozilla this summer in between busy semesters in Brazil. During that time he’s been working on multi-touch support for Firefox on Windows 7. A nice result of that work is that he’s also found ways to bring multi-touch support to the web. He’s made a short video and written up some short technical information to go with it.

    This post has also been cross-posted to Felipe’s personal blog.

    Multitouch on Firefox from Felipe on Vimeo.

    I’ve been anxious to demonstrate the progress on our multi-touch support for Firefox, and this video showcases some possible interactions and use cases for what web pages and webapps can do with a multi-touch device.

    We’re working on exposing the multi-touch data from the system to regular web pages through DOM Events, and all of these demos are built on top of that. They are simple HTML pages that receive events for each touch point and use them to build a custom multi-touch experience.

    We’re also adding CSS support to detect when you’re running on an touchscreen device. Using the pseudo-selector :-moz-system-metric(touch-enabled) you can apply specific styles for your page if it’s being viewed on a touchscreen device. That, along with physical CSS units (cm or in), makes it possible to adjust your webapp for a touchscreen experience.

    Firefox 3.6 will include the CSS property, but is unlikely to include the DOM events described below.

    Here is an example of what the API looks like for now. We have three new DOM events (MozTouchDown, MozTouchMove and MozTouchRelease), which are similar to mouse events, except that they have a new attribute called streamId that can uniquely identify the same finger being tracked in a series of MozTouch events. The following snippet is the code for the first demo where we move independent <div>s under the X/Y position of each touch point.

    var assignedFingers = {};
    var lastused = 0;
     
    function touchMove(event) {
        var divId;
        if (lastused < = 4)
            return;
     
        if (assignedFingers[event.streamId]) {
            divId = assignedFingers[event.streamId];
        }
        else {
            divId = "trackingdiv" + (++lastused);
            assignedFingers[event.streamId] = divId;
        }
     
        document.getElementById(divId).style.left = event.clientX + 'px';
        document.getElementById(divId).style.top  = event.clientY + 'px';
    }
     
    document.addEventListener("MozTouchMove", touchMove, false);
    document.addEventListener("MozTouchRelease",
                              function () { lastused--; }, false);

    On the wiki page you can see code snippets for the other demos. Leave any comments regarding the demos or the API on my weblog post. We really welcome feedback and hope to start some good discussion on this area. Hopefully as touch devices (mobile and notebooks) are getting more and more popular we’ll see new and creative ways to use touch and multitouch on the web.

  8. WebRTC efforts underway at Mozilla!

    Last week, a small team from Mozilla attended IETF 83 in Paris, and we showed an early demo of a simple video call between two BrowserID-authenticated parties in a special build of Firefox with WebRTC support. It is still very early days for WebRTC integration in Firefox, but we’re really excited to show you something that works!

    At Mozilla Labs, we’ve been experimenting with integrating social features in the browser, and it seemed like a cool idea to combine this with WebRTC to establish a video call between two users who are signed in using BrowserID (now called Persona). The SocialAPI add-on, once installed, provides a sidebar where web content from the social service provider is rendered. In our demo social service, we show a “buddy list” of people who are currently signed in using Persona.

    The video chat page that is served when the user initiates a video chat uses a custom API intended to simulate the getUserMedia and PeerConnection APIs currently being standardized at the W3C. A <canvas> is used to render both the remote and local videos, though it is also possible to render them in a <video>. We’re working very quickly to implement the standard APIs, and you can follow our progress on the tracker bug.

    A lot of folks burned the midnight oil to get this demo ready before the IETF event, and special thanks are due to Eric Rescorla, Michael Hanson, Suhas Nandakumar, Enda Mannion, Ethan Hugg, the folks behind Spacegoo, and Randell Jesup, in addition to the whole media team here at Mozilla.

    Current development is being done on a branch of mozilla-central called alder. It is going to be an exciting few months ahead as we work towards bringing WebRTC to Firefox. There is a lot of work to do, and if you are interested in contributing, please reach out! Maire Reavy, our product person and project lead for WebRTC would be happy to help you find ways to contribute. Many of us are also usually available in IRC at #media, and we have a mailing list.

    Transcript of screencast:

    Hi, I’m Anant from Mozilla Labs and I’m here at IETF where we are demonstrating a simple video call between two BrowserID-authenticated parties, using the new WebRTC APIs that we are working on.

    This is a special build of Firefox with WebRTC support, and also has the experimental SocialAPI add-on from Mozilla Labs installed. On the right hand side you can see web content served by demosocialservice.org, to which I will sign with BrowserID. Once I’m signed in, I can see all my online friends on the sidebar. I see my friend Enda is currently online, and so I’m going to click the video chat button to initiate a call.

    Here, I see a very early prototype of a video call window served up by our demo social service. Now, I can click the Start Call button to let Enda know that I want to speak with him. Once he accepts the call, a video stream is established between the two parties as you can see. So, that was a video call built entirely using JavaScript and HTML!

    You can check out the source code for this demo, as well as learn how to contribute to the ongoing WebRTC efforts at Mozilla in this blog post. Thanks for watching!

  9. another great CSS media query demo

    This demo is from Daniel Glazman who works actively on web standards and is a long-time mozilla contributor.

    CSS Media Queries were originally a proposal submitted to the CSS Working Group by Opera Software and are now implemented in Firefox 3.5. In short, Media Queries extend the media declaration attached to a stylesheet to allow matching based on the rendering device’s intrinsic properties.

    Let’s take a link element declaring a stylesheet inside an HTML document:

    <link rel="stylesheet" type="text/css" href="style.css"
          media="screen">

    Now imagine you want this stylesheet to apply to the document if and only if the width of the content window is less than 300 pixels… CSS Media Queries make it simple to declare:

    <link rel="stylesheet" type="text/css" href="style.css"
          media="screen and (max-width: 300px)">

    Available properties include viewport’s width and height, device’s width and height, orientation (portrait or landscape), viewport’s aspect ratio, device’s aspect ratio, colormap, resolution and type of device.

    It’s then very easy to have one single web page ready for consumption on a wide variety of devices, ranging from mobile devices to monochrome tty displays.

    When viewing the demo, please don’t forget to resize the window from large to very very small (less than 100px!) to see it in action.

    Loading via planet, RSS or a reader without JavaScript? Click here instead.