Skip to content
This repository was archived by the owner on Aug 18, 2025. It is now read-only.

Commit 784b68e

Browse files
committed
clean commit
0 parents  commit 784b68e

File tree

632 files changed

+563738
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

632 files changed

+563738
-0
lines changed

.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# OS X
2+
.DS_Store*
3+
Icon?
4+
._*
5+
6+
# Windows
7+
Thumbs.db
8+
ehthumbs.db
9+
Desktop.ini
10+
11+
# Linux
12+
.directory
13+
*~
14+
15+
# npm
16+
node_modules
17+
*.log
18+
*.gz
19+
20+
index.js

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
![img](https://github.com/googlecreativelab/anypixel/blob/master/header.png)
2+
3+
[AnyPixel.js](http://googlecreativelab.github.io/anypixel) is an open-source software and hardware library that makes it possible to use the web to create big, unusual, interactive displays. Anyone can fork the code and the schematics to create their own display at any scale.
4+
5+
The first display using this platform is in the 8th Avenue lobby at the Google NYC office. To create this installation, we used 5880 off-the-shelf arcade buttons with LEDs inside them as our pixels. AnyPixel.js’ straightforward hardware/software framework makes it easy to build any display where each pixel is an interactive element.
6+
7+
![buttonwall](https://github.com/googlecreativelab/anypixel/blob/master/buttonwall.jpg)
8+
9+
## What You'll Find
10+
- **/hardware**- EAGLE schematics, board layouts, CAD files, wiring diagrams, and blueprints
11+
- **/firmware** - microcontroller code, written for the STM32 family of devices
12+
- **/backend** - node.js and chrome applications for communicating with the hardware.
13+
- **/frontend** - the app framework, an in-browser previewer, and 12 example apps written by Googlers and friends worldwide.
14+
15+
## Getting Started
16+
17+
### Check out the examples
18+
We've included 12 example apps written by Googlers and friends for the 8th Avenue lobby display in NYC. To check them out, install the [previewer](https://github.com/googlecreativelab/anypixel/tree/master/frontend/previewer) and run one of the [examples](https://github.com/googlecreativelab/anypixel/tree/master/frontend/examples).
19+
20+
### Build your own app
21+
Building your own app is easy with the Anypixel framework. To get started, check out the [framework documentation](https://github.com/googlecreativelab/anypixel/tree/master/frontend/framework) and the [example app](https://github.com/googlecreativelab/anypixel/tree/master/frontend/examples/getting-started):
22+
23+
```
24+
var anypixel = require('anypixel');
25+
var ctx = anypixel.canvas.getContext2D();
26+
27+
var colors = ['#F00', '#0F0', '#00F'];
28+
29+
/**
30+
* * Listen for onButtonDown events and draw a 2x2 rectangle at the event site
31+
*/
32+
document.addEventListener('onButtonDown', function(event) {
33+
ctx.fillStyle = colors[Math.floor(Math.random() * 3)];
34+
ctx.fillRect(event.detail.x - 1, event.detail.y - 1, 2, 2);
35+
});
36+
```

backend/.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
node_modules
2+
temp
3+
.tmp
4+
dist
5+
.sass-cache
6+
.map
7+
bower_components
8+
package
9+
.DS_Store
10+
index.js

backend/README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# AnyPixel - Backend
2+
The AnyPixel backend consists of four applications which work together to provide an interface
3+
between the javascript-driven AnyPixel apps (the [_frontend_](https://github.com/googlecreativelab/anypixel/tree/master/frontend)) and the physical display
4+
[hardware](https://github.com/googlecreativelab/anypixel/tree/master/hardware).
5+
6+
- **AppServer** - A node.js server which locally hosts the AnyPixel apps.
7+
8+
- **ChromeBridge** - A Chrome app which displays AnyPixel apps and handles the communication between the AppServer apps and the physical display hardware.
9+
10+
- **UdpManager** - A node.js app which distributes data packets from ChromeBridge to the individual hardware components.
11+
12+
- **Emulator** - A Chrome app for debugging, which simulates the network communications
13+
between ChromeBridge and the physical display hardware.
14+
15+
![img](https://github.com/googlecreativelab/anypixel/blob/master/backend/flow.png)
16+
17+
## Installation & Startup
18+
_These instructions assume a basic familiarity with the command line of your particular system.
19+
For a good introduction to the command line, check out
20+
[The Command Line Crash Course](http://cli.learncodethehardway.org/book/)._
21+
22+
### Getting Started
23+
1. **Download and install [node.js](https://nodejs.org/en/).**
24+
25+
2. **Install [browserify](http://browserify.org/)** - `$ npm install -g browserify`
26+
27+
---------
28+
29+
### AppServer
30+
1. **Install node components** - In the /appserver directory, do: `$ npm install`
31+
32+
2. **Start the server** - In the /appserver directory, do `$ npm start`
33+
34+
To stop the server, do `$ npm stop`
35+
36+
_For more info on adding your own apps to the AppServer, see the [AppServer README](https://github.com/googlecreativelab/anypixel/tree/master/backend/appserver)._
37+
38+
---------
39+
40+
### UdpManager
41+
1. **Install node components** - In the /udp-manager directory, do: `$npm install`
42+
43+
2. **Start the manager** - In the /udp-manager directory, do `$ npm start`
44+
45+
To stop the manager, do `$ npm stop`
46+
47+
---------
48+
49+
### Emulator
50+
1. **Install node components** - In the /emulator directory, do: `$npm install`
51+
52+
2. **Install and launch the Chrome app** - Follow the ChromeBridge installation instructions above,
53+
except when loading the extension, select the **/emulator** folder instead.
54+
55+
---------
56+
57+
### ChromeBridge
58+
1. **Install node components** - In the /chromebridge directory, do: `$ npm install`
59+
60+
2. **Open the Chrome Extensions page** - In the Chrome browser, navigate to `chrome://extensions`
61+
62+
3. **Enable Developer mode:**
63+
![img](https://github.com/googlecreativelab/anypixel/blob/master/backend/extension.png)
64+
65+
4. **Load the extension** - Click the "Load unpacked extension..." button and select the
66+
/chromebridge folder. The ChromeBridge app will be added to the top of the extensions list.
67+
68+
4. **Ensure the AppServer and the Emulator are running** - or plug in your physical display hardware.
69+
70+
5. **Launch the app** - click the "Launch" button under the extension title:
71+
![img](https://github.com/googlecreativelab/anypixel/blob/master/backend/launch.png)
72+
73+
_For more info on using the ChromeBridge app, see the [ChromeBridge README](https://github.com/googlecreativelab/anypixel/tree/master/backend/chromebridge)_.

backend/appserver/README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Backend - AppServer
2+
AppServer is a node.js app which runs Anypixel apps from an [Express](http://expressjs.com/) server. This is what holds the canvas that your Anypixel app will draw on. Each frame it will send the pixel data from this canvas to ChromeBridge, where it will be sent on to the physical display itself. It also provides a RESTful API for changing the current app and for listing the available apps.
3+
4+
![img](https://github.com/googlecreativelab/anypixel/blob/master/backend/appserver/flow.png)
5+
6+
## Getting Started
7+
8+
1. **Install node components** - `$ npm install`
9+
10+
2. **Start the server** - `$ npm start`
11+
12+
To stop the server, do `$ npm stop` <br />
13+
14+
**To add your own apps:** <br />
15+
Copy your app folder into `/public/apps` and make sure you have an index.js file in your root app directory.
16+
17+
## API
18+
19+
### Get App
20+
Renders an HTML page containing the requested app.
21+
22+
* **URL:** <br />
23+
/app/:app_name
24+
25+
* **Method:** <br />
26+
`GET`
27+
28+
* **URL Parameters:** <br />
29+
`app_name=[string]`
30+
31+
* **Success Response:**
32+
* **Code:** 200 <br />
33+
**Content:** Rendered EJS template HTML containing the requested app.
34+
35+
* **Error Response:**
36+
* **Code:** 404 <br />
37+
**Content:** `Invalid app name`
38+
39+
### Get Available Apps
40+
Returns an array of the valid app names and directories
41+
42+
* **URL:** <br />
43+
/api/apps
44+
45+
* **Method:** <br />
46+
`GET`
47+
48+
* **URL Parameters:** <br />
49+
None
50+
51+
* **Success Response:**
52+
* **Code:** 200 <br />
53+
**Content:** <br />
54+
```
55+
{
56+
success: true,
57+
apps: [
58+
{
59+
name: "My App",
60+
path: "myApp"
61+
}
62+
]
63+
}
64+
```
65+
66+
* **Error Response:** <br />
67+
None

backend/appserver/appserver.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
Copyright 2016 Google Inc. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
var path = require('path');
18+
var http = require('http');
19+
var fs = require('fs');
20+
var express = require('express');
21+
var bodyParser = require('body-parser');
22+
var app = express();
23+
24+
/**
25+
* An Express server which hosts the current Anypixel app and provides a RESTful api with functions
26+
* for changing the current app and getting a list of all available apps.
27+
*/
28+
29+
// Express config
30+
app.set('views', path.join(__dirname, 'views'));
31+
app.set('view engine', 'ejs');
32+
app.use(bodyParser.json());
33+
app.use(bodyParser.urlencoded({extended: true}));
34+
app.use(express.static(path.join(__dirname, 'public')));
35+
app.use(function(req, res, next) {
36+
res.header("Access-Control-Allow-Origin", "*");
37+
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
38+
next();
39+
});
40+
41+
// Start the server on port 8000
42+
var server = http.createServer(app).listen(8000, function() {
43+
console.log('AnyPixel AppServer | Listening on port ' + server.address().port);
44+
});
45+
46+
47+
/**
48+
* Serves a requested app with a given app_name
49+
*/
50+
app.get('/app/:app_name', function(req, res) {
51+
// Check if app exists
52+
var dir_name = req.params.app_name;
53+
var filename = path.join(__dirname, 'public', 'apps', dir_name, 'index.js');
54+
if (!fs.existsSync(filename)) {
55+
console.log('Invalid app name: ' + dir_name);
56+
return res.status(404).send('Invalid app name');
57+
}
58+
59+
console.log('Serving: ' + req.params.app_name);
60+
61+
// Render
62+
res.render('app', {
63+
layout: false,
64+
app: {
65+
name: req.params.app_name,
66+
base: '/apps/' + dir_name + '/',
67+
path: 'index.js'
68+
}
69+
});
70+
});
71+
72+
/**
73+
* Returns an alphabetical list of all valid apps in the /public/apps directory
74+
* Valid apps must contain a package.json file with the display_name parameter set.
75+
*/
76+
app.get('/api/apps', function(req, res) {
77+
// List all available apps
78+
var apps_root_path = path.join(__dirname, 'public', 'apps');
79+
80+
fs.readdir(apps_root_path, function(err, dirs) {
81+
82+
// Filter out system directories (/.git, for example)
83+
dirs = dirs.filter(function(val) {
84+
return !(val.substr(0, 1) == '.');
85+
});
86+
87+
// For each directory, get the app name from the package.json file
88+
var apps = [];
89+
dirs.forEach(function(dir) {
90+
var package_json_path = path.join(apps_root_path, dir, 'package.json');
91+
try {
92+
var app_desc = JSON.parse(fs.readFileSync(package_json_path, 'utf8'));
93+
apps.push({
94+
name: app_desc.display_name,
95+
path: dir
96+
});
97+
} catch(e) {}
98+
});
99+
100+
// Sort alphabetically
101+
apps = apps.sort(function(a, b) {
102+
if (a.name < b.name) return -1;
103+
if (a.name > b.name) return 1;
104+
return 0;
105+
});
106+
107+
// Return success
108+
res.json({
109+
success: true,
110+
apps: apps
111+
});
112+
});
113+
});

backend/appserver/flow.png

7.04 KB
Loading

backend/appserver/package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "anypixel-app-server",
3+
"description": "Application that hosts and serves AnyPixel apps",
4+
"version": "1.0.0",
5+
"private": true,
6+
"scripts": {
7+
"preinstall": "npm install -g forever",
8+
"postinstall": "npm run build",
9+
"build": "browserify -d src/app-runner.js > public/js/index.js",
10+
"start": "forever start --minUptime 1000 --spinSleepTime 1000 appserver.js",
11+
"stop": "forever stop appserver.js"
12+
},
13+
"dependencies": {
14+
"body-parser": "1.14.x",
15+
"ejs": "2.3.x",
16+
"express": "4.13.x"
17+
}
18+
}

0 commit comments

Comments
 (0)