This project makes starting an interactive 2D Canvas application fast and easy, even for developers who have never used Canvas before. The goal is to let you focus on your application's logic rather than low-level boilerplate code that's the same for every project.
The project includes a stripped-down version of HTML5 Boilerplate and adds some Canvas-specific boilerplate and JavaScript APIs that are useful for any game or interactive application. This framework is particularly useful for side-scrolling or top-down games.
To get started building, open up main.js. There are three functions there which are the backbone of your application:
- update(): Update the objects in your world -- move them, calculate collision, etc.
- draw(): Draw all the objects and layers onto the main canvas.
- setup(): Set up the objects that should populate your world. This runs after images have been pre-loaded but immediately before animation starts.
These functions are called automatically for you. Just fill in the logic! To see your project, open index.html in your browser. By default, it has a keyboard-controlled player who can wander around.
At this point you can dive in and start building right away, explore more features, or dig deeper into the documentation:
- API Overview (below)
- Full API Documentation
- Walk-Through Guides (coming soon!)
- Examples (coming soon!): things you can build easily with this project
- Demo Applications: see what full-scale projects are possible and how intuitive it is to make them
- Feature Examples: see specific features in action and learn how to implement them
Below is an overview of the functionality this project provides. To read the complete documentation for every function and class, view the full API documentation.
The objects provided below are useful representations of a variety of entities often found in interactive environments. Box, Actor, and Player use John Resig's "simple JavaScript inheritance" library, so you can extend them to create new classes with modified functionality.
- Class: Supports OOP-style inheritance.
- Box: A box shape. This is the basic building block for most interactive entities. It has a size, position, orientation, and display, and it supports collision and various events.
- Actor: Actors inherit from Boxes and add sophisticated built-in support for various kinds of movement. They also support mouse-draggability.
- Player: Players inherit from Actors and add support for control via user input (using the keyboard by default).
- Collection: A container to keep track of multiple Boxes. It has various helper methods to easily work with all the Boxes in the Collection, including batch drawing, collision checking, and other operations.
- TileMap: A utility for rapidly initializing and manipulating grids of tiles. This makes it easy to quickly lay out an environment and process the objects in it.
- Sprite, SpriteMap: Manage sprite images for animation and convenient display. These classes are provided by a library by the same author.
- World: The complete playable game area. Contains information about the environment and helpers for controlling the viewport.
- Layer: An intermediate graphics layer (useful for drawing performance). Supports parallax scrolling.
- Timer: A timer for all your timing needs.
The normal canvas drawImage() method is enhanced in order to be able to draw any kind of image while utilizing the image cache for performance. Use it to draw any of the following:
- The file path of an image
- A Sprite or SpriteMap object
- A Layer object
- An HTMLCanvasElement
- An HTMLImageElement (same thing as an Image)
- An HTMLVideoElement
Or, just assign one of these things to the "src" attribute of a Box, Actor, or Player instance to have its draw() method display the image.
A number of events are triggered on the document, on Boxes, and on Actors for various mouse, touch, drag-drop, and game events. You can also add your own custom events.
Objects in a Canvas are not represented in the DOM and so they don't benefit from the traditional JavaScript event model. A similar replacement event system is provided so you don't have to worry about this problem. Specifically, the Box class provides the listen(), once(), and unlisten() methods to bind and unbind event handlers.
-
Keyboard Input: For many use cases, keyboard input is handled automatically via the "keys" object defined in main.js. You can also bind directly to key event combinations using natural descriptions of the keys:
$(selector).keypress('ctrl+a down', function(event) { });
Other ways to handle keyboard input are described in the documentation.
-
Mouse Input: Most mouse input can be handled by listening to mouse events on Box objects or by using the isHovered() instance methods. The mouse coordinates relative to the canvas are also available in Mouse.coords.
-
Storage: App.Storage provides a wrapper for localStorage that allows storing any kind of object (not just strings).
-
Visibility: By default, animation stops when the tab or window loses focus. This reduces CPU impact when the app is not in view (and preserves your sanity if you are developing with the browser open in one window and your editor in another). If you don't want this behavior,
$(window).off(".animFocus");
will disable it. -
Automatic Canvas Resizing: It is easy to make your canvas the size and shape you want by setting various attributes on the <canvas> tag.
-
Scrolling: By default, if the world is bigger than the canvas, the viewport will scroll as the player approaches its edge. You can switch to scrolling the viewport with the mouse with Mouse.Scroll.
-
Caching: Images will be cached on the fly if necessary, or it's easy to pre-load them with the "preloadables" array in main.js. Pre-loading is recommended to avoid images "popping" into view on the canvas as they load. If you need to, you can manipulate the Caches manually.
-
HTML Integration: App.Utils.positionOverCanvas() allows you to position any DOM element at a specific position over the canvas. This allows you to place HTML forms, buttons, labels, or anything else directly onto the canvas.
- Global Variables: Some frequently used variables, like player, canvas, context, and world, are provided globally for ease of reference.
- console.throttle(..., frequency[, logFunction]): Log a message to the JavaScript console no more often than a specified rate. This is useful for logging things in loops since it avoids being overwhelmed by an unstoppable barrage of similar log messages. If you want more helpers like this, check out Steven Wittens' console-extras.js.
- Other Utilities: A number of helper methods are available in App and App.Utils, as well as several custom methods added to the default Array, Number, and CanvasRenderingContext2D classes.
Put your application's primary styles in main.css and responsive styles for different types and sizes of screens in media.css. print.css will kick in automatically when the page is being printed. reset.css normalizes styles across browsers to sensible defaults. utilities.css provides some helpful classes to use in your markup.
These libraries have not necessarily been tested with this project, but should be compatible.
New functionality:
- PathFinding.js: Easily compute efficient paths from one place to another for your AI.
- SoundJS: Manage your audio resources.
- BigScreen: Makes it easy to go full-screen.
- History.js: Handle refreshless URL updates. This can allow storing information in the URL, which could allow e.g. linking directly to in-game content.
- Particle.js A particle emitter (useful for things like fires and waterfalls).
- Gamepad.js Provides support for console game controller input.
- jQuery Mousewheel Provides cross-browser mousewheel support which could be useful for zooming.
Enhanced functionality:
- Tween.js: Helps create smooth animated transitions.
- Box2D: Provides more comprehensive physics support than the mechanics built in to the Actor class.
- PreloadJS: If you need to pre-load any resources other than images, PreloadJS is a good bet (the built-in image caching is fine otherwise).
- Sticky.js: Provides a more thorough alternative to the App.Storage localStorage wrapper.
- Visibility.js: Provides more comprehensive support for determining whether the page is visible to the user than is provided by default. This is useful for controlling how your project behaves while it is in the background.
Before deploying to production, there are a few things you may want to do:
- Set the title and meta description in the document head.
- Replace favicon.ico and apple-touch-icon.png in the root directory.
- Modify robots.txt to fit your site's requirements.
- Create custom error pages (404, 500, etc.) and modify .htaccess to use them (search for "404 page").
- Add the rules in .caching.htaccess into .htaccess and delete .caching.htaccess. These are separated by default to ease development.
To maximize performance, draw complex collections of things onto different Layers that do not need to be updated every frame, and then simply draw the Layer itself onto the main graphics context in the draw() function. You can group elements onto the same Layer if they change with similar frequency. This performance tip is especially true for drawing text, because text renders very slowly (technically, canvas has no glyph cache so the letters have to be re-kerned on every draw). Additionally, for very large worlds, you may want to track things in a TileMap because TileMaps have support for retrieving objects within a certain area. You can use this functionality to quickly process only objects in or near the viewport e.g. for collision, updating, or drawing.
Contributions are welcome!
Officially supported in Firefox 16+, Chrome 22+, IE9+, Safari 5+.
Probably works in Firefox 4+, Chrome 9+, Opera 11+. Might work in certain more advanced mobile browsers.
Isaac Sukin is the author of this project:
I'd love to hear what you make!
Many other people wrote jQuery, classes.js, and parts of jQuery.hotkeys; they are credited in their respective files. Additionally many people contributed to H5BP, from which most of the HTML and CSS, .htaccess, and robots.txt rules originated. Thanks also to JSDuck for providing the framework for the documentation site, and to Atari for the original image used to derive the centipede example sprite.