• Stars
    star
    206
  • Rank 190,504 (Top 4 %)
  • Language
    JavaScript
  • Created over 11 years ago
  • Updated about 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A JavaScript key state handler for web apps

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.

More Repositories

1

shifty

The fastest TypeScript animation engine on the web
TypeScript
1,509
star
2

chitchatter

Secure peer-to-peer chat that is serverless, decentralized, and ephemeral
TypeScript
1,292
star
3

rekapi

A keyframe animation library for JavaScript
JavaScript
641
star
4

stylie

A graphical CSS3 animation tool
JavaScript
526
star
5

mantra

A professional web animation tool for everyone
JavaScript
181
star
6

lib-tmpl

A JavaScript library template.
JavaScript
125
star
7

farmhand

A resource management game that puts a farm in your hand
JavaScript
100
star
8

kapi

A keyframe API for the HTML5 Canvas.
JavaScript
62
star
9

dotfiles

This is what I use to get things done!
Vim Script
57
star
10

dragon

Another fn.draggable plugin for jQuery.
JavaScript
49
star
11

merkaba

An SVG editor component written in React
JavaScript
21
star
12

rekapi-timeline

A visual tool for modifying Rekapi animations
JavaScript
21
star
13

secure-file-transfer

A library to encrypt and transfer files P2P in the browser
TypeScript
19
star
14

vim-docker-env

A bare Vim environment, plus Pathogen, powered by Docker
Vim Script
15
star
15

rekapi-controls

Graphical controls for Rekapi animations.
JavaScript
10
star
16

props-editor

A UI for modifying React component props
JavaScript
8
star
17

misfit

A CLI UI for working with npm
JavaScript
8
star
18

Infinitely-Draggable-Content

Drag stuff around! For forever and ever!
JavaScript
8
star
19

js-project-starter

My personal starting point for JavaScript projects
JavaScript
6
star
20

Cachey

A caching plugin for jQuery
JavaScript
6
star
21

requirejs-lazy-load-example

An example of a lazy-loaded web app powered by RequireJS with a build process
JavaScript
6
star
22

require-and-backbone-views

An example of using Require.js and Backbone Views.
JavaScript
6
star
23

cubelet

A jQuery widget for graphically rotating a cube and working with its coordinates
JavaScript
5
star
24

tools

Some handy development tools
Vim Script
5
star
25

bezierizer

A graphical widget for defining a Bezier curve
JavaScript
4
star
26

storytime-with-github

Tell a story!
3
star
27

spinneroo

Take the web for a spin!
JavaScript
3
star
28

keyhandler_demo

A demonstration for a simple key handler in JavaScript
JavaScript
3
star
29

node-cli-boilerplate

Minimal, practical boilerplate for writing Node-powered CLI tools
JavaScript
3
star
30

rekapi-export-test

A test harness for experimenting with Rekapi exportTimeline data
JavaScript
3
star
31

tweetree

A fun project that lets you view random Twitter tweets in a visual tree.
JavaScript
3
star
32

jambi

A game development platform
2
star
33

transfornimate

A CSS transform animation tool
JavaScript
2
star
34

jumpjump

A game prototype for an idea I have.
JavaScript
2
star
35

fun-animal-names

Hash strings into fun animal names
TypeScript
2
star
36

jeremyckahn.com

My personal site.
CSS
2
star
37

wipe

An old jQuery plugin I made to make blur/wipe transitions
JavaScript
2
star
38

dumbdiff

It's a dumb, but fast and simple string differ for JavaScript.
JavaScript
2
star
39

hackday

We are hacking.
2
star
40

shifty-actors

A bridge library for Tweeny and Kapi actors.
JavaScript
2
star
41

jquery-canvas-kit

An old project, just throwing it on here because why not.
JavaScript
2
star
42

doodles

Sometimes I make art with code for fun.
JavaScript
2
star
43

farmhand-shuffle

A card game for farmers
TypeScript
2
star
44

jeremyckahn

It's a-me! jeremyckahn!
1
star
45

wrecked

An HTML5 game about rectangles. Hopefully it will be fun someday!
JavaScript
1
star
46

generator-web-project

This is the generator I use to start web projects.
JavaScript
1
star
47

trystero-node-sandbox

Sandbox repo for https://github.com/dmotz/trystero/issues/24
TypeScript
1
star
48

hackapi

Rekapi Art!
JavaScript
1
star
49

rekapi-benchmark

A simple performance benchmark for Rekapi, Underscore and Lo-Dash
JavaScript
1
star
50

rekapi-getting-started-demo

A runnable set of files for a Rekapi "Hello World"
1
star
51

vertigo

A jQuery plugin that makes a 3D UI for presenting content
JavaScript
1
star
52

petriEvolution

An old Processing project of mine.
Java
1
star
53

suggest-o-tron

An app that makes event suggestions for you
Ruby
1
star
54

rekapi-ios

An iOS-inspired Rekapi animation
JavaScript
1
star
55

3d-cards

A UI experiment with cards in 3D space
JavaScript
1
star
56

workflow-dispatch-test

A repo for experimenting with GitHub Actions
1
star
57

react-starter

My starting point for React apps
JavaScript
1
star
58

pwa-demo

TypeScript
1
star
59

jck-library-extensions

A set of extensions for open source libraries
JavaScript
1
star
60

iframe-test

HTML
1
star
61

jquerycanvaskit

Automatically exported from code.google.com/p/jquerycanvaskit
JavaScript
1
star