Skip to content

Commit

Permalink
Backport wams-js repo changes (#79)
Browse files Browse the repository at this point in the history
Co-authored-by: Scott Bateman <[email protected]>
Co-authored-by: Michael van der Kamp <[email protected]>
  • Loading branch information
3 people authored Sep 23, 2023
1 parent f277add commit 6394648
Show file tree
Hide file tree
Showing 23 changed files with 903 additions and 16 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 wams-js

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
24 changes: 8 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# WAMS: Workspaces Across Multiple Surfaces

[![Maintainability](https://api.codeclimate.com/v1/badges/025f89d6de0c6677d142/maintainability)](https://codeclimate.com/github/hcilab/wams/maintainability)
[![Maintainability](https://api.codeclimate.com/v1/badges/025f89d6de0c6677d142/maintainability)](https://codeclimate.com/github/wams-js/wams/maintainability)

WAMS is a Web API that makes creating Multi-Screen applications easy. Multi-screen applications are ones where multiple devices (and their screens) can be used together in flexible ways allowing objects to be easily moved between screens or interactions, like gestures, to span multiple screens.

Expand Down Expand Up @@ -45,12 +45,12 @@ You will need to install [node.js and npm](https://docs.npmjs.com/downloading-an

Then you can install this repo directly as a node module. For example, to install the stable `hello-world-test` release:
```bash
npm install hcilab/wams#hello-world-test
npm install wams-js/wams#hello-world-test
```

## Getting started

The easiest way to get started is to follow the [Walkthrough](#walkthrough) tutorial below. More advanced users might want to check the [code documentation](https://hcilab.github.io/wams/) and the [examples](#examples). ~For a taste on how WAMS works, check the [live demo section](#live-demo).~ (The live demo is currently broken).
The easiest way to get started is to follow the [Walkthrough](#walkthrough) tutorial below. More advanced users might want to check the [code documentation](https://wams-js.github.io/wams/) and the [examples](#examples). ~For a taste on how WAMS works, check the [live demo section](#live-demo).~ (The live demo is currently broken).

## Examples

Expand All @@ -66,17 +66,9 @@ For example:
node examples/polygons.js
```

## Live Demo

* (Currently broken)

The [live demo](https://wams-player-demo.herokuapp.com/) is an example of a video-player with a distributed user interface. First, the player controls are displayed on the screen with the video. Go to the url with a second device or browser, and as a second view is connected, the controls are automatically moved to that view.

To check out the code of the live demo, see `examples/video-player.js`

## Walkthrough

This walkthrough is a friendly guide on how to use most WAMS features. For more details, see [code documentation](https://hcilab.github.io/wams/).
This walkthrough is a friendly guide on how to use most WAMS features. For more details, see [code documentation](https://wams-js.github.io/wams/).

> **Note** The examples on this page use ES2015 (ES6) JavaScript syntax like `const` variables and object destructuring. If you are not familiar with ES2015 features, you can [read](https://webapplog.com/es6/) about them first.
Expand All @@ -87,7 +79,7 @@ First, let's set up a new directory for our demo application, and install WAMS i
```bash
mkdir demo
cd demo
npm install hcilab/wams#hello-world-test
npm install wams-js/wams#hello-world-test
```

Now, create an **app.js** file. In this file, include WAMS and initialize the application:
Expand Down Expand Up @@ -194,7 +186,7 @@ You can substitute `const app = new Wams.Application();` in your code with the c

### Basics

A WAMS app is made of **items**. There are several predefined items (see in the [code documentation](https://hcilab.github.io/wams/module-predefined.items.html)):
A WAMS app is made of **items**. There are several predefined items (see in the [code documentation](https://wams-js.github.io/wams/module-predefined.items.html)):

- `rectangle`
- `square`
Expand Down Expand Up @@ -231,7 +223,7 @@ app.spawn(
);
```

Polygons are built using an array of relative points. For a random set of points, you can use `randomPoints` method from `Wams.predefined.utilities` (see in [code documentation](https://hcilab.github.io/wams/module-predefined.utilities.html#.randomPoints)).
Polygons are built using an array of relative points. For a random set of points, you can use `randomPoints` method from `Wams.predefined.utilities` (see in [code documentation](https://wams-js.github.io/wams/module-predefined.utilities.html#.randomPoints)).

For example:

Expand Down Expand Up @@ -625,7 +617,7 @@ function flipCard(event) {

### Grouped items

Sometimes you would like to spawn several items and then move or drag them together. To do that easily, you can use the `createItemGroup` method (see in the [code documentation](https://hcilab.github.io/wams/module-server.Application.html#createItemGroup)):
Sometimes you would like to spawn several items and then move or drag them together. To do that easily, you can use the `createItemGroup` method (see in the [code documentation](https://wams-js.github.io/wams/module-server.Application.html#createItemGroup)):

```javascript
const items = [];
Expand Down
271 changes: 271 additions & 0 deletions examples/chess-1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
'use strict';
const WAMS = require('..');
const path = require('path');
const app = new WAMS.Application({
clientScripts: ['custom-events.js'],
});
app.addStaticDirectory(path.join(__dirname, './client'));
const rectangle = WAMS.predefined.items.rectangle;
const image = WAMS.predefined.items.image;
const { square } = WAMS.predefined.items;
const { polygon } = WAMS.predefined.items;
const points = [
{ x: 0, y: 0 },
{ x: 21, y: 19 },
{ x: 11, y: 19 },
{ x: 16, y: 30 },
{ x: 12, y: 31 },
{ x: 7, y: 19 },
{ x: 0, y: 25 },
{ x: 0, y: 0 },
];
const teleColors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#00ffff', '#ff00fff'];
let numOfTeles = 0;
let selected = null;
let prevX, prevY;

// app globals
let appCreated = false;
let teleMap = new Map();

//------------------------------------------------------
// classes
//------------------------------------------------------

class Piece {
constructor(filename, size, row, col, rotated) {
this.row = row;
this.col = col;
this.wamsObject = app.spawn(
image(filename, {
width: size,
height: size,
x: col * size,
y: row * size,
})
);
this.wamsObject.on('drag', WAMS.predefined.actions.drag);

if (rotated) {
this.wamsObject.rotateBy(Math.PI, this.wamsObject.x + size / 2, this.wamsObject.y + size / 2);
}
}
}

class Board {
constructor() {
this.pieces = [];
this.wamsToPieceMap = new Map();
this.positions = [];
// [null, null, null, null, null, null, null, null],
// [null, null, null, null, null, null, null, null],
// [null, null, null, null, null, null, null, null],
// [null, null, null, null, null, null, null, null],
// [null, null, null, null, null, null, null, null],
// [null, null, null, null, null, null, null, null],
// [null, null, null, null, null, null, null, null],
// [null, null, null, null, null, null, null, null]];
for (let i = 0; i < 8; i++) {
this.positions.push([null, null, null, null, null, null, null, null]);
}
this.size = 1000 / 8;
this.wamsObject = app.spawn(
image('board.png', {
width: 1000,
height: 1000,
x: 0,
y: 0,
})
);
}

createPiece(filename, row, col, rotated) {
let piece = new Piece(filename, this.size, row, col, rotated);
this.pieces.push(piece);
this.wamsToPieceMap.set(piece.wamsObject, piece);
this.positions[row][col] = piece;
}

createPieces() {
this.createPiece('wr.png', 7, 0, false);
this.createPiece('wr.png', 7, 7, false);
this.createPiece('wkt.png', 7, 1, false);
this.createPiece('wkt.png', 7, 6, false);
this.createPiece('wb.png', 7, 2, false);
this.createPiece('wb.png', 7, 5, false);
this.createPiece('wq.png', 7, 3, false);
this.createPiece('wk.png', 7, 4, false);
for (let i = 0; i < 8; i++) {
this.createPiece('wp.png', 6, i, false);
}

this.createPiece('br.png', 0, 0, true);
this.createPiece('br.png', 0, 7, true);
this.createPiece('bkt.png', 0, 1, true);
this.createPiece('bkt.png', 0, 6, true);
this.createPiece('bb.png', 0, 2, true);
this.createPiece('bb.png', 0, 5, true);
this.createPiece('bq.png', 0, 3, true);
this.createPiece('bk.png', 0, 4, true);
for (let i = 0; i < 8; i++) {
this.createPiece('bp.png', 1, i, true);
}
}

movePiece(wamsPiece) {
// find the associated piece
let piece = this.wamsToPieceMap.get(wamsPiece);
// find new location
let newRow = Math.floor((wamsPiece.y + wamsPiece.height / 2) / this.size);
let newCol = Math.floor((wamsPiece.x + wamsPiece.width / 2) / this.size);
// snap piece to location
// wamsPiece.x = newCol * this.size;
// wamsPiece.y = newRow * this.size;
console.log('snapping');
wamsPiece.moveTo(newCol * this.size, newRow * this.size);
// remove piece from old location
console.log(piece.row + ',' + piece.col);
this.positions[piece.row][piece.col] = null;
// move piece to new location
piece.row = newRow;
piece.col = newCol;
this.positions[newRow][newCol] = piece;
//console.log(piece);
}
}

// function movePiece(piece, event) {
// selected = piece;
// }

//------------------------------------------------------
// WAMS functions
//------------------------------------------------------

let numberConnected = 0;
let board;

function handleConnect({ view, device }) {
// view.on('click', createBox);
console.log('connecting view id: ' + view.id);
numberConnected++;
console.log('Number connected:' + numberConnected);
if (numberConnected == 1) {
// I'm first, create the board and pieces
board = new Board();
board.createPieces();
} else {
// rotate board 180
view.rotateBy(Math.PI, 500, 500);
}
// size my view to show the whole board
view.scale = Math.min(view.width / 1000, view.height / 1000);
}

// function createBox(event) {
// const box = app.spawn(square(100, "green", {
// x: event.x,
// y: event.y,
// })
// );
// box.on('drag', handleBoxDrag);
// }

// function handleBoxDrag(event) {
// let dX = event.x - prevX;
// let dY = event.y - prevY;
// prevX = event.x;
// prevY = event.y;
// event.target.moveBy(dX,dY);
// }

//------------------------------------------------------
// Handle custom events
//------------------------------------------------------

app.on('mousedown', (event) => {
const { view } = event;
// custom event gives us canvas coords; need to convert to WAMS coords
// let wX = event.x / view.scale + view.x;
// let wY = event.y / view.scale + view.y;
let wX = event.x / view.scale;
let wY = event.y / view.scale;
console.log(view.rotation);
if (view.rotation != 0) {
//wY = app.workspace.height - wY;
//wX = app.workspace.width - wX;
wY = 1000 - wY;
wX = 1000 - wX;
}
console.log(event.x + ',' + event.y + ' ' + wX + ',' + wY);
let item = app.workspace.findItemByCoordinates(wX, wY);
//console.log(item);
if (item) {
selected = item;
}
//console.log(item);
// if (item) {
// prevX = wX;
// prevY = wY;
// selected = item;
// }
});

app.on('mousemove', (event) => {
const { view } = event;
// let tele;
// if (selected != null) {
// let dX = event.x - prevX;
// let dY = event.y - prevY;
// prevX = event.x;
// prevY = event.y;
// selected.moveBy(dX,dY);
// }
// if (teleMap.has(event.id)) {
// tele = teleMap.get(event.id);
// tele.moveTo(event.x, event.y);
// } else {
// // create tele
// let tele = app.spawn(createTelepointer(event.x, event.y, numOfTeles));
// teleMap.set(event.id, tele);
// }
});

// function createTelepointer(x, y) {
// return WAMS.predefined.items.polygon(
// points,
// teleColors[numOfTeles++],
// {
// x: x,
// y: y,
// type: 'colour',
// onclick: findBelow,
// }
// );
// }

// function findBelow(event) {
// console.log("findBelow");
// }

app.on('mouseup', (event) => {
const { view } = event;
console.log(selected);
if (selected != null) {
console.log('mouseup on piece: ' + selected);
board.movePiece(selected);
selected = null;
}
});

app.on('keydown', (event) => {
const { view } = event;
console.log('keydown');
});

//------------------------------------------------------
// Start WAMS app
//------------------------------------------------------

app.on('connect', handleConnect);
app.listen(3500);
Binary file added examples/client/Chess_bdt60.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/client/Chess_blt60.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 6394648

Please sign in to comment.