惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
C
CERT Recently Published Vulnerability Notes
Forbes - Security
Forbes - Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
L
LINUX DO - 最新话题
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
SecWiki News
SecWiki News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The Last Watchdog
The Last Watchdog
S
Schneier on Security
T
Troy Hunt's Blog
N
News | PayPal Newsroom
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Schneier on Security
Schneier on Security
P
Privacy & Cybersecurity Law Blog
T
Tor Project blog
T
Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
Arctic Wolf
S
Secure Thoughts
P
Proofpoint News Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Security Latest
Security Latest
Scott Helme
Scott Helme
Security Archives - TechRepublic
Security Archives - TechRepublic
Latest news
Latest news
PCI Perspectives
PCI Perspectives
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V2EX - 技术
V2EX - 技术
Google DeepMind News
Google DeepMind News
Project Zero
Project Zero
V
Vulnerabilities – Threatpost
T
Threat Research - Cisco Blogs
Webroot Blog
Webroot Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
大猫的无限游戏
大猫的无限游戏
T
Tenable Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
H
Hacker News: Front Page
Simon Willison's Weblog
Simon Willison's Weblog
AWS News Blog
AWS News Blog

remy sharp's l:inks

Deno Style Guide Easy 6502 by skilldrick Profiling React.js Performance BEM Naming Cheat Sheet by 9elements Visual 6502 Remix Elijah Manor (@elijahmanor) on X All – Tiny Helpers AST explorer Insecure How to Authenticate with Next.js and Auth0: A Guide for Every Deployment Model Revealed: quarter of all tweets about climate crisis produced by bots I Add 3-25 Seconds of Latency to Every Page I Visit GitHub - ericchiang/pup: Parsing HTML at the command line Browserling – Online cross-browser testing Error Handling with GraphQL and Apollo Schwerkraftprojektionsgerät How To Turn Off Catalina Update Notifications (Prompts & Badges) • macReports Maskable.app It’s 2020 and you’re in the future Emulators written in JavaScript | Frederic Cambus The Size of Space systemfontstack JavaScript isn’t always available and it’s not the user’s fault Programming Fonts - Test Drive Screen Size Map GitHub - Yonet/MixedRealityResources: Mixed Reality related resources The Lines of Code That Changed Everything Notes from the Internet Health Report 2019 CopyPalette Generative Artistry Profile a React App for Performance nanoSQL 2 Moving Your JavaScript Development To Bash On Windows — Smashing Magazine Startup Playbook How to Release a Custom React Component, Hook or Effect as an npm Package React Suite - Enterprise React UI Component Library Use VSCode Dimmer to Highlight Code when Teaching 3 simple rules for effectively handling dates and timezones Large collection of how to animate pixelart Accessible React component libraries mineral-ui.com Australian Government Design System Reakit – Toolkit for building accessible UIs Chakra UI Curl Cookbook The problem with tooltips and what to do instead GitHub - trimstray/the-book-of-secret-knowledge: A collection of inspiring lists, manuals, cheatsheets, blogs, hacks, one-liners, cli/web tools and more. It Form design: from zero to hero all in one blog post Brussels changes its mind AGAIN on .EU domains: Euro citizens in post-Brexit Britain can keep them after all Improve Your Email Campaigns with These Fantastic Tools Ethical Web Principles Old Typewriter Text Effect Bruce Lawson Google open sources standardized code in bid to become Mr Robots.txt Preferreds-color-scheme:你好,黑暗,我的老朋友  |  Articles  |  web.dev Free for Developers Startup idea checklist Developing a Robust Font Loading Strategy for CSS-Tricks—zachleat.com How I use Slack—alone—to get more done Upcoming proposals in JavaScript 🦄 VueJS is dead, long live VueJS! Bruce Lawson Answers for young people - Tim Berners-Lee Finally, an AI that can reliably catch and undo Photoshop airbrushing. Who made it? Er, Photoshop maker Adobe Qubyte Codes - How I schedule posts using GitHub Actions Games and Graphics in Popup URL bars Stack 58 bytes of css to look great nearly everywhere The reduce ({...spread}) anti-pattern - RichSnapp.com The Online Disassembler CSS Gradient – Generator, Maker, and Background Chrome DevTools  |  Chrome for Developers HB88 | Đăng Nhập HB88 Cá Cược Nhanh Chóng Không Bị Chăn #1 Introducing React Apollo 2.1 - Apollo GraphQL Blog Color Palettes Generator and Color Gradient Tool Clément Chastagnol ~ Moving efficiently in the CLI Testing Async Components · Issue #346 · enzymejs/enzyme Game Platforms recent news | Game Developer Professional Sound Effects - Royalty-Free SFX | Unlimited Downloads entr(1) Learn React From The Comfort Of Your Browser Axe Rules | Deque University Record and share your terminal sessions, the simple way Web Design Museum Powerful New Additions to the CSS Grid Inspector in Firefox Nightly – Mozilla Hacks - the Web developer blog Latency | Apex Software HackerNoon Signals and Sine Waves (Learn Web Audio from the Ground Up, Part 1) JavaScript Systems Music Vintage bits on cassettes Microsoft Design Legal Documents & Contract Templates | Simply Docs create-graphql-server — instantly scaffold a GraphQL server GraphQL and MongoDB — a quick example Using GraphQL with MongoDB Your First GraphQL Server Build a GraphQL server from scratch Practical Redux, Part 3: Project Planning and Setup Freesound
PxLoader
Pixel Lab · 2012-01-10 · via remy sharp's l:inks

A JavaScript Preloader for HTML5 Apps

PxLoader is a Javascript library that helps you download images, sound files or anything else you need before you take a specific action on your site (like showing a user interface or starting a game). You can use it to create a preloader for HTML5 games and websites.

It let's you monitor download status by providing progress and completed events and it lets you prioritize the order in which items are downloaded. You can even tag groups of files and then prioritize downloads or register for events by tag.

We created PxLoader for the HTML5 version of Cut the Rope and out of the box works great with images and sound files (the types of resources we needed for the game), but it's designed to be extensible and work with any file type or other network action.

Step by Step Instructions

1. Download the script and place the files in the JavaScript directory of your site. The files you need are:

  • PxLoader.js (the main library file)
  • PxLoaderImage.js (the image file downloader if you want to download images)
  • PxLoaderSound.js (the sound file downloader if you want to download sounds)*
  • PxLoaderVideo.js (the video file downloader if you want to download videos)
  • Any other downloaders that you write or get in the plugins section of this page

*The sound file downloader works with SoundManager 2 and allows it do the heavy lifting of the actual download. In fact, PxLoader always defers downloads to the downloader objects. That gives a complex sound library like SoundManager 2 the ability to choose how to download the file based on whether it's using Flash or HTML5 for the audio.

2. Add the core JavasScript file.

<script type="text/javascript" src="js/PxLoader.js"></script>

3. Add plugins for the resource types you need.


<!- images -->
<script type="text/javascript" src="js/PxLoaderImage.js"></script>

<!- sounds -->
<script type="text/javascript" src="js/PxLoaderSound.js"></script>

Download Images Before Drawing to a Canvas

Images must be fully loaded before they can be drawn on an HTML5 canvas. In this example we wait for 3 images to download before drawing our picture.


// Create the loader and queue our 3 images. Images will not
// begin downloading until we tell the loader to start.
var loader = new PxLoader(),
    backgroundImg = loader.addImage('images/headerbg.jpg'),
    treesImg = loader.addImage('images/trees.png'),
    ufoImg = loader.addImage('images/ufo.png');

// callback that will be run once images are ready
loader.addCompletionListener(function() {
    var canvas = document.getElementById('sample1-canvas'),
        ctx = canvas.getContext('2d');

    ctx.drawImage(backgroundImg, 0, 0);
    ctx.drawImage(treesImg, 0, 104);
    ctx.drawImage(ufoImg, 360, 50);
});

// begin downloading images
loader.start();

Report Progress While Images Load

HTML5 games typically download a large number of images. In this example, we'll report progress while the game loads 100 images. We've configured our server to delay each image by 1 second to simulate large images and so you can watch the progress. Don't worry, your browser will download batches of images in parallel so the demo won't actually take 100 seconds.


// delay each image and append the timestamp to prevent caching
var baseUrl = 'http://thinkpixellab.com/pxloader' +
        '/slowImage.php?delay=1&time=' + new Date,
    $log = $('#sample2-log').val(''),
    $progress = $('#sample2-progress').text('0 / 100'),
    loader = new PxLoader();

// add 100 images to the queue
for(var i=0; i < 100; i++) {
    // this time we'll create a PxLoaderImage instance instead of just
    // giving the loader the image url
    var pxImage = new PxLoaderImage(baseUrl + '&i=' + i);

    // we can add our own properties for later use
    pxImage.imageNumber = i + 1;

    loader.add(pxImage);
}

// callback that runs every time an image loads
loader.addProgressListener(function(e) {

    // log which image completed
    $log.val($log.val() + 'Image ' + e.resource.imageNumber + ' Loaded\r');

    // scroll to the bottom of the log
    $log.scrollTop($log[0].scrollHeight);

    // the event provides stats on the number of completed items
    $progress.text(e.completedCount + ' / ' + e.totalCount);
});

loader.start();

Load Images in Groups

Many HTML5 sites need to download resources for several different sections of the app. PxLoader lets you tag and prioritize resources. For this example we'll assume that we need one set of images to draw a game menu and second set of images for the gameplay. Since we need to show the menu first we'll start the download for those images first. PxLoader can provide progress updates to many listeners and will scope the updates and statistics to only the set of tags a listener is interested in.


// delay each image and append the timestamp to prevent caching
var baseUrl = 'http://thinkpixellab.com/pxloader' +
        '/slowImage.php?delay=1time=' + new Date,
    $log = $('#sample3-log').val(''),
    $menuProgress = $('#sample3-menuProgress').text('0 / 50'),
    $gameProgress = $('#sample3-gameProgress').text('0 / 50'),
    $totalProgress = $('#sample3-totalProgress').text('0 / 100'),
    loader = new PxLoader();

// queue 50 images for each section
var addImagesForTag = function(tag, $progress) {
    for(var i=0; i < 50; i++) {
        var imageUrl = baseUrl + '&i=' + i + '&tag=' + tag;
            pxImage = new PxLoaderImage(imageUrl, tag);
        pxImage.imageNumber = i + 1;
        loader.add(pxImage);
    }

    // add a listener to update progress for the tag
    loader.addProgressListener(function(e) {
        $progress.text(e.completedCount + ' / ' + e.totalCount);
    }, tag); // scope listener to the current tag only
};

addImagesForTag('menu', $menuProgress);
addImagesForTag('game', $gameProgress);

// listen to every event to update total progress
loader.addProgressListener(function(e) {

    // log which image completed
    var line = ' Image ' + e.resource.imageNumber +
        ' Loaded [' + e.resource.tags[0] + ']\r';
    $log.val($log.val() + line);

    // scroll to the bottom of the log
    $log.scrollTop($log[0].scrollHeight);

    // the event provides stats on the number of completed items
    $totalProgress.text(e.completedCount + ' / ' + e.totalCount);
});

// start downloading images for tags in prioritized order
loader.start(['menu', 'game']);

Load a Set of Sound Effects

For this sample, we'll load 5 audio clips. Once all of the sounds are ready, we'll show a set of images that can be clicked to play each sound.

The PxLoaderSound plugin relies on SoundManager2 to load and play audio files. First, add the soundManager2 and PxLoaderSound script references:

<script type="text/javascript" src="soundManager2.js"></script>
<script type="text/javascript" src="PxLoaderSound.js"></script>

Next, you need to initialize the soundManager. Here are the settings we use:


// initialize the sound manager
soundManager.url = 'soundManager2/';
soundManager.flashVersion = 9;
soundManager.useHighPerformance = true; // reduces delays

// reduce the default 1 sec delay to 500 ms
soundManager.flashLoadTimeout = 500;

// mp3 is required by default, but we don't want any requirements
soundManager.audioFormats.mp3.required = false;

// flash may timeout if not installed or when flashblock is installed
soundManager.ontimeout(function(status) {
    // no flash, go with HTML5 audio
    soundManager.useHTML5Audio = true;
    soundManager.preferFlash = false;
    soundManager.reboot();
});

soundManager.onready(function() {
    // ok to show the button to run the sound sample
    $('#sample4-run').show();
});

Finally, here is the code to load and play each audio clip:


var soundNames = ['cow', 'pig', 'tractor', 'dino', 'r2d2'],
    loader = new PxLoader(),
    i, len, url;

// queue each sound for loading
for(i=0, len = soundNames.length; i < len; i++) {

    // see if the browser can play m4a
    url = 'audio/' + soundNames[i] + '.m4a';
    if (!soundManager.canPlayURL(url)) {

        // ok, what about ogg?
        url = 'audio/' + soundNames[i] + '.ogg';
        if (!soundManager.canPlayURL(url)) {
            continue; // can't be played
        }
    }

    // queue the sound using the name as the SM2 id
    loader.addSound(soundNames[i], url);
}

// listen to load events
loader.addProgressListener(function(e) {

    // show the icon once a sound has loaded
    var soundId = e.resource.sound.sID,
        $icon = $('#' + soundId).addClass('ready');

    // play the sound when the icon is clicked
    $icon.click(function() {

        // highlight the icon while playing
        $icon.addClass('playing');

        soundManager.play(soundId, {
            onfinish: function() {
                $icon.removeClass('playing');
            }
        });
    });
});

loader.start();

Documentation for the Core API

You can override the default settings when creating a new PxLoader instance.


// create a loader using the default settings
var loader = new PxLoader();

// create a loader with custom settings (shown with default values)
var loader = new PxLoader({
        // how frequently we poll resources for progress
        statusInterval: 5000, // every 5 seconds by default

        // delay before logging since last progress change
        loggingDelay: 20 * 1000, // log stragglers after 20 secs

        // stop waiting if no progress has been made in the moving time window
        noProgressTimeout: Infinity // do not stop waiting by default
    });

add(resource)

Add a resource to the the loading queue. This generic method allows PxLoader to handle any type of resource that has a PxLoader plugin.


// add an image with a url
loader.add(new PxLoaderImage('/image1.png'));

// add an image with a single tag
loader.add(new PxLoaderImage('/image2.png', 'tag1'));

// image with multiple tags
loader.add(new PxLoaderImage('/image3.png', ['tag1', 'tag2']);

// image with a priority (relative to another resource with the same tag)
loader.add(new PxLoaderImage('/image4.png', ['tag1', 'tag2'], 1);

Plugins may also add a convenience method to PxLoader which makes adding a new resource a little easier and more concise.


// The PxLoaderImage plugin provides addImage which returns the img element
// which can be used once the image has been downloaded
var imgElement1 = loader.addImage('/image1.png');
    imgElement2 = loader.addImage('/image2.png', 'tag1');

addProgressListener(callback, tags)

Registers a callback that will be called anytime an event occurs for a resource with the specified tag(s). If the tags parameter is omitted then progress updates will be provided for every resource.


// log the name of every resource as its loaded
loader.addProgressListener(function(e) {
    console.log(e.resource.getName());
});

// the callback function receives an event object:
var sampleEvent = {

    // the updated resource
    resource: {} // the resource parameter provided to loader.add()

    // status for the updated resource
    loaded: true,
    error: false,
    timeout: false,

    // stats for all resources that match the listener's tags
    completedCount: 42,
    totalCount: 100
};

addCompletionListener(callback, tags)

Works in the same way as the progress listener API, except instead of receiving updates for each change you are notified once everything completes.


// log when all resources have completed
loader.addCompletionListener(function(e) {
    console.log('Ready to go!');
});

log(showAll)

Writes a list of resources to the browser console. If showAll is true then all resources are logged, otherwise resources that have completed (loaded, error, or timeout) are omitted.


// write a list of resources we are still waiting for
loader.log();

isBusy()

Returns true if the loader is still waiting for some resources to complete.

start(orderedTags)

Starts downloading all queued resources. Resources are ordered and started by tag first and then by priority. Its important to register all event listeners before calling start() because its possible for the loader to complete very quickly if resources are cached.


// start loading resources according to resource priority alone
loader.start();

// start resources by tag first and then by priority
loader.start(['tag1', 'tag2']);

Plugins

Images

PxLoaderImage loads images using JavaScript <image> elements. We listen to load and readystate change events. Some browsers won't send events for cached images so we also check the iscomplete status during the periodic poll initiated by the loader. Errors are reported to the loader, and details can be retrieved from the img element's errors property.

SoundManager 2

PxLoaderSound loads audio using the SoundManager2 library. We're fans of this great little library because it supports HTML5 audio when available and falls back to flash when necessary.

Videos

Samples showing how to use this plugin are coming soon.

Plugin API

Writing a plugin so PxLoader can track another resource type is pretty easy. There are just a few functions that a resource should implement to communicate with the loader. Here is a skeleton that you can use to start.


function PxLoaderResource(url, tags, priority) {
    var self = this;
        loader = null;

    // used by the loader to categorize and prioritize
    this.tags = tags;
    this.priority = priority;

    // called by PxLoader to trigger download
    this.start = function(pxLoader) {
        // we need the loader ref so we can notify upon completion
        loader = pxLoader;

        // set up event handlers so we send the loader progress updates

        // there are 3 possible events we can tell the loader about:
        // loader.onLoad(self);    // the resource loaded
        // loader.onError(self);   // an error occured
        // loader.onTimeout(self); // timeout while waiting

        // start downloading
    };

    // called by PxLoader to check status of image (fallback in case
    // the event listeners are not triggered).
    this.checkStatus = function() {
        // report any status changes to the loader
        // no need to do anything if nothing has changed
    };

    // called by PxLoader when it is no longer waiting
    this.onTimeout = function() {
        // must report a status to the loader: load, error, or timeout
    };

    // returns a name for the resource that can be used in logging
    this.getName = function() {
        return url;
    }
}

Get Involved

We'd love to hear what you think about PxLoader. It's a work in progress and we'd welcome any suggestions or code contributions. You can fork us on Github.

There are also lots of opportunities to extend PxLoader to handle additional resource types. Video (contributed!) and JSON are a few we'd love to see. Please remember that not just some, but "all your resource are belong to us".

Happy loading!