mudlet-map-renderer 0.0.25 → 0.1.0-konva
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/demo/colors.json +1 -0
- package/demo/index.html +102 -0
- package/demo/main.ts +389 -0
- package/demo/mapExport.json +1 -0
- package/demo/tsconfig.json +11 -0
- package/package.json +34 -23
- package/src/ExitRenderer.ts +275 -0
- package/src/PathFinder.ts +93 -0
- package/src/PathRenderer.ts +129 -0
- package/src/Renderer.ts +374 -0
- package/src/directions.ts +66 -0
- package/src/index.ts +4 -0
- package/src/reader/Area.ts +96 -0
- package/src/reader/Exit.ts +36 -0
- package/src/reader/ExplorationArea.ts +132 -0
- package/src/reader/MapReader.ts +123 -0
- package/src/reader/Plane.ts +42 -0
- package/src/types/MapData.ts +90 -0
- package/tsconfig.json +17 -0
- package/vercel.json +5 -0
- package/vite.config.ts +29 -0
- package/vite.demo.config.ts +15 -0
- package/.prettierrc +0 -5
- package/CHANGELOG.md +0 -69
- package/README.md +0 -59
- package/exports.js +0 -5
- package/map-fragment/draw/controls.js +0 -172
- package/map-fragment/draw/renderer.js +0 -819
- package/map-fragment/reader/Area.js +0 -74
- package/map-fragment/reader/MapReader.js +0 -89
- package/map-fragment/reader/PathFinder.js +0 -26
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import Area from "./Area";
|
|
2
|
+
import ExplorationArea from "./ExplorationArea";
|
|
3
|
+
|
|
4
|
+
interface Color {
|
|
5
|
+
rgb: number[];
|
|
6
|
+
rgbValue: string;
|
|
7
|
+
symbolColor: number[];
|
|
8
|
+
symbolColorValue: string,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const defaultColor: Color = {
|
|
12
|
+
rgb: [114, 1, 0],
|
|
13
|
+
rgbValue: 'rgb(114, 1, 0)',
|
|
14
|
+
symbolColor: [225, 225, 225],
|
|
15
|
+
symbolColorValue: 'rgb(225,225,225)'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function calculateLuminance(rgb: number[]) {
|
|
19
|
+
const rn = rgb[0] / 255;
|
|
20
|
+
const gn = rgb[1] / 255;
|
|
21
|
+
const bn = rgb[2] / 255;
|
|
22
|
+
|
|
23
|
+
const max = Math.max(rn, gn, bn);
|
|
24
|
+
const min = Math.min(rn, gn, bn);
|
|
25
|
+
|
|
26
|
+
return (max + min) / 2;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default class MapReader {
|
|
30
|
+
|
|
31
|
+
private rooms: Record<number, MapData.Room> = {};
|
|
32
|
+
private areas: Record<number, Area> = {};
|
|
33
|
+
private areaSources: Record<number, MapData.Area> = {};
|
|
34
|
+
private visitedRooms?: Set<number>;
|
|
35
|
+
private explorationEnabled = false;
|
|
36
|
+
private colors: Record<number, Color> = {};
|
|
37
|
+
|
|
38
|
+
constructor(map: MapData.Map, envs: MapData.Env[]) {
|
|
39
|
+
map.forEach(area => {
|
|
40
|
+
area.rooms.forEach(room => {
|
|
41
|
+
room.y = -room.y;
|
|
42
|
+
this.rooms[room.id] = room;
|
|
43
|
+
})
|
|
44
|
+
const areaId = parseInt(area.areaId);
|
|
45
|
+
this.areas[areaId] = new Area(area);
|
|
46
|
+
this.areaSources[areaId] = area;
|
|
47
|
+
})
|
|
48
|
+
this.colors = envs.reduce((acc, c) => ({
|
|
49
|
+
...acc,
|
|
50
|
+
[c.envId]: {
|
|
51
|
+
rgb: c.colors,
|
|
52
|
+
rgbValue: `rgb(${c.colors.join(',')}`,
|
|
53
|
+
symbolColor: calculateLuminance(c.colors) > 0.41 ? [25, 25, 25] : [225, 255, 255],
|
|
54
|
+
symbolColorValue: calculateLuminance(c.colors) > 0.41 ? 'rgb(25,25,25)' : 'rgb(225,255,255)'
|
|
55
|
+
}
|
|
56
|
+
}), {});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getArea(areaId: number) {
|
|
60
|
+
return this.areas[areaId];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getExplorationArea(areaId: number) {
|
|
64
|
+
const area = this.areas[areaId];
|
|
65
|
+
if (area instanceof ExplorationArea) {
|
|
66
|
+
return area;
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getAreas() {
|
|
72
|
+
return Object.values(this.areas);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getRooms() {
|
|
76
|
+
return Object.values(this.rooms);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
getRoom(roomId: number) {
|
|
80
|
+
return this.rooms[roomId];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
decorateWithExploration(visitedRooms?: Iterable<number> | Set<number>) {
|
|
84
|
+
this.visitedRooms = visitedRooms instanceof Set ? visitedRooms : new Set(visitedRooms ?? []);
|
|
85
|
+
Object.entries(this.areaSources).forEach(([id, area]) => {
|
|
86
|
+
const numericId = parseInt(id, 10);
|
|
87
|
+
this.areas[numericId] = new ExplorationArea(area, this.visitedRooms!);
|
|
88
|
+
});
|
|
89
|
+
this.explorationEnabled = true;
|
|
90
|
+
return this.visitedRooms;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getVisitedRooms() {
|
|
94
|
+
return this.visitedRooms;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
clearExplorationDecoration() {
|
|
98
|
+
Object.entries(this.areaSources).forEach(([id, area]) => {
|
|
99
|
+
const numericId = parseInt(id, 10);
|
|
100
|
+
this.areas[numericId] = new Area(area);
|
|
101
|
+
});
|
|
102
|
+
this.explorationEnabled = false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
isExplorationEnabled() {
|
|
106
|
+
return this.explorationEnabled;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
getColorValue(envId: number): string {
|
|
110
|
+
return this.colors[envId]?.rgbValue ?? defaultColor.rgbValue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
getSymbolColor(envId: number, opacity?: number): string {
|
|
114
|
+
const color = this.colors[envId]?.symbolColor ?? defaultColor.symbolColor;
|
|
115
|
+
const normalizedOpacity = Math.min(Math.max(opacity ?? 1, 0), 1);
|
|
116
|
+
const value = color.join(',');
|
|
117
|
+
if (normalizedOpacity != 1) {
|
|
118
|
+
return `rgba(${value}, ${normalizedOpacity})`;
|
|
119
|
+
}
|
|
120
|
+
return `rgba(${value})`;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export default class Plane {
|
|
2
|
+
|
|
3
|
+
private readonly bounds: { minX: number, maxX: number, minY: number, maxY: number }
|
|
4
|
+
private readonly rooms: MapData.Room[] = [];
|
|
5
|
+
private readonly labels: MapData.Label[] = [];
|
|
6
|
+
|
|
7
|
+
constructor(rooms: MapData.Room[], labels: MapData.Label[]) {
|
|
8
|
+
this.rooms = rooms
|
|
9
|
+
this.bounds = this.createBounds();
|
|
10
|
+
this.labels = labels
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getRooms() {
|
|
14
|
+
return this.rooms;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
getLabels() {
|
|
18
|
+
return this.labels;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
getBounds() {
|
|
22
|
+
return this.bounds;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private createBounds() {
|
|
26
|
+
return this.rooms.reduce(
|
|
27
|
+
(acc, r) => ({
|
|
28
|
+
minX: Math.min(acc.minX, r.x),
|
|
29
|
+
maxX: Math.max(acc.maxX, r.x),
|
|
30
|
+
minY: Math.min(acc.minY, r.y),
|
|
31
|
+
maxY: Math.max(acc.maxY, r.y),
|
|
32
|
+
}),
|
|
33
|
+
{
|
|
34
|
+
minX: Number.POSITIVE_INFINITY,
|
|
35
|
+
maxX: Number.NEGATIVE_INFINITY,
|
|
36
|
+
minY: Number.POSITIVE_INFINITY,
|
|
37
|
+
maxY: Number.NEGATIVE_INFINITY,
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
declare namespace MapData {
|
|
2
|
+
|
|
3
|
+
export type direction =
|
|
4
|
+
"north"
|
|
5
|
+
| "south"
|
|
6
|
+
| "east"
|
|
7
|
+
| "west"
|
|
8
|
+
| "northwest"
|
|
9
|
+
| "northeast"
|
|
10
|
+
| "southeast"
|
|
11
|
+
| "southwest"
|
|
12
|
+
| "up"
|
|
13
|
+
| "down"
|
|
14
|
+
| "in"
|
|
15
|
+
| "out"
|
|
16
|
+
|
|
17
|
+
export interface Color {
|
|
18
|
+
alpha: number;
|
|
19
|
+
r: number;
|
|
20
|
+
g: number;
|
|
21
|
+
b: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface Line {
|
|
25
|
+
points: Point[];
|
|
26
|
+
attributes: LineAttribute;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface Point {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface LineAttribute {
|
|
35
|
+
color: Color;
|
|
36
|
+
style: string;
|
|
37
|
+
arrow: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface Room {
|
|
41
|
+
id: number;
|
|
42
|
+
area: number;
|
|
43
|
+
x: number;
|
|
44
|
+
y: number;
|
|
45
|
+
z: number;
|
|
46
|
+
areaId: string;
|
|
47
|
+
weight: number;
|
|
48
|
+
roomChar: string;
|
|
49
|
+
name: string;
|
|
50
|
+
userData: Record<string, string>;
|
|
51
|
+
customLines: Record<string, Line>;
|
|
52
|
+
stubs: number[];
|
|
53
|
+
hash: string;
|
|
54
|
+
env: number;
|
|
55
|
+
exits: Record<direction, number>;
|
|
56
|
+
doors: Record<string, 1 | 2 | 3>;
|
|
57
|
+
specialExits: Record<string, number>;
|
|
58
|
+
exitLocks?: number[];
|
|
59
|
+
mSpecialExitLocks?: number[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface Label {
|
|
63
|
+
labelId: number;
|
|
64
|
+
areaId: number;
|
|
65
|
+
pixMap: string;
|
|
66
|
+
X: number;
|
|
67
|
+
Y: number;
|
|
68
|
+
Z: number;
|
|
69
|
+
Width: number;
|
|
70
|
+
Height: number;
|
|
71
|
+
Text: string;
|
|
72
|
+
FgColor: Color;
|
|
73
|
+
BgColor: Color;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface Area {
|
|
77
|
+
areaName: string;
|
|
78
|
+
areaId: string;
|
|
79
|
+
rooms: Room[];
|
|
80
|
+
labels: Label[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type Map = Area[]
|
|
84
|
+
|
|
85
|
+
export interface Env {
|
|
86
|
+
envId: number;
|
|
87
|
+
colors: number[];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2021",
|
|
4
|
+
"lib": ["ES2021", "DOM"],
|
|
5
|
+
"module": "ES2020",
|
|
6
|
+
"moduleResolution": "Bundler",
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"declarationDir": "dist",
|
|
9
|
+
"outDir": "dist",
|
|
10
|
+
"strict": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"sourceMap": true,
|
|
15
|
+
},
|
|
16
|
+
"include": ["src"]
|
|
17
|
+
}
|
package/vercel.json
ADDED
package/vite.config.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import dts from 'vite-plugin-dts';
|
|
3
|
+
|
|
4
|
+
export default defineConfig(({ command }) => ({
|
|
5
|
+
root: command === 'serve' ? 'demo' : '.',
|
|
6
|
+
plugins: [
|
|
7
|
+
dts({
|
|
8
|
+
include: ['src'],
|
|
9
|
+
outDir: 'dist'
|
|
10
|
+
})
|
|
11
|
+
],
|
|
12
|
+
build: {
|
|
13
|
+
lib: {
|
|
14
|
+
entry: 'src/index.ts',
|
|
15
|
+
name: 'mudlet-map-renderer',
|
|
16
|
+
fileName: (format) => (format === 'es' ? 'index.mjs' : 'index.cjs'),
|
|
17
|
+
formats: ['es', 'cjs']
|
|
18
|
+
},
|
|
19
|
+
rollupOptions: {
|
|
20
|
+
external: ['konva', 'canvas']
|
|
21
|
+
},
|
|
22
|
+
sourcemap: true,
|
|
23
|
+
emptyOutDir: true
|
|
24
|
+
},
|
|
25
|
+
server: {
|
|
26
|
+
open: true,
|
|
27
|
+
port: 5173
|
|
28
|
+
}
|
|
29
|
+
}));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
root: 'demo',
|
|
6
|
+
resolve: {
|
|
7
|
+
alias: {
|
|
8
|
+
'@src': path.resolve(__dirname, 'src')
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
build: {
|
|
12
|
+
outDir: 'dist',
|
|
13
|
+
emptyOutDir: true
|
|
14
|
+
}
|
|
15
|
+
});
|
package/.prettierrc
DELETED
package/CHANGELOG.md
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# 0.0.24
|
|
2
|
-
- respect room weights
|
|
3
|
-
# 0.0.23
|
|
4
|
-
- do not draw path fragments no on the level of displayed area
|
|
5
|
-
|
|
6
|
-
# 0.0.22
|
|
7
|
-
- handle not existing paths
|
|
8
|
-
|
|
9
|
-
# 0.0.21
|
|
10
|
-
- fixes in special links to other areas
|
|
11
|
-
- add controls for paths
|
|
12
|
-
|
|
13
|
-
# 0.0.20
|
|
14
|
-
|
|
15
|
-
# 0.0.19
|
|
16
|
-
- add path renders
|
|
17
|
-
|
|
18
|
-
# 0.0.18
|
|
19
|
-
- drag event will be fired actually on drag not only on release
|
|
20
|
-
|
|
21
|
-
# 0.0.17
|
|
22
|
-
- fix emboss
|
|
23
|
-
|
|
24
|
-
# 0.0.16
|
|
25
|
-
- add emoss setting
|
|
26
|
-
- add drag event
|
|
27
|
-
|
|
28
|
-
# 0.0.15
|
|
29
|
-
- additional fix for custom exit lines exit
|
|
30
|
-
# 0.0.14
|
|
31
|
-
- add area change clicks on custom exit lines
|
|
32
|
-
# 0.0.13
|
|
33
|
-
- add line color (experimental)
|
|
34
|
-
|
|
35
|
-
# 0.0.12
|
|
36
|
-
- try to limit label font size to fit within label bounds
|
|
37
|
-
|
|
38
|
-
# 0.0.11
|
|
39
|
-
- another fix frame mode for background selection
|
|
40
|
-
|
|
41
|
-
# 0.0.10
|
|
42
|
-
- fix frame mode for background selection
|
|
43
|
-
|
|
44
|
-
# 0.0.9
|
|
45
|
-
- add transparent labels option
|
|
46
|
-
|
|
47
|
-
# 0.0.8
|
|
48
|
-
- remove wrong limits for drag
|
|
49
|
-
# 0.0.7
|
|
50
|
-
- fix renderer compliation error
|
|
51
|
-
# 0.0.6
|
|
52
|
-
- fix controls error when zooming out max
|
|
53
|
-
- make JS code not use experimental features
|
|
54
|
-
# 0.0.5
|
|
55
|
-
- add limit function for areas
|
|
56
|
-
|
|
57
|
-
# 0.0.4
|
|
58
|
-
- fix exports
|
|
59
|
-
|
|
60
|
-
# 0.0.3
|
|
61
|
-
- add option to set font and background color
|
|
62
|
-
- multiple fixes
|
|
63
|
-
|
|
64
|
-
# 0.0.2
|
|
65
|
-
- add option to set font for text labels
|
|
66
|
-
- fix README example
|
|
67
|
-
|
|
68
|
-
# 0.0.1
|
|
69
|
-
- initial release
|
package/README.md
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# Mudlet Map Renderer
|
|
2
|
-
|
|
3
|
-
Mudlet map rendering library. Can be used in Node.js and in browser.
|
|
4
|
-
|
|
5
|
-
Until version `1.0.0` API is subject of change. Use with caution!
|
|
6
|
-
|
|
7
|
-
## TODO
|
|
8
|
-
|
|
9
|
-
- [ ] Publish some examples (with data)
|
|
10
|
-
- [ ] Convert to .ts
|
|
11
|
-
- [ ] Document functions
|
|
12
|
-
- [ ] Add test
|
|
13
|
-
- [ ] Add lint
|
|
14
|
-
- [ ] Align model with mudlet-map-binary-reader
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
## Very basic example
|
|
18
|
-
|
|
19
|
-
```js
|
|
20
|
-
const fs = require("fs");
|
|
21
|
-
const { MudletMapReader } = require("mudlet-map-binary-reader") //npm mudlet-map-binary-reader
|
|
22
|
-
const { Renderer, MapReader } = require("mudlet-map-renderer")
|
|
23
|
-
|
|
24
|
-
let map = MudletMapReader.read("./data/map.dat");
|
|
25
|
-
MudletMapReader.export(map, "./data");
|
|
26
|
-
let mapData = require("./data/mapExport.json");
|
|
27
|
-
let mapColors = require("./data/colors.json");
|
|
28
|
-
|
|
29
|
-
let reader = new MapReader(mapData, mapColors);
|
|
30
|
-
|
|
31
|
-
const roomId = 1;
|
|
32
|
-
const scale = 40;
|
|
33
|
-
let area = reader.getAreaByRoomId(roomId);
|
|
34
|
-
let settings = { scale: scale }
|
|
35
|
-
let renderer = new Renderer(null, reader, area, reader.getColors(), settings);
|
|
36
|
-
fs.writeFileSync("mapFull.svg", renderer.exportSvg());
|
|
37
|
-
fs.writeFileSync("mapFragment.svg", renderer.exportSvg(roomId, 10));
|
|
38
|
-
console.log("Map generated");
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Settings and their default values
|
|
42
|
-
```js
|
|
43
|
-
class Settings {
|
|
44
|
-
isRound = false;
|
|
45
|
-
scale = 55;
|
|
46
|
-
roomSize = 10;
|
|
47
|
-
exitsSize = 2;
|
|
48
|
-
borders = false;
|
|
49
|
-
frameMode = false;
|
|
50
|
-
areaName = true;
|
|
51
|
-
showLabels = true;
|
|
52
|
-
uniformLevelSize = false;
|
|
53
|
-
fontFamily = 'sans-serif';
|
|
54
|
-
mapBackground = "#000000";
|
|
55
|
-
linesColor = '#FFFFFF';
|
|
56
|
-
transparentLabels = false;
|
|
57
|
-
emboss = false;
|
|
58
|
-
}
|
|
59
|
-
```
|
package/exports.js
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
const paper = require("paper");
|
|
2
|
-
const { PathFinder } = require("../reader/PathFinder");
|
|
3
|
-
|
|
4
|
-
let selectionStyle = function (item) {
|
|
5
|
-
let style = {
|
|
6
|
-
strokeColor: new paper.Color(180 / 255, 93 / 255, 60 / 255, 0.9),
|
|
7
|
-
};
|
|
8
|
-
if (item.closed) {
|
|
9
|
-
style.fillColor = new paper.Color(
|
|
10
|
-
new paper.Gradient([[item.fillColor, 0.38], new paper.Color(1, 1, 1)], false),
|
|
11
|
-
item.bounds.topCenter,
|
|
12
|
-
item.bounds.bottomCenter
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
return style;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
paper.Item.prototype.select = function (styleFunction) {
|
|
19
|
-
this.mapSelected = !this.mapSelected;
|
|
20
|
-
if (this.mapSelected && styleFunction !== undefined) {
|
|
21
|
-
let style = styleFunction(this);
|
|
22
|
-
this.orgStyle = {};
|
|
23
|
-
for (const key in style) {
|
|
24
|
-
this.orgStyle[key] = this[key];
|
|
25
|
-
}
|
|
26
|
-
this.style = style;
|
|
27
|
-
} else {
|
|
28
|
-
this.style = this.orgStyle;
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
class Controls {
|
|
33
|
-
constructor(renderer, reader, element, paperScope) {
|
|
34
|
-
this.renderer = renderer;
|
|
35
|
-
this.reader = reader;
|
|
36
|
-
this.element = element;
|
|
37
|
-
this.scope = paperScope;
|
|
38
|
-
this.view = paperScope.view;
|
|
39
|
-
this.element.onwheel = (event) => this.zoom(event);
|
|
40
|
-
this.activateDrag();
|
|
41
|
-
this.renderer.emitter.addEventListener("roomClick", (event) => this.selectRoom(event.detail));
|
|
42
|
-
this.renderer.emitter.addEventListener("backgroundClick", () => this.deselectRoom());
|
|
43
|
-
this.renderer.emitter.addEventListener("areaArrowClick", (event) => this.goToRoomArea(event.detail));
|
|
44
|
-
|
|
45
|
-
let bounds = this.renderer.getBounds();
|
|
46
|
-
|
|
47
|
-
this.view.center = bounds.center;
|
|
48
|
-
this.view.zoom = Math.min(this.view.size.width / bounds.width, this.view.size.height / bounds.height);
|
|
49
|
-
this.view.minZoom = this.view.zoom;
|
|
50
|
-
|
|
51
|
-
this.pathFinder = new PathFinder(reader);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
zoom(event) {
|
|
55
|
-
event.preventDefault();
|
|
56
|
-
let oldZoom = this.view.zoom;
|
|
57
|
-
this.deltaZoom(event.deltaY > 0 ? 0.9 : 1.1);
|
|
58
|
-
let viewPos = this.view.viewToProject(new paper.Point(event.offsetX, event.offsetY));
|
|
59
|
-
let zoomScale = oldZoom / this.view.zoom;
|
|
60
|
-
let centerAdjust = viewPos.subtract(this.view.center);
|
|
61
|
-
let offset = viewPos.subtract(centerAdjust.multiply(zoomScale)).subtract(this.view.center);
|
|
62
|
-
this.view.center = this.view.center.add(offset);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
setZoom(value) {
|
|
66
|
-
this.view.zoom = value;
|
|
67
|
-
this.view.zoom = Math.min(Math.max(this.view.zoom, this.view.minZoom), 50);
|
|
68
|
-
this.element.dispatchEvent(new CustomEvent("zoom", { detail: this.view }));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
deltaZoom(delta) {
|
|
72
|
-
this.setZoom(this.view.zoom * delta);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
activateDrag() {
|
|
76
|
-
let toolPan = new paper.Tool();
|
|
77
|
-
toolPan.activate();
|
|
78
|
-
toolPan.onMouseDrag = (event) => {
|
|
79
|
-
this.toggleOptimizedDrag(true);
|
|
80
|
-
this.element.style.cursor = "all-scroll";
|
|
81
|
-
let delta = event.downPoint.subtract(event.point);
|
|
82
|
-
this.view.translate(delta.negate());
|
|
83
|
-
this.isDrag = true;
|
|
84
|
-
this.element.dispatchEvent(new CustomEvent("drag", { detail: this.view }));
|
|
85
|
-
};
|
|
86
|
-
toolPan.onMouseDown = () => {
|
|
87
|
-
this.isDrag = false;
|
|
88
|
-
this.element.dispatchEvent(new CustomEvent("drag", { detail: this.view }));
|
|
89
|
-
};
|
|
90
|
-
toolPan.onMouseUp = () => {
|
|
91
|
-
this.isDrag = false;
|
|
92
|
-
this.element.style.cursor = "default";
|
|
93
|
-
this.toggleOptimizedDrag(false);
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
toggleOptimizedDrag(state) {
|
|
98
|
-
if (!this.renderer.settings.optimizeDrag) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (state) {
|
|
102
|
-
if (!this.isDrag) {
|
|
103
|
-
this.renderer.linkLayer.visible = false;
|
|
104
|
-
this.renderer.roomLayer.visible = false;
|
|
105
|
-
this.renderer.rasterLayer.visible = true;
|
|
106
|
-
}
|
|
107
|
-
} else {
|
|
108
|
-
this.renderer.linkLayer.visible = true;
|
|
109
|
-
this.renderer.roomLayer.visible = true;
|
|
110
|
-
this.renderer.rasterLayer.visible = false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
selectRoom(room) {
|
|
115
|
-
if (this.isDrag) {
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
this.deselectRoom();
|
|
119
|
-
this.renderer.renderPosition(room.id);
|
|
120
|
-
room.render.select(selectionStyle);
|
|
121
|
-
room.exitsRenders.forEach((render) => render.select(selectionStyle));
|
|
122
|
-
this.selected = room;
|
|
123
|
-
|
|
124
|
-
this.element.dispatchEvent(new CustomEvent("roomSelected", { detail: room }));
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
deselectRoom() {
|
|
128
|
-
if (this.isDrag) {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
this.renderer.clearPosition();
|
|
132
|
-
this.renderer.clearHighlight();
|
|
133
|
-
if (this.selected !== undefined) {
|
|
134
|
-
this.selected.render.select();
|
|
135
|
-
this.selected.exitsRenders.forEach((render) => render.select());
|
|
136
|
-
delete this.selected;
|
|
137
|
-
this.element.dispatchEvent(new CustomEvent("roomDeselected"));
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
centerRoom(id) {
|
|
142
|
-
let room = this.renderer.area.getRoomById(id);
|
|
143
|
-
if (room !== undefined) {
|
|
144
|
-
this.centerOnItem(room.render);
|
|
145
|
-
this.selectRoom(room);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
centerOnItem(item) {
|
|
150
|
-
this.view.center = item.localToGlobal(item.position);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
goToRoomArea(id) {
|
|
154
|
-
let destRoom = this.reader.getRoomById(id);
|
|
155
|
-
this.element.dispatchEvent(new CustomEvent("goToArea", { detail: destRoom }));
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
move(x, y) {
|
|
159
|
-
this.view.translate(new paper.Point(x * 50, y * 50).negate());
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
renderPath(from, to, color) {
|
|
163
|
-
let rooms = this.pathFinder.path(from, to)?.map(number => parseInt(number));
|
|
164
|
-
if (rooms) {
|
|
165
|
-
return this.renderer.renderPath(rooms, color);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
module.exports = {
|
|
171
|
-
Controls: Controls,
|
|
172
|
-
};
|