Rework Line gen, add stats & viewport
Generate 4 separate lines. Trains now follow lines and only spawn on connected stations.
This commit is contained in:
parent
a79f501c5e
commit
df9ba6d5ea
81
package-lock.json
generated
81
package-lock.json
generated
@ -980,6 +980,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/pixi.js/-/pixi.js-4.7.2.tgz",
|
||||
"integrity": "sha512-ybrqVdncNCa81fCYCqxz/CISyMbXl8usszNv0mwdeYDyfDqmemQHJtf4GtduHva+3suhItPc9Akr/WfV19zWiQ=="
|
||||
},
|
||||
"@types/stats.js": {
|
||||
"version": "0.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.0.tgz",
|
||||
"integrity": "sha512-9w+a7bR8PeB0dCT/HBULU2fMqf6BAzvKbxFboYhmDtDkKPiyXYbjoe2auwsXlEFI7CFNMF1dCv3dFH5Poy9R1w=="
|
||||
},
|
||||
"@types/tinycolor2": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.0.tgz",
|
||||
@ -4406,6 +4411,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"exists": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/exists/-/exists-1.0.1.tgz",
|
||||
"integrity": "sha1-/8vuKRQvJAVt8Bkk5zJicz2xC0k="
|
||||
},
|
||||
"exit-hook": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
|
||||
@ -9205,6 +9215,11 @@
|
||||
"sha.js": "2.4.11"
|
||||
}
|
||||
},
|
||||
"penner": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/penner/-/penner-0.1.3.tgz",
|
||||
"integrity": "sha1-C4tILU6bOa8vPXw3WSIpuKzClwU="
|
||||
},
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
@ -9226,11 +9241,46 @@
|
||||
"pinkie": "2.0.4"
|
||||
}
|
||||
},
|
||||
"pixi-ease": {
|
||||
"version": "0.18.0",
|
||||
"resolved": "https://registry.npmjs.org/pixi-ease/-/pixi-ease-0.18.0.tgz",
|
||||
"integrity": "sha512-qC9ofPKHblNlkdKDFgXDcw1vTPg4zDTLBudk32lScafOB59QKE5duElA+XwaS5kEpumVfnlKtg3k4gCcGcat3Q==",
|
||||
"requires": {
|
||||
"eventemitter3": "3.0.1",
|
||||
"penner": "0.1.3",
|
||||
"yy-angle": "1.2.0",
|
||||
"yy-color": "1.0.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"eventemitter3": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.0.1.tgz",
|
||||
"integrity": "sha512-QOCPu979MMWX9XNlfRZoin+Wm+bK1SP7vv3NGUniYwuSJK/+cPA10blMaeRgzg31RvoSFk6FsCDVa4vNryBTGA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"pixi-gl-core": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/pixi-gl-core/-/pixi-gl-core-1.1.4.tgz",
|
||||
"integrity": "sha1-i0tcQzsx5Bm8N53FZc4bg1qRs3I="
|
||||
},
|
||||
"pixi-viewport": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/pixi-viewport/-/pixi-viewport-1.5.0.tgz",
|
||||
"integrity": "sha512-hMPtka90PulpBLXBhE3RZvKaB1VTPFoXe4dSuqsYYBQeo8b1G3FTy7WAfgqkqj1ibrblEf0MmTzO9PzoXKLKXA==",
|
||||
"requires": {
|
||||
"eventemitter3": "3.0.1",
|
||||
"exists": "1.0.1",
|
||||
"pixi-ease": "0.18.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"eventemitter3": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.0.1.tgz",
|
||||
"integrity": "sha512-QOCPu979MMWX9XNlfRZoin+Wm+bK1SP7vv3NGUniYwuSJK/+cPA10blMaeRgzg31RvoSFk6FsCDVa4vNryBTGA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"pixi.js": {
|
||||
"version": "4.7.1",
|
||||
"resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-4.7.1.tgz",
|
||||
@ -10595,6 +10645,11 @@
|
||||
"integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=",
|
||||
"dev": true
|
||||
},
|
||||
"seedrandom": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
|
||||
"integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw="
|
||||
},
|
||||
"select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
@ -11159,6 +11214,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"stats.js": {
|
||||
"version": "0.17.0",
|
||||
"resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz",
|
||||
"integrity": "sha1-scPcRtlEmLV4t/05hbgaznExzH0="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
|
||||
@ -12966,6 +13026,27 @@
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"yy-angle": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yy-angle/-/yy-angle-1.2.0.tgz",
|
||||
"integrity": "sha512-Sf311F5zlItZA0dH/mD3MMG6mIIo1b+9XsFqpLhKCTqFFUL4ip+XWTaQLWLRDkh/Ag0GzAsGt6rWcq61OU9+zQ=="
|
||||
},
|
||||
"yy-color": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/yy-color/-/yy-color-1.0.7.tgz",
|
||||
"integrity": "sha1-P5IxiCQ/q8zqJNNy9Li24wk8Zak=",
|
||||
"requires": {
|
||||
"yy-random": "1.6.0"
|
||||
}
|
||||
},
|
||||
"yy-random": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/yy-random/-/yy-random-1.6.0.tgz",
|
||||
"integrity": "sha512-oMIO8eo4BVed+o8NDMGj9scboHWBFtOdip1oDpXhxYw3A03lYqDqtlwPLg8SOK0q95Fsdzj9EdCQMWFWRk3p7A==",
|
||||
"requires": {
|
||||
"seedrandom": "2.4.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,8 +44,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/pixi.js": "^4.7.2",
|
||||
"@types/stats.js": "^0.17.0",
|
||||
"@types/tinycolor2": "^1.4.0",
|
||||
"pixi-viewport": "^1.5.0",
|
||||
"pixi.js": "^4.7.1",
|
||||
"stats.js": "^0.17.0",
|
||||
"tinycolor2": "^1.4.1"
|
||||
}
|
||||
}
|
||||
|
86
src/Line.ts
86
src/Line.ts
@ -1,72 +1,58 @@
|
||||
import * as tinycolor from 'tinycolor2';
|
||||
|
||||
import Direction, { getPointDirection } from './Direction';
|
||||
import LineConnection from './LineConnection';
|
||||
import Station from './Station';
|
||||
import { distance, randomInt, randomPoint } from './utils';
|
||||
|
||||
const CONNECTION_RADIUS = Math.floor(Math.sqrt(
|
||||
Math.pow(window.innerWidth, 2) + Math.pow(window.innerHeight, 2),
|
||||
) / 4);
|
||||
) / 8);
|
||||
|
||||
export default class Line {
|
||||
public static getLinesWithStation(lines: Line[], station: Station): Line[] {
|
||||
return lines.filter(line => line.stations.indexOf(station) >= 0);
|
||||
}
|
||||
|
||||
public stations: Station[];
|
||||
public name: string;
|
||||
public color: tinycolorInstance;
|
||||
|
||||
constructor(
|
||||
stations: Station[],
|
||||
start: PIXI.Point,
|
||||
startDirection: Direction,
|
||||
numStations: number,
|
||||
name: string,
|
||||
color: tinycolorInstance,
|
||||
) {
|
||||
this.name = name;
|
||||
this.color = color;
|
||||
this.stations = [];
|
||||
let stationsLeft = stations.slice();
|
||||
let currentStation = Station.randomCloseLargeStation(stationsLeft, start, CONNECTION_RADIUS);
|
||||
stationsLeft = stationsLeft.filter(s => s !== currentStation);
|
||||
this.stations.push(currentStation);
|
||||
}
|
||||
|
||||
let direction = startDirection;
|
||||
while (this.stations.length < numStations) {
|
||||
const previousStation = this.stations[this.stations.length - 1];
|
||||
let candidateStations = Station.stationsWithinRadius(
|
||||
stationsLeft,
|
||||
currentStation.location,
|
||||
CONNECTION_RADIUS,
|
||||
);
|
||||
|
||||
if (this.stations.length > 1) {
|
||||
const secondPreviousStation = this.stations[this.stations.length - 2];
|
||||
direction = getPointDirection(secondPreviousStation.location,
|
||||
previousStation.location);
|
||||
}
|
||||
|
||||
const straightStations = Station.stationsInDirection(
|
||||
candidateStations, previousStation.location, direction,
|
||||
);
|
||||
const leftStations = Station.stationsInDirection(
|
||||
candidateStations, previousStation.location, (direction - 1) % 7,
|
||||
);
|
||||
const rightStations = Station.stationsInDirection(
|
||||
candidateStations, previousStation.location, (direction + 1) % 7,
|
||||
);
|
||||
candidateStations = [
|
||||
...straightStations,
|
||||
...leftStations,
|
||||
...rightStations,
|
||||
];
|
||||
|
||||
currentStation = Station.randomCloseLargeStation(candidateStations, previousStation.location,
|
||||
CONNECTION_RADIUS);
|
||||
if (currentStation === null || currentStation === undefined) {
|
||||
public connectStations(
|
||||
currentStation: Station,
|
||||
stations: Station[],
|
||||
visitedStations: Station[],
|
||||
connectionLimit: number,
|
||||
) {
|
||||
visitedStations.push(currentStation);
|
||||
const otherStations = stations.filter(station => station !== currentStation);
|
||||
const closeStations = Station.stationsWithinRadius(
|
||||
otherStations,
|
||||
currentStation.location,
|
||||
CONNECTION_RADIUS,
|
||||
);
|
||||
for (let i = 0; i < connectionLimit; i += 1) {
|
||||
if (closeStations.length < 1) {
|
||||
break;
|
||||
}
|
||||
stationsLeft = stationsLeft.filter(s => s !== currentStation);
|
||||
this.stations.push(currentStation);
|
||||
const largest = Station.largestStation(closeStations);
|
||||
currentStation.connections.push(
|
||||
new LineConnection(largest, this),
|
||||
);
|
||||
closeStations.splice(closeStations.indexOf(largest), 1);
|
||||
}
|
||||
for (const connectedStation of currentStation.connections) {
|
||||
if (visitedStations.indexOf(connectedStation.station) === -1) {
|
||||
this.connectStations(
|
||||
connectedStation.station,
|
||||
stations,
|
||||
visitedStations,
|
||||
connectionLimit,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
src/LineConnection.ts
Normal file
15
src/LineConnection.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import Line from './Line';
|
||||
import Station from './Station';
|
||||
|
||||
export default class LineConnection {
|
||||
public station: Station;
|
||||
public line: Line;
|
||||
|
||||
constructor(
|
||||
station: Station,
|
||||
line: Line,
|
||||
) {
|
||||
this.station = station;
|
||||
this.line = line;
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import * as tinycolor from 'tinycolor2';
|
||||
|
||||
import Direction, { getPointDirection } from './Direction';
|
||||
import LineConnection from './LineConnection';
|
||||
import { distance, randomPoint, weightedRandom } from './utils';
|
||||
|
||||
let stationCount = 0;
|
||||
@ -65,7 +66,7 @@ export default class Station {
|
||||
|
||||
public location: PIXI.Point;
|
||||
public population: number;
|
||||
public connections: Station[];
|
||||
public connections: LineConnection[];
|
||||
public id: number;
|
||||
public label: PIXI.Text;
|
||||
public color: tinycolorInstance;
|
||||
@ -74,12 +75,12 @@ export default class Station {
|
||||
location: PIXI.Point,
|
||||
population: number,
|
||||
color: tinycolorInstance,
|
||||
connections?: Station[],
|
||||
connections?: LineConnection[],
|
||||
) {
|
||||
this.location = location;
|
||||
this.population = population;
|
||||
this.color = color;
|
||||
this.connections = connections;
|
||||
this.connections = connections || [];
|
||||
|
||||
// for debugging
|
||||
stationCount += 1;
|
||||
|
129
src/transport.ts
129
src/transport.ts
@ -1,4 +1,6 @@
|
||||
import * as Viewport from 'pixi-viewport';
|
||||
import * as PIXI from 'pixi.js';
|
||||
import * as Stats from 'stats.js';
|
||||
import * as tinycolor from 'tinycolor2';
|
||||
|
||||
import Direction from './Direction';
|
||||
@ -16,10 +18,14 @@ const NODE_RES = 100;
|
||||
const MAX_SPEED = 10.0;
|
||||
const ACCELERATION = 0.025;
|
||||
const APPROACH_DISTANCE = 3.0;
|
||||
const MAX_JOURNEY = Math.floor(Math.sqrt(
|
||||
Math.pow(window.innerWidth, 2) + Math.pow(window.innerHeight, 2),
|
||||
) / 4);
|
||||
const TRAIN_CAPACITY = 50;
|
||||
const LINE_CONNECTION_LIMIT = 5;
|
||||
const WORLD_WIDTH = 1000;
|
||||
const WORLD_HEIGHT = 1000;
|
||||
const ZOOM_MIN_WIDTH = 100;
|
||||
const ZOOM_MIN_HEIGHT = 100;
|
||||
const ZOOM_MAX_WIDTH = 4000;
|
||||
const ZOOM_MAX_HEIGHT = 4000;
|
||||
|
||||
const trainTexts: PIXI.Text[] = [];
|
||||
|
||||
@ -36,8 +42,11 @@ const initStations = (numStations: number): Station[] => {
|
||||
|
||||
const initTrains = (numTrains: number, stations: Station[]): Train[] => {
|
||||
const trains = [];
|
||||
const stationsWithConnections = stations.filter(station => station.connections.length > 0);
|
||||
for (let i = 0; i < numTrains; i += 1) {
|
||||
const originStation = stations[Math.floor(Math.random() * stations.length)];
|
||||
const originStation = stationsWithConnections[
|
||||
Math.floor(Math.random() * stationsWithConnections.length)
|
||||
];
|
||||
trains.push(new Train(
|
||||
new PIXI.Point(originStation.location.x, originStation.location.y),
|
||||
0, 0, originStation, undefined, tinycolor('grey')),
|
||||
@ -46,15 +55,36 @@ const initTrains = (numTrains: number, stations: Station[]): Train[] => {
|
||||
return trains;
|
||||
};
|
||||
|
||||
const initLines = (numLines: number, stations: Station[]): Line[] => {
|
||||
const lines = [];
|
||||
for (let i = 0; i < numLines; i += 1) {
|
||||
let color = tinycolor.random();
|
||||
while (color.isDark()) {
|
||||
color = tinycolor.random();
|
||||
}
|
||||
const stationsWithoutConnections = stations.filter(station =>
|
||||
station.connections.length === 0,
|
||||
);
|
||||
const centralHub = Station.largestStation(stationsWithoutConnections);
|
||||
const line = new Line(`line-${i}`, tinycolor.random());
|
||||
const stationsLeft = stations.slice(0);
|
||||
line.connectStations(centralHub, stationsLeft, [], LINE_CONNECTION_LIMIT);
|
||||
lines.push(line);
|
||||
}
|
||||
return lines;
|
||||
};
|
||||
|
||||
const moveTrains = (trains: Train[], stations: Station[]) => {
|
||||
for (const train of trains) {
|
||||
if (train.origin.connections.length === 0) {
|
||||
// train is stuck at an orphaned station
|
||||
continue;
|
||||
}
|
||||
// choose a destination randomly with a bias towards larger stations
|
||||
if (train.destination === undefined) {
|
||||
const otherStations = stations.filter(station => station !== train.origin);
|
||||
const closeStations = Station.stationsWithinRadius(otherStations, train.location,
|
||||
MAX_JOURNEY);
|
||||
const closeStationWeights = closeStations.map(station => station.population);
|
||||
train.destination = weightedRandom(closeStations, closeStationWeights);
|
||||
const otherStations = train.origin.connections.map(conn => conn.station);
|
||||
const closeStationWeights = otherStations.map(station => station.population);
|
||||
train.destination = weightedRandom(otherStations, closeStationWeights);
|
||||
|
||||
// board passengers
|
||||
const boardingPassengers = randomInt(0, Math.min(TRAIN_CAPACITY - train.passengers,
|
||||
@ -116,7 +146,7 @@ const moveTrains = (trains: Train[], stations: Station[]) => {
|
||||
|
||||
const drawStations = (stations: Station[], graphics: PIXI.Graphics) => {
|
||||
for (const station of stations) {
|
||||
const radius = station.population / 60;
|
||||
const radius = station.population / 150;
|
||||
graphics.beginFill(parseInt(station.color.toHex(), 16), 0.5);
|
||||
graphics.drawCircle(station.location.x, station.location.y, radius);
|
||||
graphics.endFill();
|
||||
@ -127,10 +157,6 @@ const drawStations = (stations: Station[], graphics: PIXI.Graphics) => {
|
||||
|
||||
const drawTrains = (trains: Train[], graphics: PIXI.Graphics) => {
|
||||
for (const train of trains) {
|
||||
// graphics.beginFill(parseInt(train.color.toHex(), 16), 0.8);
|
||||
// graphics.drawCircle(train.location.x, train.location.y,
|
||||
// rangeMap(train.passengers, 0, TRAIN_CAPACITY, 1, 5));
|
||||
// graphics.endFill();
|
||||
const trainSize = rangeMap(train.passengers, 0, TRAIN_CAPACITY, 1, 5);
|
||||
const scale = trainSize / NODE_RES;
|
||||
train.sprite.x = train.location.x;
|
||||
@ -143,13 +169,18 @@ const drawTrains = (trains: Train[], graphics: PIXI.Graphics) => {
|
||||
}
|
||||
};
|
||||
|
||||
const drawLines = (lines: Line[], graphics: PIXI.Graphics) => {
|
||||
for (const line of lines) {
|
||||
graphics.lineStyle(1, parseInt(line.color.toHex(), 16), 1);
|
||||
const start = line.stations[0].location;
|
||||
graphics.moveTo(start.x, start.y);
|
||||
for (const station of line.stations.slice(1)) {
|
||||
graphics.lineTo(station.location.x, station.location.y);
|
||||
const drawLines = (stations: Station[], graphics: PIXI.Graphics) => {
|
||||
for (const station of stations) {
|
||||
for (const connection of station.connections) {
|
||||
let twoWay = false;
|
||||
for (const conn of connection.station.connections) {
|
||||
if (conn.station === station) {
|
||||
twoWay = true;
|
||||
}
|
||||
}
|
||||
graphics.lineStyle(twoWay ? 2 : 1, parseInt(connection.line.color.toHex(), 16), 1);
|
||||
graphics.moveTo(station.location.x, station.location.y);
|
||||
graphics.lineTo(connection.station.location.x, connection.station.location.y);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -160,41 +191,29 @@ const run = () => {
|
||||
height: window.innerHeight,
|
||||
width: window.innerWidth,
|
||||
});
|
||||
const viewport = new Viewport({
|
||||
screenHeight: window.innerHeight,
|
||||
screenWidth: window.innerWidth,
|
||||
worldHeight: WORLD_HEIGHT,
|
||||
worldWidth: WORLD_WIDTH,
|
||||
});
|
||||
const stats = new Stats();
|
||||
stats.showPanel(0);
|
||||
document.body.appendChild(stats.dom);
|
||||
const ticker = new PIXI.ticker.Ticker();
|
||||
const graphics = new PIXI.Graphics();
|
||||
const fpsText = new PIXI.Text('', { fontSize: '25px', fontFamily: 'monospace', fill: 'yellow' });
|
||||
|
||||
fpsText.anchor = new PIXI.ObservablePoint(null, 0, 1);
|
||||
fpsText.x = window.innerWidth;
|
||||
fpsText.y = 0;
|
||||
|
||||
const stations = initStations(30);
|
||||
const lines = initLines(4, stations);
|
||||
const trains = initTrains(50, stations);
|
||||
const lines = [
|
||||
new Line(
|
||||
stations, new PIXI.Point(0, 0),
|
||||
Direction.Southeast, 12, tinycolor('red'),
|
||||
),
|
||||
new Line(
|
||||
stations, new PIXI.Point(window.innerWidth, 0),
|
||||
Direction.Southwest, 12, tinycolor('darkcyan'),
|
||||
),
|
||||
new Line(
|
||||
stations, new PIXI.Point(window.innerWidth, window.innerHeight),
|
||||
Direction.Northwest, 12, tinycolor('yellow'),
|
||||
),
|
||||
new Line(
|
||||
stations, new PIXI.Point(0, window.innerHeight),
|
||||
Direction.Northeast, 12, tinycolor('green'),
|
||||
),
|
||||
];
|
||||
|
||||
ticker.stop();
|
||||
ticker.add((deltaTime) => {
|
||||
stats.begin();
|
||||
|
||||
moveTrains(trains, stations);
|
||||
|
||||
graphics.clear();
|
||||
fpsText.text = `${Math.round(ticker.FPS)}`;
|
||||
|
||||
graphics.lineStyle(1, 0xFFA500, 1);
|
||||
drawStations(stations, graphics);
|
||||
@ -202,24 +221,32 @@ const run = () => {
|
||||
graphics.lineStyle(1, 0xAEAEAE, 1);
|
||||
drawTrains(trains, graphics);
|
||||
|
||||
drawLines(lines, graphics);
|
||||
drawLines(stations, graphics);
|
||||
|
||||
stats.end();
|
||||
});
|
||||
ticker.start();
|
||||
|
||||
app.stage.addChild(graphics);
|
||||
app.stage.addChild(fpsText);
|
||||
viewport.addChild(graphics);
|
||||
// add train sprites
|
||||
for (const train of trains) {
|
||||
app.stage.addChild(train.sprite);
|
||||
viewport.addChild(train.sprite);
|
||||
}
|
||||
// Add debug labels
|
||||
for (const train of trains) {
|
||||
app.stage.addChild(train.label);
|
||||
viewport.addChild(train.label);
|
||||
}
|
||||
for (const station of stations) {
|
||||
app.stage.addChild(station.label);
|
||||
viewport.addChild(station.label);
|
||||
}
|
||||
document.body.appendChild(app.view);
|
||||
app.stage.addChild(viewport);
|
||||
viewport.drag().pinch().wheel().clampZoom({
|
||||
maxHeight: ZOOM_MAX_HEIGHT,
|
||||
maxWidth: ZOOM_MAX_WIDTH,
|
||||
minHeight: ZOOM_MIN_HEIGHT,
|
||||
minWidth: ZOOM_MIN_WIDTH,
|
||||
}).decelerate();
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
app.renderer.resize(window.innerWidth, window.innerHeight);
|
||||
|
@ -10,6 +10,7 @@ module.exports = {
|
||||
filename: 'transport.js',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
},
|
||||
mode: env === 'production' ? 'production' : 'development',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user