Compare commits
No commits in common. "34050291a87e3e4524b5309e66b7d9d7aef767a8" and "8555e3f9e2d6d435eeb2d3078fad6f9accca4a43" have entirely different histories.
34050291a8
...
8555e3f9e2
16
README.md
16
README.md
|
@ -1,16 +0,0 @@
|
||||||
# HTML Canvas with WebSocket
|
|
||||||
|
|
||||||
## About
|
|
||||||
|
|
||||||
This is a demo app that allows you to draw on an HTML canvas. Everythng that gets drawn will be
|
|
||||||
transmitted to a server using websocket and displayed by a receiver app.
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
This app needs Node.js and npm to build and run.
|
|
||||||
|
|
||||||
## Running the app
|
|
||||||
|
|
||||||
Open the command line in the project directory and run ```npm run launch```
|
|
||||||
|
|
||||||
Then open your browser and navigate to http://localhost:8080.
|
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#canvas {
|
#canvas {
|
||||||
width: 100%;
|
width: 500px;
|
||||||
height: 800px;
|
height: 500px;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
"watch": "tsc -watch -p ./",
|
"watch": "tsc -watch -p ./",
|
||||||
"serve": "serve -l 8080 .",
|
"serve": "serve -l 8080 .",
|
||||||
"debug": "npm-run-all --parallel watch serve",
|
"debug": "npm-run-all --parallel watch serve",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
"run-server": "cd server && npm run launch",
|
|
||||||
"launch": "npm-run-all --parallel run-server build serve"
|
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#canvas {
|
#canvas {
|
||||||
width: 100%;
|
width: 500px;
|
||||||
height: 800px;
|
height: 500px;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
dist/
|
|
||||||
|
|
||||||
node_modules/
|
|
||||||
.node_modules/
|
|
||||||
built/*
|
|
||||||
tests/cases/rwc/*
|
|
||||||
tests/cases/test262/*
|
|
||||||
tests/cases/perf/*
|
|
||||||
!tests/cases/webharness/compilerToString.js
|
|
||||||
test-args.txt
|
|
||||||
~*.docx
|
|
||||||
\#*\#
|
|
||||||
.\#*
|
|
||||||
tests/baselines/local/*
|
|
||||||
tests/baselines/local.old/*
|
|
||||||
tests/services/baselines/local/*
|
|
||||||
tests/baselines/prototyping/local/*
|
|
||||||
tests/baselines/rwc/*
|
|
||||||
tests/baselines/test262/*
|
|
||||||
tests/baselines/reference/projectOutput/*
|
|
||||||
tests/baselines/local/projectOutput/*
|
|
||||||
tests/baselines/reference/testresults.tap
|
|
||||||
tests/services/baselines/prototyping/local/*
|
|
||||||
tests/services/browser/typescriptServices.js
|
|
||||||
src/harness/*.js
|
|
||||||
src/compiler/diagnosticInformationMap.generated.ts
|
|
||||||
src/compiler/diagnosticMessages.generated.json
|
|
||||||
src/parser/diagnosticInformationMap.generated.ts
|
|
||||||
src/parser/diagnosticMessages.generated.json
|
|
||||||
rwc-report.html
|
|
||||||
*.swp
|
|
||||||
build.json
|
|
||||||
*.actual
|
|
||||||
tests/webTestServer.js
|
|
||||||
tests/webTestServer.js.map
|
|
||||||
tests/webhost/*.d.ts
|
|
||||||
tests/webhost/webtsc.js
|
|
||||||
tests/cases/**/*.js
|
|
||||||
!tests/cases/docker/*.js/
|
|
||||||
tests/cases/**/*.js.map
|
|
||||||
*.config
|
|
||||||
scripts/eslint/built/
|
|
||||||
scripts/debug.bat
|
|
||||||
scripts/run.bat
|
|
||||||
scripts/word2md.js
|
|
||||||
scripts/buildProtocol.js
|
|
||||||
scripts/ior.js
|
|
||||||
scripts/authors.js
|
|
||||||
scripts/configurePrerelease.js
|
|
||||||
scripts/configureLanguageServiceBuild.js
|
|
||||||
scripts/open-user-pr.js
|
|
||||||
scripts/open-cherry-pick-pr.js
|
|
||||||
scripts/processDiagnosticMessages.d.ts
|
|
||||||
scripts/processDiagnosticMessages.js
|
|
||||||
scripts/produceLKG.js
|
|
||||||
scripts/importDefinitelyTypedTests/importDefinitelyTypedTests.js
|
|
||||||
scripts/generateLocalizedDiagnosticMessages.js
|
|
||||||
scripts/request-pr-review.js
|
|
||||||
scripts/*.js.map
|
|
||||||
scripts/typings/
|
|
||||||
coverage/
|
|
||||||
internal/
|
|
||||||
**/.DS_Store
|
|
||||||
.settings
|
|
||||||
**/.vs
|
|
||||||
**/.vscode/*
|
|
||||||
!**/.vscode/tasks.json
|
|
||||||
!**/.vscode/settings.template.json
|
|
||||||
!**/.vscode/launch.template.json
|
|
||||||
!**/.vscode/extensions.json
|
|
||||||
!tests/cases/projects/projectOption/**/node_modules
|
|
||||||
!tests/cases/projects/NodeModulesSearch/**/*
|
|
||||||
!tests/baselines/reference/project/nodeModules*/**/*
|
|
||||||
.idea
|
|
||||||
yarn.lock
|
|
||||||
yarn-error.log
|
|
||||||
.parallelperf.*
|
|
||||||
tests/cases/user/*/package-lock.json
|
|
||||||
tests/cases/user/*/node_modules/
|
|
||||||
tests/cases/user/*/**/*.js
|
|
||||||
tests/cases/user/*/**/*.js.map
|
|
||||||
tests/cases/user/*/**/*.d.ts
|
|
||||||
!tests/cases/user/zone.js/
|
|
||||||
!tests/cases/user/bignumber.js/
|
|
||||||
!tests/cases/user/discord.js/
|
|
||||||
tests/baselines/reference/dt
|
|
||||||
.failed-tests
|
|
||||||
TEST-results.xml
|
|
||||||
package-lock.json
|
|
||||||
tests/cases/user/npm/npm
|
|
||||||
tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter
|
|
||||||
tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter
|
|
||||||
tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter
|
|
||||||
tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter
|
|
||||||
tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter
|
|
||||||
tests/cases/user/create-react-app/create-react-app
|
|
||||||
tests/cases/user/fp-ts/fp-ts
|
|
||||||
tests/cases/user/webpack/webpack
|
|
||||||
tests/cases/user/puppeteer/puppeteer
|
|
||||||
tests/cases/user/axios-src/axios-src
|
|
||||||
tests/cases/user/prettier/prettier
|
|
||||||
.eslintcache
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"scripts": {
|
|
||||||
"build": "npm install && tsc -p ./",
|
|
||||||
"start": "node dist/app.js",
|
|
||||||
"launch": "npm-run-all build start"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@tsconfig/node16": "^1.0.2",
|
|
||||||
"@types/node": "^16.7.1",
|
|
||||||
"@types/ws": "^7.4.7",
|
|
||||||
"npm-run-all": "^4.1.5",
|
|
||||||
"typescript": "^4.3.5"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ws": "^8.2.0"
|
|
||||||
}
|
|
||||||
}
|
|
102
server/ts/app.ts
102
server/ts/app.ts
|
@ -1,102 +0,0 @@
|
||||||
import WebSocket from 'ws';
|
|
||||||
import Coordinates from './coordinates';
|
|
||||||
|
|
||||||
const wss = new WebSocket.Server({ port: 8081 });
|
|
||||||
const receivers: WebSocket[] = [];
|
|
||||||
let sender: WebSocket | null = null;
|
|
||||||
|
|
||||||
const paths = [] as Coordinates[][];
|
|
||||||
|
|
||||||
let currentPath = [] as Coordinates[];
|
|
||||||
|
|
||||||
wss.on('connection', ws => {
|
|
||||||
console.log('CONNECTION incoming');
|
|
||||||
ws.once('message', message => {
|
|
||||||
const str = message.toString();
|
|
||||||
switch (str) {
|
|
||||||
case 'SENDER':
|
|
||||||
setSender(ws);
|
|
||||||
break;
|
|
||||||
case 'RECEIVER':
|
|
||||||
addReceiver(ws)
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log('Unknown register code: ' + str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('READY');
|
|
||||||
|
|
||||||
function addReceiver(ws: WebSocket) {
|
|
||||||
console.log('RECEIVER registered');
|
|
||||||
for (const path of paths) {
|
|
||||||
ws.send('START');
|
|
||||||
path.forEach(c => ws.send(JSON.stringify(c)));
|
|
||||||
ws.send('STOP');
|
|
||||||
}
|
|
||||||
|
|
||||||
receivers.push(ws);
|
|
||||||
|
|
||||||
ws.onclose = () => {
|
|
||||||
// Remove receiver when connection closes
|
|
||||||
for (const [i, recv] of receivers.entries()) {
|
|
||||||
if (ws === recv) {
|
|
||||||
receivers.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSender(ws: WebSocket) {
|
|
||||||
console.log('SENDER is being registered')
|
|
||||||
if (sender) {
|
|
||||||
console.log('Removing current sender...')
|
|
||||||
sender.close();
|
|
||||||
clearPaths();
|
|
||||||
}
|
|
||||||
|
|
||||||
sender = ws;
|
|
||||||
ws.on('message', msg => processMessage(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
function processMessage(message: WebSocket.Data) {
|
|
||||||
const text = message.toString();
|
|
||||||
switch (text) {
|
|
||||||
case 'START':
|
|
||||||
startPath();
|
|
||||||
break;
|
|
||||||
case 'STOP':
|
|
||||||
finishPath();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
processCoordinates(text);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function processCoordinates(text: string) {
|
|
||||||
console.log('COORDINATES received: ' + text);
|
|
||||||
|
|
||||||
console.log('SENDING to ' + receivers.length, 'clients');
|
|
||||||
receivers.forEach(r => r.send(text));
|
|
||||||
|
|
||||||
currentPath.push(JSON.parse(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
function startPath() {
|
|
||||||
currentPath = [];
|
|
||||||
receivers.forEach(r => r.send('START'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function finishPath() {
|
|
||||||
paths.push(currentPath);
|
|
||||||
receivers.forEach(r => r.send("STOP"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearPaths() {
|
|
||||||
paths.splice(0, paths.length);
|
|
||||||
receivers.forEach(r => r.send('CLEAR'));
|
|
||||||
console.log('Paths have been cleared');
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
export default class Coordinates {
|
|
||||||
public x: number;
|
|
||||||
public y: number;
|
|
||||||
|
|
||||||
constructor(x: number, y: number) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "@tsconfig/node16/tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"sourceMap": true,
|
|
||||||
"outDir": "dist",
|
|
||||||
"moduleResolution": "node"
|
|
||||||
},
|
|
||||||
"include": ["ts/**/*"],
|
|
||||||
"exclude": ["node_modules", "**/*.spec.ts"]
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
import CanvasUtil from './canvas-util/canvasUtil.js';
|
import CanvasUtil from './canvas-util/canvasUtil.js';
|
||||||
import Coordinates from './canvas-util/coordinates.js';
|
import Coordinates from './canvas-util/coordinates.js';
|
||||||
import { getWebsocketUrl } from "./websocket/websocket.js";
|
|
||||||
|
|
||||||
class CanvasReceiverController {
|
class CanvasReceiverController {
|
||||||
|
private canvas!: HTMLCanvasElement;
|
||||||
private canvasDiv: HTMLDivElement;
|
private canvasDiv: HTMLDivElement;
|
||||||
private canvasUtil: CanvasUtil;
|
private canvasUtil: CanvasUtil;
|
||||||
private ws: WebSocket;
|
private ws: WebSocket;
|
||||||
|
@ -23,7 +23,7 @@ class CanvasReceiverController {
|
||||||
alert('Canvas API unavailable, drawing will not work!');
|
alert('Canvas API unavailable, drawing will not work!');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ws = new WebSocket(getWebsocketUrl(), 'json');
|
this.ws = new WebSocket('ws://localhost:8081', 'json');
|
||||||
|
|
||||||
this.ws.onmessage = message => this.processMessage(message);
|
this.ws.onmessage = message => this.processMessage(message);
|
||||||
this.ws.onopen = () => this.ws.send('RECEIVER');
|
this.ws.onopen = () => this.ws.send('RECEIVER');
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import CanvasUtil from "./canvas-util/canvasUtil.js";
|
import CanvasUtil from "./canvas-util/canvasUtil.js";
|
||||||
import Coordinates from "./canvas-util/coordinates.js";
|
import Coordinates from "./canvas-util/coordinates.js";
|
||||||
import { getWebsocketUrl } from "./websocket/websocket.js";
|
|
||||||
|
|
||||||
class CanvasSenderController {
|
class CanvasSenderController {
|
||||||
private canvasUtil: CanvasUtil;
|
private canvasUtil: CanvasUtil;
|
||||||
|
@ -29,7 +28,7 @@ class CanvasSenderController {
|
||||||
canvas.addEventListener('touchmove', e => this.onMouseMove(e.touches[0]));
|
canvas.addEventListener('touchmove', e => this.onMouseMove(e.touches[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ws = new WebSocket(getWebsocketUrl(), 'json');
|
this.ws = new WebSocket('ws://localhost:8081', 'json');
|
||||||
this.ws.onopen = () => this.ws.send('SENDER');
|
this.ws.onopen = () => this.ws.send('SENDER');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
export function getWebsocketUrl(): string {
|
|
||||||
let scheme = 'ws';
|
|
||||||
|
|
||||||
if (document.location.protocol === 'https:') {
|
|
||||||
scheme += 's';
|
|
||||||
}
|
|
||||||
|
|
||||||
return scheme + '://' + document.location.hostname + ':8081';
|
|
||||||
}
|
|
Loading…
Reference in New Issue