官术网_书友最值得收藏!

LED scoreboard using web fonts

In this recipe, we are going create an LED scoreboard similar to the ones used in basketball games by making a clever use of HTML web fonts. The main goal of the recipe is to get introduced to web fonts and the features they offer.

Tip

The full specification on web fonts can be found on W3C at http://www.w3.org/TR/css3-webfonts/.

Getting ready

Before staring, you need to get the font we are going to use in this example. The files can be retrieved from the examples code, and they all have a RADIOLAND prefix.

How to do it...

To create the scoreboard, we will create an HTML page, a backing JavaScript code that will update the timers, and related data, as well as a CSS file that will use web fonts:

  1. First, we will start with creation of the HTML page; in the head section, include stylesheet.css and a dependency to jQuery
      <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8">
      <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
  2. In the body part, add the div elements that we are going to use as placeholders for the scores and additionally include scoreboard.js:
        <div class="counter"></div>
        <div class="score">
                  <span class="home"></span>
                   <span class="period"></span>
                   <span class="guests"></span>
        </div>
      </div>
      <script type="text/javascript" src="scoreboard.js"></script>
  3. We can now create the stylesheet.css file, defining first the web font that has the LED look:
    @font-face {
      font-family: 'RadiolandRegular';
      src: url('RADIOLAND-webfont.eot');
      src: url('RADIOLAND-webfont.eot?#iefix') format('embedded-opentype'),
        url('RADIOLAND-webfont.woff') format('woff'),
        url('RADIOLAND-webfont.ttf') format('truetype'),
        url('RADIOLAND-webfont.svg#RadiolandRegular') format('svg');
      font-weight: normal;
      font-style: normal;
    }
  4. As the font is now defined as RadiolandRegular, we can refer to it directly:
    div.counter{
      font: 118px/127px 'RadiolandRegular', Arial, sans-serif;
      color: green;
    }
        .score {
          font: 55px/60px 'RadiolandRegular', Arial, sans-serif;
          letter-spacing: 0;
          color: red;
          width: 450px;
        }
    
      .period {
          font: 35px/45px 'RadiolandRegular', Arial, sans-serif;
          color: white;
        }
    
        div.display {
          padding: 50px;
        }
  5. We can proceed with the creation of the JavaScript that will be used and we'll use a mock object called game that has the game information. This object, in general, should be retrieved from a server using an AJAX call, but for simplicity, we are using some predefined values:
      var game = {
        periodStart: 1354650343000,
        currentPeriod: 1,
        score: {
          home: 15,
          guests: 10
        }
      };
  6. In order to have the logic for creation of our display object and for fetching the data separated, we can put it in a function:
      function fetchNewData() {
        // server data
        var game = {
          periodStart: new Date().getTime(),
          //the server will return data like: periodStart: 1354838410000,
          currentPeriod: 1,
          score: {
            home: 15,
            guests: 10
          }
        };
        //return display data
        return {
          periodStart: game.periodStart,
          counter: '00:00',
          period: game.currentPeriod + ' Period',
          score: {
            home: game.score.home,
            guests: game.score.guests
          }
        };
      }
  7. We also create a config object where we can define game parameters, such as number of periods and minutes per period:
      var config = {
        refreshSec: 1,
        periods: 4,
        minPerPeriod: 12
      };
  8. We then define the updateCounter() and updateScore() functions that will update the display and perform calculations for the timers. We are going to check if the current time is smaller that the start time of the game and set the timer to 00:00. If current time is greater than the max possible, set the timer to max possible for a period:
      function updateCounter() {
              var now = new Date(),
              millsPassed = now.getTime() - displayData.periodStart;
    
             if (millsPassed < 0) {
               displayData.counter = '00:00';
             } else if (millsPassed > config.minPerPeriod * 60 * 1000) {
               displayData.counter = config.minPerPeriod + ':00';
             } else {
               //counting normal time
               var min = Math.floor(millsPassed/60000);
               if (min<10) {
                 min = '0' + min;
               }
               var sec = Math.floor((millsPassed % 60000)/1000);
               if (sec<10) {
                 sec = '0'+sec;
               }
               displayData.counter = min+':'+sec;
             }
             $('.counter').text(displayData.counter);
             $('.period').text(displayData.period);
  9. Following that, we add a function that will update the score:
      function updateScore(){
        $('.home').text(displayData.score.home);
        $('.guests').text(displayData.score.guests);
      }
  10. At the end, we can call the setInterval function that will call the updates every 500 milliseconds:
        setInterval(updateCounter, 500);
        setInterval(updateScore, 500);

How it works…

The HTML and JavaScript code are pretty straightforward in this recipe, but on the other hand, we are taking a deeper look at the CSS and the font files.

With the addition of the @font-face at-rule, we can specify online fonts to use in other other elements. By doing this, we allow the use of different fonts that are not available on the client machine.

In the definition of @font-face, we add font-family—a name definition that we can afterwards apply on any element. For example, consider the following example where we call our font someName:

@font-face {
  font-family: someName;
  src: url(awesome.woff) format("woff"),
       url(awesome.ttf) format("opentype");
}

You can notice the format definition named format("woff") next to url in this example as well as in our stylesheet.css. The following formats can be applied there:

  • .woff: This stands for Web Open Font Format (WOFF), a format developed by Mozilla and is one of the newer standards around. The full specification is available on http://www.w3.org/TR/WOFF/. The format's goal is to provided alternative solutions to other formats that would be optimal for use in cases where we need a certain level of licensing. The format allows metadata to be attached to the file itself that can contain the license.
  • .ttf and .otf: The TrueType Font (TTF) and the extended version OpenType Font (OTF) are some of the most widely used types. The standard for TrueType was developed by Apple Computers by the end of the 80s as a replacement of some of the PostScript standards. It provided the font developers with flexibility and control over how the fonts are shown to the user with many different sizes. Due to its popularity and features, it swiftly spreads over to other platforms such as Windows. OpenType is a successor to TrueType up on which it is based. The specification was developed by Microsoft with additions from Adobe Systems. The name OpenType is a registered trademark of Microsoft Corporation. Detailed specification can be found on http://www.microsoft.com/typography/otspec/default.htm.
  • .eot: Embedded OpenType fonts are a form of OpenType fonts designed for use on web pages. The extensions done on the embedded versions are closely related to making copy protection. As the other fonts are easily copied, EOT gives only a subset of the available characters to the user, making it more difficult to copy the font fully. More information on EOT can be found on the W3C specification at http://www.w3.org/Submission/EOT/.
  • .svg and .svgz: SVG and the gunziped version with extension .svgz can be used to represent fonts. The font definition is stored as SVG glyph allowing easy support. More on SVG fonts can be found on the specification at http://www.w3.org/TR/SVG/fonts.html. Unfortunately, this format is not supported in IE and Firefox at the time of writing.

There are few other attributes that can be used on @font-face, such as font-style, font-weight, and font-stretch. Also, we can specify a range of the characters used in Unicode by setting a value for unicode-range. Some examples for this taken from the specification are as follows:

  • unicode-range: U+0-7F;: This is a code range for basic ASCII characters
  • unicode-range: U+590-5ff;: This is a code range for Hebrew characters

One of the problems with web fonts is that no particular format is requested by the specification of CSS2. This often means that we need to offer several different formats to get identical experience across browsers.

Note

There a many font-face definition generators that simplify the creation of all of these possible options. One such is FontSquirrel (http://www.fontsquirrel.com/tools/webfont-generator).

Web fonts are becoming one of the most common building blocks of the Web, and as such, they should be always considered when we are in a need of a great looking typography. Images, SVG, Coufons, and similar types just don't play well with text. We might get great looking text using those, but the text will not be accessible by search engines, most of the accessibility software will ignore it, and it might even get the page size larger. On the other hand, using text allows us to do various CSS tweaks on the data where we can use selectors, such as :first-letter, :first-line, and :lang.

There's more...

Google has a good selection of fonts that we can use that are provided on http://www.google.com/fonts/. Besides the standard inclusion of fonts, they also have a JavaScript-based font loader. This loader solves the problem of seeing the fallback text rendering while the "real" font is loading, commonly known as Flash of Unstyled Text (FOUT). There, for example, we can do the following to include a font called 'Noto Sans':

<script type="text/javascript">
  WebFontConfig = {
    google: { families: [ 'Noto+Sans::latin' ] }
  };
  (function() {
    var wf = document.createElement('script');
    wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
      '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
    wf.type = 'text/javascript';
    wf.async = 'true';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(wf, s);
  })(); </script>

Afterwards, we can simply include it in CSS using font-family: 'Noto Sans', sans-serif;.

Note

More on the options for Google fonts can be found at https://developers.google.com/fonts/. As for the so-called FOUT and some of the ways to fight it there is more on an article by Paul Irish at http://paulirish.com/2009/fighting-the-font-face-fout/.

主站蜘蛛池模板: 修文县| 东阿县| 新田县| 西城区| 桦南县| 岳池县| 石台县| 略阳县| 北海市| 商水县| 漾濞| 桃园市| 收藏| 称多县| 广南县| 苍山县| 望都县| 共和县| 监利县| 碌曲县| 西乌珠穆沁旗| 浦城县| 施秉县| 阳泉市| 遵义市| 尚志市| 普宁市| 建水县| 克什克腾旗| 临高县| 勐海县| 大方县| 左贡县| 镇坪县| 治多县| 平果县| 洪湖市| 福建省| 石林| 崇明县| 抚远县|