npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

keydrown

v1.2.8

Published

A JavaScript key state handler for web apps

Downloads

22

Readme

Keydrown

A JavaScript key state handler for web apps

When building games or any application that requires quick reactions from the user, a system to track key states is needed. You might say "Silly developer! There are events for that! They're called keydown and keyup!" This is correct, but the problem that Keydrown solves is more subtle: When you press and hold any key on the keyboard, there is a brief delay between the initial firing of the keydown event handler and the subsequent firings of that event for every tick. Here's an approximate ASCII visualization:

TIME (seconds)           KEYDOWN HANDLER FIRING STATE
-----------------------------------------------------

0                        Firing
0.25                     Not firing
0.50                     Not firing
0.75                     Not firing
1                        Firing
1.25                     Firing
1.50                     Firing
1.75                     Firing
2                        Firing

...And the handler will just keep firing until the button is released. The expectation from the user is that the key handler would be firing for the entire duration of time that the key is held down - the early ticks where the keydown state is not handled creates a feeling of sluggishness and noticeably worsens the User Experience. A way around this delay is to only listen for one keydown event for a button, and execute the key handler on every tick until the corresponding keyup event is detected for that button.

Keydrown makes this super easy.

API

All Keydrown functionality exists under the kd namespace.

Key Objects

Every letter key, as well as some other keys on the keyboard are represented in a map of kd.Key instances with uppercase key names:

kd.A instanceof kd.Key; // true
kd.SPACE instanceof kd.Key; // true
kd.UP instanceof kd.Key; // true

You can see the full list of supported keys in kd.map.js (more key codes can easily be added, please submit a Pull Request if you add more). kd.Key has the following API:

/**
 * @param {function=} opt_handler
 */
kd.Key.prototype.down = function (opt_handler)

opt_handler fires for every tick where the key is held down. There is no early delay, as described in the ASCII graph above. Calling this method for a key again will overwrite the previous opt_handler - only one handler function is allowed per key.

If opt_handler is omitted, this function invokes whatever handler function was previously bound with kd.Key#down.

/**
 * @param {function=} opt_handler
 */
kd.Key.prototype.up = function (opt_handler)

opt_handler fires when the key is released by the user. As with kd.Key#down, only one handler function is allowed. Unlike kd.Key#down, opt_handler does not fire continuously — only once when the key is released.

If opt_handler is omitted, this function invokes whatever handler function was previously bound with kd.Key#up.

/**
 * @param {function=} opt_handler
 */
kd.Key.prototype.press = function (opt_handler)

opt_handler fires once when the key is pressed by the user. Only one handler function is allowed. This is not a repeating state — it only fires once until the user releases the key and presses it again.

If opt_handler is omitted, this function invokes whatever handler function was previously bound with kd.Key#press.

kd.Key.prototype.isDown = function()

Returns true if the key is currently pressed, otherwise returns false.

Example

kd.B.down(function () {
  console.log('The "B" key is being held down!');
});

kd.B.up(function () {
  console.log('The "B" key was released!');
});

kd.SPACE.press(function () {
  console.log('The space bar was pressed!');
});

if (kd.LEFT.isDown()) {
  console.log('The left arrow key is being held down!')
}

down, up, and press functions also provide the raw Keyboard event Object created by the corresponding browser event. The schema of this Object may differ across browsers, particularly older ones.

kd.A.down(function (evt) {
  if (evt.shiftKey) {
    console.log('The shift key is being held down!');
  }

  if (evt.ctrlKey) {
    console.log('The ctrl key is being held down!');
  }
});

kd.Key.prototype.unbindDown = function ()

Unbinds the function handler that was bound with kd.Key#down.

kd.Key.prototype.unbindUp = function ()

Unbinds the function handler that was bound with kd.Key#up.

kd.Key.prototype.unbindPress = function ()

Unbinds the function handler that was bound with kd.Key#press.

Example

kd.B.down(function () {
  console.log('The "B" key is being held down!');
});

// Now pressing the "B" key won't do anything
kd.B.unbindDown();

Helper methods

The kd Object has helper methods attached to it, and they are represented by camelCase property names.

kd.tick = function ()

Check the states of all of the keys and invoke the necessary key handlers. You should call this once and only once somewhere in your run loop. If you don't call tick somewhere in your run loop, Keydrown won't do anything.

/**
 * @param {function} handler
 */
kd.run = function (handler)

A basic run loop. If your application already has a run loop, you don't need this. kd.run uses requestAnimationFrame if it is available, and falls back to a setTimeout loop if it is not.

kd.stop = function ()

Cancels the run loop started by kd.run.

Example

kd.run(function () {
  kd.tick();
});

kd.SPACE.down(function () {
  console.log('The space bar is being held down!');
});

kd.ESC.down(function () {
  console.log('Canceling the loop.');
  kd.stop();
});

Getting the code

If you want to keep things simple, all you need is either dist/keydrown.js or dist/keydrown.min.js from this Git repo. Alternatively, you can install Keydrown via NPM:

$: npm install keydrown

Module compatibility

If loaded directly (without a script loader), Keydrown creates the kd browser global. However, it can also be loaded as an AMD module or as a CommonJS module (through a tool like Webpack).

// Loaded as a CommonJS module with Webpack
var kd = require('keydrown');

kd.run(function () {
  kd.tick();
});
// Loaded with an AMD loader (such as Require.js)
require(['./path/to/keydrown'], function (kd) {
  kd.run(function () {
    kd.tick();
  });
});

Browser compatibility

Keydrown supports all modern browsers, as well as Internet Explorer 7 and up (please see the note below about IE compatibility).

Limitations

Keydrown has a feature where when the user blurs the browser window (for example, switching to another application or tab), the key state is reset and "down" handlers stop firing. On other words, keys aren't considered "down" if the user is not focused on the browser window. This functionality is not supported in IE 7 and 8, as there doesn't seem to be a way to bind to the window's blur event correctly in those browsers. You can assign a function to window.onblur, but that function will only fire once IE regains focus, which is not sufficient for Keydrown's reset-on-blur functionality.

Keydrown in the wild

Keydrown has been used in several interesting projects:

License

Keydrown is distibuted under the MIT license. You are encouraged to use and modify the code to suit your needs, as well as redistribute it.