@react-shimeji/core 0.2.0 → 0.2.2
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/dist/index.cjs +38 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -6
- package/dist/index.d.ts +4 -6
- package/dist/index.js +38 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -47,42 +47,24 @@ module.exports = __toCommonJS(index_exports);
|
|
|
47
47
|
|
|
48
48
|
// src/dom.ts
|
|
49
49
|
var DomManager = class {
|
|
50
|
-
/**
|
|
51
|
-
constructor(container, sprites
|
|
50
|
+
/** Uses the supplied element only as a mount point for independent mascots. */
|
|
51
|
+
constructor(container, sprites) {
|
|
52
52
|
this.container = container;
|
|
53
53
|
this.sprites = sprites;
|
|
54
|
-
const workArea = document.createElement("div");
|
|
55
|
-
workArea.dataset.reactShimejiWorkArea = "true";
|
|
56
|
-
if (workAreaClassName) workArea.className = workAreaClassName;
|
|
57
|
-
Object.assign(workArea.style, {
|
|
58
|
-
position: "absolute",
|
|
59
|
-
inset: "0",
|
|
60
|
-
width: "100%",
|
|
61
|
-
height: "100%",
|
|
62
|
-
overflow: "hidden",
|
|
63
|
-
pointerEvents: "none",
|
|
64
|
-
zIndex: "2147483643"
|
|
65
|
-
});
|
|
66
|
-
this.workArea = workArea;
|
|
67
|
-
this.ensureMounted();
|
|
68
54
|
}
|
|
69
55
|
container;
|
|
70
56
|
sprites;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
/** Reattaches the work area if application code temporarily removed it. */
|
|
57
|
+
handles = /* @__PURE__ */ new Set();
|
|
58
|
+
/** Reattaches mascot elements if application code temporarily removed them. */
|
|
74
59
|
ensureMounted() {
|
|
75
|
-
|
|
60
|
+
for (const handle of this.handles) {
|
|
61
|
+
if (handle.element.parentElement !== this.container) this.container.appendChild(handle.element);
|
|
62
|
+
}
|
|
76
63
|
}
|
|
77
|
-
/** Returns
|
|
64
|
+
/** Returns viewport bounds because fixed mascots use viewport coordinates. */
|
|
78
65
|
getBounds() {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
/** Converts a previously-read work-area client rectangle into local bounds. */
|
|
82
|
-
getBoundsFromClientRectangle(rectangle) {
|
|
83
|
-
const width = rectangle.width || this.container.clientWidth || window.innerWidth;
|
|
84
|
-
const height = rectangle.height || this.container.clientHeight || window.innerHeight;
|
|
85
|
-
return { x: 0, y: 0, width, height };
|
|
66
|
+
const view = this.container.ownerDocument.defaultView ?? window;
|
|
67
|
+
return { x: 0, y: 0, width: view.innerWidth, height: view.innerHeight };
|
|
86
68
|
}
|
|
87
69
|
/** Creates a mascot node and acquires its spritesheet resource. */
|
|
88
70
|
createMascot(spec, mascotId, mascotClassName) {
|
|
@@ -90,12 +72,14 @@ var DomManager = class {
|
|
|
90
72
|
const element = document.createElement("div");
|
|
91
73
|
element.dataset.shimejiId = mascotId;
|
|
92
74
|
if (mascotClassName) element.className = mascotClassName;
|
|
93
|
-
Object.assign(element.style, { position: "
|
|
75
|
+
Object.assign(element.style, { position: "fixed", left: "0", top: "0", width: "0", height: "0", pointerEvents: "none", zIndex: "9999", userSelect: "none", willChange: "transform" });
|
|
94
76
|
const spriteElement = document.createElement("div");
|
|
95
|
-
Object.assign(spriteElement.style, { position: "absolute", left: "0", top: "0", backgroundRepeat: "no-repeat", transformOrigin: "center center", pointerEvents: "none" });
|
|
77
|
+
Object.assign(spriteElement.style, { position: "absolute", left: "0", top: "0", backgroundRepeat: "no-repeat", transformOrigin: "center center", pointerEvents: "auto", touchAction: "none", userSelect: "none" });
|
|
96
78
|
element.appendChild(spriteElement);
|
|
97
|
-
|
|
98
|
-
|
|
79
|
+
const handle = { element, spriteElement, spriteLease };
|
|
80
|
+
this.handles.add(handle);
|
|
81
|
+
this.container.appendChild(element);
|
|
82
|
+
return handle;
|
|
99
83
|
}
|
|
100
84
|
/** Paints one mascot state into its existing DOM nodes. */
|
|
101
85
|
render(handle, spec, state) {
|
|
@@ -127,12 +111,18 @@ var DomManager = class {
|
|
|
127
111
|
}
|
|
128
112
|
/** Removes one mascot node and releases its temporary image URL. */
|
|
129
113
|
removeMascot(handle) {
|
|
114
|
+
if (!this.handles.delete(handle)) return;
|
|
130
115
|
handle.element.remove();
|
|
131
116
|
handle.spriteLease.release();
|
|
132
117
|
}
|
|
133
|
-
/**
|
|
118
|
+
/** Returns whether an element belongs to one of this manager's mascots. */
|
|
119
|
+
owns(element) {
|
|
120
|
+
for (const handle of this.handles) if (handle.element === element || handle.element.contains(element)) return true;
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
/** Removes every mascot element and releases its temporary image URL. */
|
|
134
124
|
destroy() {
|
|
135
|
-
this.
|
|
125
|
+
for (const handle of [...this.handles]) this.removeMascot(handle);
|
|
136
126
|
}
|
|
137
127
|
};
|
|
138
128
|
|
|
@@ -986,6 +976,7 @@ function environmentRectangle(bounds) {
|
|
|
986
976
|
};
|
|
987
977
|
}
|
|
988
978
|
var PLATFORM_NEARBY_DISTANCE = 400;
|
|
979
|
+
var PLATFORM_EDGE_TOLERANCE = 16;
|
|
989
980
|
function distanceToRectangle(point, rectangle) {
|
|
990
981
|
const dx = Math.max(rectangle.x - point.x, 0, point.x - rectangle.x - rectangle.width);
|
|
991
982
|
const dy = Math.max(rectangle.y - point.y, 0, point.y - rectangle.y - rectangle.height);
|
|
@@ -1059,9 +1050,11 @@ var Mascot = class {
|
|
|
1059
1050
|
}
|
|
1060
1051
|
if (!started) break;
|
|
1061
1052
|
}
|
|
1062
|
-
const
|
|
1053
|
+
const activeIE = environment.mascot.environment.activeIE;
|
|
1054
|
+
const wasOnPlatformTop = activeIE.visible && activeIE.topBorder.isOn(this.state);
|
|
1063
1055
|
const completed = this.actions.tick(deltaMs, environment, bounds);
|
|
1064
|
-
|
|
1056
|
+
const remainedNearPlatform = this.state.x >= activeIE.left - PLATFORM_EDGE_TOLERANCE && this.state.x <= activeIE.right + PLATFORM_EDGE_TOLERANCE;
|
|
1057
|
+
if (wasOnPlatformTop && !remainedNearPlatform && !platforms.some((platform) => isOnTop(this.state, platform))) {
|
|
1065
1058
|
this.actions.cancel();
|
|
1066
1059
|
this.currentBehavior = this.findFallBehavior();
|
|
1067
1060
|
if (this.currentBehavior) this.startBehavior(this.createEnvironment(bounds, platforms));
|
|
@@ -1146,7 +1139,7 @@ var Mascot = class {
|
|
|
1146
1139
|
return nearby;
|
|
1147
1140
|
}
|
|
1148
1141
|
installPointerHandlers() {
|
|
1149
|
-
const element = this.domHandle.
|
|
1142
|
+
const element = this.domHandle.spriteElement;
|
|
1150
1143
|
const listen = (target, type, listener) => {
|
|
1151
1144
|
target.addEventListener(type, listener);
|
|
1152
1145
|
this.disposers.push(() => target.removeEventListener(type, listener));
|
|
@@ -1155,8 +1148,7 @@ var Mascot = class {
|
|
|
1155
1148
|
const pointerEvent = event;
|
|
1156
1149
|
if (pointerEvent.button !== 0) return;
|
|
1157
1150
|
event.preventDefault();
|
|
1158
|
-
const
|
|
1159
|
-
const point = { x: pointerEvent.clientX - bounds.left, y: pointerEvent.clientY - bounds.top };
|
|
1151
|
+
const point = { x: pointerEvent.clientX, y: pointerEvent.clientY };
|
|
1160
1152
|
this.pointerId = pointerEvent.pointerId;
|
|
1161
1153
|
this.pointerDown = point;
|
|
1162
1154
|
this.lastPointer = point;
|
|
@@ -1170,8 +1162,7 @@ var Mascot = class {
|
|
|
1170
1162
|
listen(document, "pointermove", (event) => {
|
|
1171
1163
|
const pointerEvent = event;
|
|
1172
1164
|
if (!this.state.dragging || pointerEvent.pointerId !== this.pointerId) return;
|
|
1173
|
-
const
|
|
1174
|
-
const point = { x: pointerEvent.clientX - bounds.left, y: pointerEvent.clientY - bounds.top };
|
|
1165
|
+
const point = { x: pointerEvent.clientX, y: pointerEvent.clientY };
|
|
1175
1166
|
const previous = this.lastPointer ?? point;
|
|
1176
1167
|
this.state.vx = (point.x - previous.x) * 0.8;
|
|
1177
1168
|
this.state.vy = (point.y - previous.y) * 0.8;
|
|
@@ -1319,10 +1310,7 @@ var ShimejiEngine = class {
|
|
|
1319
1310
|
if (!container) throw new TypeError("ShimejiEngine requires a container element");
|
|
1320
1311
|
this.options = { ...defaults, ...options, random: options.random };
|
|
1321
1312
|
this.platformSource = this.options.platforms;
|
|
1322
|
-
this.
|
|
1323
|
-
this.adjustedContainerPosition = getComputedStyle(container).position === "static";
|
|
1324
|
-
if (this.adjustedContainerPosition) container.style.position = "relative";
|
|
1325
|
-
this.dom = new DomManager(container, this.sprites, this.options.workAreaClassName || void 0);
|
|
1313
|
+
this.dom = new DomManager(container, this.sprites);
|
|
1326
1314
|
this.initialize();
|
|
1327
1315
|
}
|
|
1328
1316
|
container;
|
|
@@ -1334,8 +1322,6 @@ var ShimejiEngine = class {
|
|
|
1334
1322
|
disposers = [];
|
|
1335
1323
|
intervals = /* @__PURE__ */ new Set();
|
|
1336
1324
|
options;
|
|
1337
|
-
originalContainerPosition;
|
|
1338
|
-
adjustedContainerPosition;
|
|
1339
1325
|
pointer = { x: 0, y: 0, dx: 0, dy: 0 };
|
|
1340
1326
|
animationFrame;
|
|
1341
1327
|
lastFrameTime;
|
|
@@ -1350,9 +1336,8 @@ var ShimejiEngine = class {
|
|
|
1350
1336
|
this.initialized = true;
|
|
1351
1337
|
this.listen(document, "pointermove", (event) => {
|
|
1352
1338
|
const pointerEvent = event;
|
|
1353
|
-
const
|
|
1354
|
-
const
|
|
1355
|
-
const y = pointerEvent.clientY - rectangle.top;
|
|
1339
|
+
const x = pointerEvent.clientX;
|
|
1340
|
+
const y = pointerEvent.clientY;
|
|
1356
1341
|
this.pointer = { x, y, dx: x - this.pointer.x, dy: y - this.pointer.y };
|
|
1357
1342
|
});
|
|
1358
1343
|
this.listen(window, "resize", () => this.renderAll());
|
|
@@ -1456,7 +1441,6 @@ var ShimejiEngine = class {
|
|
|
1456
1441
|
this.sprites.destroy();
|
|
1457
1442
|
this.specs.clear();
|
|
1458
1443
|
this.events.clear();
|
|
1459
|
-
if (this.adjustedContainerPosition && this.container.style.position === "relative") this.container.style.position = this.originalContainerPosition;
|
|
1460
1444
|
this.destroyed = true;
|
|
1461
1445
|
this.initialized = false;
|
|
1462
1446
|
}
|
|
@@ -1479,10 +1463,9 @@ var ShimejiEngine = class {
|
|
|
1479
1463
|
for (const mascot of this.mascots.values()) mascot.tick(0, bounds, platforms);
|
|
1480
1464
|
}
|
|
1481
1465
|
readFrameGeometry() {
|
|
1482
|
-
const
|
|
1483
|
-
const
|
|
1484
|
-
|
|
1485
|
-
return { bounds, platforms: readPlatformRectangles(elements, workAreaRectangle) };
|
|
1466
|
+
const bounds = this.dom.getBounds();
|
|
1467
|
+
const elements = resolvePlatformElements(this.platformSource, this.container.ownerDocument).filter((element) => !this.dom.owns(element));
|
|
1468
|
+
return { bounds, platforms: readPlatformRectangles(elements, { left: 0, top: 0 }) };
|
|
1486
1469
|
}
|
|
1487
1470
|
emitState() {
|
|
1488
1471
|
this.events.emit("statechange", this.getState());
|