@lemoncat7/dsh-theme-xiaohei 0.4.6 → 0.5.1
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/README.md +15 -9
- package/THIRD_PARTY_NOTICES.md +13 -1
- package/docs/dsh-021-compatibility.md +23 -0
- package/docs/releases/0.5.0.md +24 -0
- package/docs/rift-interaction.md +35 -0
- package/docs/rift-preview.md +39 -0
- package/lib/client.companion.js +3 -4
- package/lib/client.decorations.js +224 -51
- package/lib/client.js +534 -2405
- package/lib/index.d.ts +1 -2
- package/lib/index.js +395 -11
- package/lib/rift/boot.d.ts +6 -0
- package/package.json +29 -19
- package/lib/appearance.d.ts +0 -12
- package/lib/appearance.js +0 -42
- package/lib/blink.d.ts +0 -4
- package/lib/blink.js +0 -110
- package/lib/bloub-heixiu/ambient.d.ts +0 -3
- package/lib/bloub-heixiu/ambient.js +0 -12
- package/lib/bloub-heixiu/character.d.ts +0 -33
- package/lib/bloub-heixiu/character.js +0 -124
- package/lib/bloub-heixiu/effects.d.ts +0 -4
- package/lib/bloub-heixiu/effects.js +0 -91
- package/lib/bloub-heixiu/flight.d.ts +0 -15
- package/lib/bloub-heixiu/flight.js +0 -66
- package/lib/bloub-heixiu/follow.d.ts +0 -13
- package/lib/bloub-heixiu/follow.js +0 -23
- package/lib/bloub-heixiu/layout.d.ts +0 -34
- package/lib/bloub-heixiu/layout.js +0 -26
- package/lib/bloub-heixiu/renderer.d.ts +0 -16
- package/lib/bloub-heixiu/renderer.js +0 -94
- package/lib/bloub-heixiu/runtime.d.ts +0 -6
- package/lib/bloub-heixiu/runtime.js +0 -440
- package/lib/bloub-heixiu/signals.d.ts +0 -17
- package/lib/bloub-heixiu/signals.js +0 -55
- package/lib/bloub-heixiu/styles.d.ts +0 -2
- package/lib/bloub-heixiu/styles.js +0 -98
- package/lib/boot-appearance.d.ts +0 -10
- package/lib/boot-appearance.js +0 -47
- package/lib/boot-loader.d.ts +0 -5
- package/lib/boot-loader.js +0 -158
- package/lib/chrome/accessibility.d.ts +0 -3
- package/lib/chrome/accessibility.js +0 -69
- package/lib/chrome/blink.d.ts +0 -3
- package/lib/chrome/blink.js +0 -15
- package/lib/chrome/composer-avatar.d.ts +0 -10
- package/lib/chrome/composer-avatar.js +0 -599
- package/lib/chrome/composer-send-heixiu.d.ts +0 -3
- package/lib/chrome/composer-send-heixiu.js +0 -143
- package/lib/chrome/composer.d.ts +0 -3
- package/lib/chrome/composer.js +0 -135
- package/lib/chrome/controls.d.ts +0 -8
- package/lib/chrome/controls.js +0 -348
- package/lib/chrome/conversation-messages.d.ts +0 -3
- package/lib/chrome/conversation-messages.js +0 -329
- package/lib/chrome/conversation-submissions.d.ts +0 -3
- package/lib/chrome/conversation-submissions.js +0 -68
- package/lib/chrome/conversation.d.ts +0 -3
- package/lib/chrome/conversation.js +0 -67
- package/lib/chrome/frames.d.ts +0 -6
- package/lib/chrome/frames.js +0 -134
- package/lib/chrome/gaze.d.ts +0 -3
- package/lib/chrome/gaze.js +0 -103
- package/lib/chrome/identity.d.ts +0 -6
- package/lib/chrome/identity.js +0 -47
- package/lib/chrome/overlays.d.ts +0 -3
- package/lib/chrome/overlays.js +0 -104
- package/lib/chrome/portal.d.ts +0 -6
- package/lib/chrome/portal.js +0 -169
- package/lib/chrome/reactions.d.ts +0 -3
- package/lib/chrome/reactions.js +0 -85
- package/lib/chrome/sidebar.d.ts +0 -3
- package/lib/chrome/sidebar.js +0 -313
- package/lib/chrome/tokens.d.ts +0 -3
- package/lib/chrome/tokens.js +0 -224
- package/lib/chrome/workspace.d.ts +0 -3
- package/lib/chrome/workspace.js +0 -94
- package/lib/chrome.d.ts +0 -10
- package/lib/chrome.js +0 -46
- package/lib/client-entry.d.ts +0 -3
- package/lib/client-entry.js +0 -3
- package/lib/client.d.ts +0 -10
- package/lib/client.pose-chin-dark.js +0 -4
- package/lib/client.pose-chin-light.js +0 -4
- package/lib/client.pose-doze-dark.js +0 -4
- package/lib/client.pose-doze-light.js +0 -4
- package/lib/client.pose-halfpeek-dark.js +0 -4
- package/lib/client.pose-halfpeek-light.js +0 -4
- package/lib/client.pose-peek-dark.js +0 -4
- package/lib/client.pose-peek-light.js +0 -4
- package/lib/client.pose-seated-dark.js +0 -4
- package/lib/client.pose-seated-light.js +0 -4
- package/lib/client.rig-chin-dark.js +0 -4
- package/lib/client.rig-chin-light.js +0 -4
- package/lib/client.rig-halfpeek-dark.js +0 -4
- package/lib/client.rig-halfpeek-light.js +0 -4
- package/lib/client.rig-peek-dark.js +0 -4
- package/lib/client.rig-peek-light.js +0 -4
- package/lib/client.rig-seated-dark.js +0 -4
- package/lib/client.rig-seated-light.js +0 -4
- package/lib/companion-entry.d.ts +0 -3
- package/lib/companion-entry.js +0 -3
- package/lib/composer-avatar.d.ts +0 -18
- package/lib/composer-avatar.js +0 -441
- package/lib/composer-draft-preview.d.ts +0 -4
- package/lib/composer-draft-preview.js +0 -8
- package/lib/composer-send-heixiu.d.ts +0 -8
- package/lib/composer-send-heixiu.js +0 -133
- package/lib/current-session.d.ts +0 -6
- package/lib/current-session.js +0 -5
- package/lib/decorations-entry.d.ts +0 -3
- package/lib/decorations-entry.js +0 -18
- package/lib/deferred-companion.d.ts +0 -5
- package/lib/deferred-companion.js +0 -9
- package/lib/deferred-decorations.d.ts +0 -3
- package/lib/deferred-decorations.js +0 -51
- package/lib/gaze.d.ts +0 -4
- package/lib/gaze.js +0 -230
- package/lib/generated-backgrounds.d.ts +0 -14
- package/lib/generated-backgrounds.js +0 -14
- package/lib/generated-character-motion.d.ts +0 -4
- package/lib/generated-character-motion.js +0 -2
- package/lib/generated-identity.d.ts +0 -6
- package/lib/generated-identity.js +0 -6
- package/lib/generated-keyart.d.ts +0 -34
- package/lib/generated-keyart.js +0 -34
- package/lib/generated-loading-assets.d.ts +0 -4
- package/lib/generated-loading-assets.js +0 -4
- package/lib/heixiu-interactions.d.ts +0 -10
- package/lib/heixiu-interactions.js +0 -161
- package/lib/host-contract.d.ts +0 -9
- package/lib/host-contract.js +0 -13
- package/lib/host-dom.d.ts +0 -11
- package/lib/host-dom.js +0 -72
- package/lib/loading-heixiu.d.ts +0 -8
- package/lib/loading-heixiu.js +0 -287
- package/lib/metallic-brand-mark.d.ts +0 -10
- package/lib/metallic-brand-mark.js +0 -296
- package/lib/plugin.d.ts +0 -6
- package/lib/plugin.js +0 -60
- package/lib/portal.d.ts +0 -40
- package/lib/portal.js +0 -225
- package/lib/reactions.d.ts +0 -20
- package/lib/reactions.js +0 -380
- package/lib/scene/avatar-model.d.ts +0 -6
- package/lib/scene/avatar-model.js +0 -646
- package/lib/scene/avatar-motion.d.ts +0 -3
- package/lib/scene/avatar-motion.js +0 -799
- package/lib/scene/character-assets.d.ts +0 -13
- package/lib/scene/character-assets.js +0 -26
- package/lib/scene/character-expression.d.ts +0 -4
- package/lib/scene/character-expression.js +0 -15
- package/lib/scene/character-eye-material.d.ts +0 -13
- package/lib/scene/character-eye-material.js +0 -88
- package/lib/scene/character-eye-renderer.d.ts +0 -5
- package/lib/scene/character-eye-renderer.js +0 -80
- package/lib/scene/character-eye-rig.d.ts +0 -20
- package/lib/scene/character-eye-rig.js +0 -35
- package/lib/scene/character-gaze.d.ts +0 -16
- package/lib/scene/character-gaze.js +0 -36
- package/lib/scene/character-idle.d.ts +0 -17
- package/lib/scene/character-idle.js +0 -65
- package/lib/scene/character-layout.d.ts +0 -24
- package/lib/scene/character-layout.js +0 -51
- package/lib/scene/character-motion-clock.d.ts +0 -18
- package/lib/scene/character-motion-clock.js +0 -70
- package/lib/scene/character-motion-types.d.ts +0 -12
- package/lib/scene/character-motion-types.js +0 -2
- package/lib/scene/character-motion.d.ts +0 -6
- package/lib/scene/character-motion.js +0 -187
- package/lib/scene/character-poses.d.ts +0 -26
- package/lib/scene/character-poses.js +0 -11
- package/lib/scene/character-rig-renderer.d.ts +0 -5
- package/lib/scene/character-rig-renderer.js +0 -95
- package/lib/scene/character-rig.d.ts +0 -22
- package/lib/scene/character-rig.js +0 -61
- package/lib/scene/heixiu-feedback.d.ts +0 -3
- package/lib/scene/heixiu-feedback.js +0 -64
- package/lib/scene/heixiu-interactions.d.ts +0 -3
- package/lib/scene/heixiu-interactions.js +0 -92
- package/lib/scene/ids.d.ts +0 -5
- package/lib/scene/ids.js +0 -5
- package/lib/scene/pointer-bridge.d.ts +0 -21
- package/lib/scene/pointer-bridge.js +0 -155
- package/lib/scene/runtime.d.ts +0 -12
- package/lib/scene/runtime.js +0 -74
- package/lib/scene/state-transitions.d.ts +0 -3
- package/lib/scene/state-transitions.js +0 -37
- package/lib/scene/styles.d.ts +0 -5
- package/lib/scene/styles.js +0 -69
- package/lib/scene/sylva-performance.d.ts +0 -11
- package/lib/scene/sylva-performance.js +0 -58
- package/lib/scene/wallpaper-character-styles.d.ts +0 -3
- package/lib/scene/wallpaper-character-styles.js +0 -49
- package/lib/scene/wallpaper-character.d.ts +0 -5
- package/lib/scene/wallpaper-character.js +0 -222
- package/lib/scene.d.ts +0 -8
- package/lib/scene.js +0 -8
- package/lib/sidebar-glass.d.ts +0 -16
- package/lib/sidebar-glass.js +0 -168
- package/lib/sidebar-heixiu-escape.d.ts +0 -44
- package/lib/sidebar-heixiu-escape.js +0 -340
- package/lib/sidebar-heixiu-roaming.d.ts +0 -27
- package/lib/sidebar-heixiu-roaming.js +0 -310
- package/lib/sidebar-reveal.d.ts +0 -8
- package/lib/sidebar-reveal.js +0 -59
- package/lib/state.d.ts +0 -21
- package/lib/state.js +0 -123
- package/lib/theme.d.ts +0 -19
- package/lib/theme.js +0 -188
- package/lib/vendor/bloub/decor.d.ts +0 -114
- package/lib/vendor/bloub/decor.js +0 -198
- package/lib/vendor/bloub/engine.d.ts +0 -213
- package/lib/vendor/bloub/engine.js +0 -452
- package/lib/vendor/bloub/expressions.d.ts +0 -35
- package/lib/vendor/bloub/expressions.js +0 -143
- package/lib/vendor/bloub/eyefit.d.ts +0 -75
- package/lib/vendor/bloub/eyefit.js +0 -393
- package/lib/vendor/bloub/face.d.ts +0 -63
- package/lib/vendor/bloub/face.js +0 -106
- package/lib/vendor/bloub/math.d.ts +0 -22
- package/lib/vendor/bloub/math.js +0 -36
- package/lib/vendor/bloub/profiles.d.ts +0 -8
- package/lib/vendor/bloub/profiles.js +0 -20
- package/lib/vendor/bloub/repere.d.ts +0 -30
- package/lib/vendor/bloub/repere.js +0 -32
- package/lib/vendor/bloub/shape.d.ts +0 -80
- package/lib/vendor/bloub/shape.js +0 -268
- package/lib/vendor/bloub/skins.d.ts +0 -36
- package/lib/vendor/bloub/skins.js +0 -74
- package/lib/vendor/bloub/states.d.ts +0 -87
- package/lib/vendor/bloub/states.js +0 -468
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { subscribeXiaoheiHostDom } from '../host-dom.js';
|
|
2
|
-
import { XIAOHEI_HOST_SELECTORS } from '../host-contract.js';
|
|
3
|
-
import { XIAOHEI_SCENE_LAYER_ID } from './ids.js';
|
|
4
|
-
import { resolveCharacterPlacement } from './character-layout.js';
|
|
5
|
-
import { createCharacterIdleController } from './character-idle.js';
|
|
6
|
-
import { characterAssets, CHARACTER_POSE_NAMES } from './character-assets.js';
|
|
7
|
-
import { createCharacterMotion } from './character-motion.js';
|
|
8
|
-
export const XIAOHEI_WALLPAPER_CHARACTER_ID = 'dsh-theme-xiaohei/wallpaper-character';
|
|
9
|
-
/** Places the layered character only when the host geometry is settled. */
|
|
10
|
-
export function installXiaoheiWallpaperCharacter(doc = typeof document === 'undefined' ? undefined : document, loadPose = characterAssets.pose) {
|
|
11
|
-
const win = doc?.defaultView;
|
|
12
|
-
if (!doc || !win)
|
|
13
|
-
return () => { };
|
|
14
|
-
let disposed = false;
|
|
15
|
-
let frame;
|
|
16
|
-
let settled;
|
|
17
|
-
let host;
|
|
18
|
-
let targets = [];
|
|
19
|
-
let dirty = true;
|
|
20
|
-
let placement = { pose: 'hidden', left: 0, top: 0, width: 0, height: 0 };
|
|
21
|
-
const ready = new Map();
|
|
22
|
-
const loading = new Set();
|
|
23
|
-
const failed = new Set();
|
|
24
|
-
const motion = typeof win.matchMedia === 'function' ? createCharacterMotion(doc) : undefined;
|
|
25
|
-
const idle = createCharacterIdleController({ now: () => win.performance.now(),
|
|
26
|
-
setTimeout: (fn, delay) => win.setTimeout(fn, delay), clearTimeout: handle => win.clearTimeout(handle),
|
|
27
|
-
}, () => schedule());
|
|
28
|
-
const sizes = new WeakMap();
|
|
29
|
-
const observer = typeof win.ResizeObserver === 'function' ? new win.ResizeObserver(entries => {
|
|
30
|
-
for (const entry of entries) {
|
|
31
|
-
const previous = sizes.get(entry.target);
|
|
32
|
-
const width = entry.contentRect.width;
|
|
33
|
-
const height = entry.contentRect.height;
|
|
34
|
-
sizes.set(entry.target, { width, height });
|
|
35
|
-
// Appending streamed paragraphs changes flow height, not its horizontal
|
|
36
|
-
// safe area. Ignore that size change instead of measuring the whole UI.
|
|
37
|
-
if (!previous || previous.width !== width || (entry.target === targets[0] && previous.height !== height))
|
|
38
|
-
dirty = true;
|
|
39
|
-
}
|
|
40
|
-
if (dirty) {
|
|
41
|
-
schedule();
|
|
42
|
-
scheduleSettled();
|
|
43
|
-
}
|
|
44
|
-
}) : undefined;
|
|
45
|
-
function reconcile() {
|
|
46
|
-
if (disposed || !doc)
|
|
47
|
-
return;
|
|
48
|
-
// The glass owner already tracks the native column's animated geometry.
|
|
49
|
-
// Do not measure controls or rebuild a different rig at intermediate widths.
|
|
50
|
-
if (doc.documentElement?.hasAttribute('data-xiaohei-sidebar-resizing')) {
|
|
51
|
-
dirty = true;
|
|
52
|
-
if (host && host.dataset.pose !== 'hidden')
|
|
53
|
-
host.dataset.pose = 'hidden';
|
|
54
|
-
idle.setPaused(true);
|
|
55
|
-
motion?.setPose(undefined, 'hidden');
|
|
56
|
-
scheduleSettled();
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const layer = doc.getElementById(XIAOHEI_SCENE_LAYER_ID);
|
|
60
|
-
const next = [
|
|
61
|
-
doc.querySelector(XIAOHEI_HOST_SELECTORS.sidebarShell),
|
|
62
|
-
doc.querySelector('[data-conversation-scroll]'),
|
|
63
|
-
doc.querySelector('[data-chat-flow]'),
|
|
64
|
-
doc.querySelector(XIAOHEI_HOST_SELECTORS.composerCard),
|
|
65
|
-
];
|
|
66
|
-
if (next.some((element, i) => element !== targets[i])) {
|
|
67
|
-
targets = next;
|
|
68
|
-
observer?.disconnect();
|
|
69
|
-
for (const element of targets)
|
|
70
|
-
if (element)
|
|
71
|
-
observer?.observe(element);
|
|
72
|
-
dirty = true;
|
|
73
|
-
}
|
|
74
|
-
if (!layer) {
|
|
75
|
-
host?.remove();
|
|
76
|
-
host = undefined;
|
|
77
|
-
idle.setPaused(true);
|
|
78
|
-
motion?.setPose(undefined, 'hidden');
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
if (!host || host.parentElement !== layer) {
|
|
82
|
-
host?.remove();
|
|
83
|
-
doc.getElementById(XIAOHEI_WALLPAPER_CHARACTER_ID)?.remove();
|
|
84
|
-
host = doc.createElement('div');
|
|
85
|
-
host.id = XIAOHEI_WALLPAPER_CHARACTER_ID;
|
|
86
|
-
host.className = 'xiaohei-wallpaper-character';
|
|
87
|
-
host.setAttribute('aria-hidden', 'true');
|
|
88
|
-
host.dataset.pose = 'hidden';
|
|
89
|
-
for (const pose of CHARACTER_POSE_NAMES) {
|
|
90
|
-
const part = doc.createElement('span');
|
|
91
|
-
part.className = `xiaohei-wallpaper-character__${pose}`;
|
|
92
|
-
host.append(part);
|
|
93
|
-
}
|
|
94
|
-
layer.append(host);
|
|
95
|
-
dirty = true;
|
|
96
|
-
}
|
|
97
|
-
if (!dirty) {
|
|
98
|
-
renderPose();
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
dirty = false;
|
|
102
|
-
const [sidebar, scroll, flow, composer] = targets;
|
|
103
|
-
if (!sidebar || !scroll || !composer) {
|
|
104
|
-
placement = { ...placement, pose: 'hidden' };
|
|
105
|
-
renderPose();
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
const sidebarBounds = sidebar.getBoundingClientRect();
|
|
109
|
-
const controls = sidebarBounds.width < 100
|
|
110
|
-
? [...sidebar.querySelectorAll('button,a,input,[role="button"],[role="treeitem"]')]
|
|
111
|
-
.map(e => e.getBoundingClientRect()).filter(r => r.width > 0 && r.height > 0)
|
|
112
|
-
: [];
|
|
113
|
-
const composerBounds = composer.getBoundingClientRect();
|
|
114
|
-
// Native message content is inset 16px from its composer column. Use the
|
|
115
|
-
// same horizontal footprint on the empty welcome page; never use its Y.
|
|
116
|
-
const flowBounds = flow?.getBoundingClientRect() ?? {
|
|
117
|
-
left: composerBounds.left + 16, right: composerBounds.right - 16, top: 0, bottom: 0
|
|
118
|
-
};
|
|
119
|
-
placement = resolveCharacterPlacement({ sidebar: sidebarBounds,
|
|
120
|
-
scroll: scroll.getBoundingClientRect(), flow: flowBounds,
|
|
121
|
-
viewportWidth: win.innerWidth, viewportHeight: win.innerHeight, controls });
|
|
122
|
-
renderPose();
|
|
123
|
-
}
|
|
124
|
-
function renderPose() {
|
|
125
|
-
if (!host || disposed)
|
|
126
|
-
return;
|
|
127
|
-
idle.setPaused(doc.hidden || placement.pose !== 'seated');
|
|
128
|
-
const pose = doc.hidden ? 'hidden' : placement.pose === 'seated' ? idle.pose : placement.pose;
|
|
129
|
-
if (pose === 'hidden') {
|
|
130
|
-
if (host.dataset.pose !== 'hidden')
|
|
131
|
-
host.dataset.pose = 'hidden';
|
|
132
|
-
motion?.setPose(undefined, 'hidden');
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
const appearance = doc.documentElement.dataset.xiaoheiAppearance === 'light' ? 'light' : 'dark';
|
|
136
|
-
const key = `${pose}-${appearance}`;
|
|
137
|
-
if (!ready.has(key)) {
|
|
138
|
-
motion?.setPose(undefined, 'hidden');
|
|
139
|
-
// Do not retain the old location across a layout change: it could now
|
|
140
|
-
// overlap a message. Idle changes keep the already decoded seated pose.
|
|
141
|
-
if (placement.pose !== 'seated' || !['seated', 'chin', 'doze'].includes(host.dataset.pose ?? ''))
|
|
142
|
-
host.dataset.pose = 'hidden';
|
|
143
|
-
if (!loading.has(key) && !failed.has(key)) {
|
|
144
|
-
loading.add(key);
|
|
145
|
-
// Fetch only the requested pose and palette, not the complete catalog.
|
|
146
|
-
void loadPose(pose, appearance).then(async (src) => {
|
|
147
|
-
if (disposed)
|
|
148
|
-
return;
|
|
149
|
-
const image = new win.Image();
|
|
150
|
-
image.src = src;
|
|
151
|
-
await image.decode();
|
|
152
|
-
if (disposed)
|
|
153
|
-
return;
|
|
154
|
-
loading.delete(key);
|
|
155
|
-
ready.set(key, src);
|
|
156
|
-
schedule();
|
|
157
|
-
}).catch(() => { loading.delete(key); failed.add(key); });
|
|
158
|
-
}
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
// Each pose keeps its own coordinates during the short crossfade. No
|
|
162
|
-
// travelling from the right edge through the conversation to the sidebar.
|
|
163
|
-
const part = host.querySelector(`.xiaohei-wallpaper-character__${pose}`);
|
|
164
|
-
if (part.dataset.appearance !== appearance) {
|
|
165
|
-
part.style.setProperty(`--xiaohei-${pose}-art`, `url("${ready.get(key)}")`);
|
|
166
|
-
part.dataset.appearance = appearance;
|
|
167
|
-
}
|
|
168
|
-
for (const key of ['left', 'top', 'width', 'height']) {
|
|
169
|
-
const value = `${Math.round(placement[key] * 100) / 100}px`;
|
|
170
|
-
if (part.style[key] !== value)
|
|
171
|
-
part.style[key] = value;
|
|
172
|
-
}
|
|
173
|
-
if (!part.dataset.ready)
|
|
174
|
-
part.dataset.ready = 'true';
|
|
175
|
-
if (host.dataset.pose !== pose)
|
|
176
|
-
host.dataset.pose = pose;
|
|
177
|
-
motion?.setPose(part, pose);
|
|
178
|
-
}
|
|
179
|
-
function schedule() {
|
|
180
|
-
if (disposed || frame !== undefined)
|
|
181
|
-
return;
|
|
182
|
-
frame = win.requestAnimationFrame(() => { frame = undefined; reconcile(); });
|
|
183
|
-
}
|
|
184
|
-
function scheduleSettled() {
|
|
185
|
-
if (settled !== undefined)
|
|
186
|
-
win.clearTimeout(settled);
|
|
187
|
-
// Native rail/collapse transitions can move the sidebar after its last
|
|
188
|
-
// size notification. One final measurement catches that resting position.
|
|
189
|
-
settled = win.setTimeout(() => { settled = undefined; dirty = true; schedule(); }, 240);
|
|
190
|
-
}
|
|
191
|
-
const unsubscribe = subscribeXiaoheiHostDom(doc, schedule);
|
|
192
|
-
const appearanceObserver = new win.MutationObserver(schedule);
|
|
193
|
-
appearanceObserver.observe(doc.documentElement, { attributes: true, attributeFilter: ['data-xiaohei-appearance'] });
|
|
194
|
-
const resized = () => { dirty = true; schedule(); scheduleSettled(); };
|
|
195
|
-
win.addEventListener('resize', resized, { passive: true });
|
|
196
|
-
const activity = () => idle.activity();
|
|
197
|
-
const events = ['pointermove', 'pointerdown', 'keydown', 'input', 'wheel'];
|
|
198
|
-
for (const event of events)
|
|
199
|
-
doc.addEventListener(event, activity, { passive: true, capture: true });
|
|
200
|
-
const visibility = () => { if (doc.hidden)
|
|
201
|
-
idle.setPaused(true); schedule(); };
|
|
202
|
-
doc.addEventListener('visibilitychange', visibility);
|
|
203
|
-
schedule();
|
|
204
|
-
return () => {
|
|
205
|
-
disposed = true;
|
|
206
|
-
if (frame !== undefined)
|
|
207
|
-
win.cancelAnimationFrame(frame);
|
|
208
|
-
if (settled !== undefined)
|
|
209
|
-
win.clearTimeout(settled);
|
|
210
|
-
unsubscribe();
|
|
211
|
-
observer?.disconnect();
|
|
212
|
-
appearanceObserver.disconnect();
|
|
213
|
-
idle.dispose();
|
|
214
|
-
motion?.dispose();
|
|
215
|
-
for (const event of events)
|
|
216
|
-
doc.removeEventListener(event, activity, true);
|
|
217
|
-
doc.removeEventListener('visibilitychange', visibility);
|
|
218
|
-
win.removeEventListener('resize', resized);
|
|
219
|
-
host?.remove();
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
//# sourceMappingURL=wallpaper-character.js.map
|
package/lib/scene.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/** Public scene facade. Runtime structure and visual styling evolve independently. */
|
|
2
|
-
export { XIAOHEI_SCENE_CSS, XIAOHEI_SCENE_LAYER_ID, XIAOHEI_SCENE_STYLE_ID, XIAOHEI_SCENE_WORLD_CLASS, } from './scene/styles.js';
|
|
3
|
-
export { configureXiaoheiWorldRenderer, installXiaoheiScene, XIAOHEI_SCENE_PART_COUNT, } from './scene/runtime.js';
|
|
4
|
-
export { injectXiaoheiSylvaAvatarModel, prepareXiaoheiSylvaAvatarFrame, XIAOHEI_SYLVA_AVATAR_MARKER, } from './scene/avatar-model.js';
|
|
5
|
-
export { XIAOHEI_AVATAR_MOTION_RUNTIME } from './scene/avatar-motion.js';
|
|
6
|
-
export { injectXiaoheiSylvaPerformanceProfile, XIAOHEI_SYLVA_PERFORMANCE_MARKER, } from './scene/sylva-performance.js';
|
|
7
|
-
export { injectXiaoheiSylvaPointerBridge, prepareXiaoheiSylvaPointerFrame, resolveXiaoheiSylvaPointer, XIAOHEI_SYLVA_POINTER_CHANNEL, XIAOHEI_SYLVA_POINTER_MARKER, } from './scene/pointer-bridge.js';
|
|
8
|
-
//# sourceMappingURL=scene.d.ts.map
|
package/lib/scene.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/** Public scene facade. Runtime structure and visual styling evolve independently. */
|
|
2
|
-
export { XIAOHEI_SCENE_CSS, XIAOHEI_SCENE_LAYER_ID, XIAOHEI_SCENE_STYLE_ID, XIAOHEI_SCENE_WORLD_CLASS, } from './scene/styles.js';
|
|
3
|
-
export { configureXiaoheiWorldRenderer, installXiaoheiScene, XIAOHEI_SCENE_PART_COUNT, } from './scene/runtime.js';
|
|
4
|
-
export { injectXiaoheiSylvaAvatarModel, prepareXiaoheiSylvaAvatarFrame, XIAOHEI_SYLVA_AVATAR_MARKER, } from './scene/avatar-model.js';
|
|
5
|
-
export { XIAOHEI_AVATAR_MOTION_RUNTIME } from './scene/avatar-motion.js';
|
|
6
|
-
export { injectXiaoheiSylvaPerformanceProfile, XIAOHEI_SYLVA_PERFORMANCE_MARKER, } from './scene/sylva-performance.js';
|
|
7
|
-
export { injectXiaoheiSylvaPointerBridge, prepareXiaoheiSylvaPointerFrame, resolveXiaoheiSylvaPointer, XIAOHEI_SYLVA_POINTER_CHANNEL, XIAOHEI_SYLVA_POINTER_MARKER, } from './scene/pointer-bridge.js';
|
|
8
|
-
//# sourceMappingURL=scene.js.map
|
package/lib/sidebar-glass.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/** Stable id for the paint-only glass surface behind DSH's native sidebar. */
|
|
2
|
-
export declare const XIAOHEI_SIDEBAR_GLASS_ID = "dsh-theme-xiaohei/sidebar-glass";
|
|
3
|
-
export interface XiaoheiSidebarGlassBounds {
|
|
4
|
-
left: number;
|
|
5
|
-
top: number;
|
|
6
|
-
width: number;
|
|
7
|
-
height: number;
|
|
8
|
-
}
|
|
9
|
-
/** Keep the visual surface inside the native sidebar without changing layout. */
|
|
10
|
-
export declare function resolveXiaoheiSidebarGlassBounds(rect: Pick<DOMRect, 'left' | 'top' | 'width' | 'height'>): XiaoheiSidebarGlassBounds;
|
|
11
|
-
/**
|
|
12
|
-
* Mount a visual-only glass surface in the scene layer. It mirrors the native
|
|
13
|
-
* sidebar geometry but never becomes an ancestor of controls or fixed dialogs.
|
|
14
|
-
*/
|
|
15
|
-
export declare function installXiaoheiSidebarGlass(doc?: Document | undefined): () => void;
|
|
16
|
-
//# sourceMappingURL=sidebar-glass.d.ts.map
|
package/lib/sidebar-glass.js
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import { XIAOHEI_SCENE_LAYER_ID, XIAOHEI_SCENE_WORLD_CLASS } from './scene/ids.js';
|
|
2
|
-
import { subscribeXiaoheiHostDom } from './host-dom.js';
|
|
3
|
-
import { XIAOHEI_HOST_SELECTORS } from './host-contract.js';
|
|
4
|
-
import { createSidebarReveal } from './sidebar-reveal.js';
|
|
5
|
-
/** Stable id for the paint-only glass surface behind DSH's native sidebar. */
|
|
6
|
-
export const XIAOHEI_SIDEBAR_GLASS_ID = 'dsh-theme-xiaohei/sidebar-glass';
|
|
7
|
-
const HORIZONTAL_INSET_START = 7;
|
|
8
|
-
const HORIZONTAL_INSET_END = 7;
|
|
9
|
-
const VERTICAL_INSET = 8;
|
|
10
|
-
const RESIZE_SETTLE_MS = 120;
|
|
11
|
-
/** Keep the visual surface inside the native sidebar without changing layout. */
|
|
12
|
-
export function resolveXiaoheiSidebarGlassBounds(rect) {
|
|
13
|
-
return {
|
|
14
|
-
left: rect.left + HORIZONTAL_INSET_START,
|
|
15
|
-
top: rect.top + VERTICAL_INSET,
|
|
16
|
-
width: Math.max(0, rect.width - HORIZONTAL_INSET_START - HORIZONTAL_INSET_END),
|
|
17
|
-
height: Math.max(0, rect.height - VERTICAL_INSET * 2),
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Mount a visual-only glass surface in the scene layer. It mirrors the native
|
|
22
|
-
* sidebar geometry but never becomes an ancestor of controls or fixed dialogs.
|
|
23
|
-
*/
|
|
24
|
-
export function installXiaoheiSidebarGlass(doc = typeof document === 'undefined' ? undefined : document) {
|
|
25
|
-
if (doc === undefined)
|
|
26
|
-
return () => { };
|
|
27
|
-
const browserWindow = doc.defaultView;
|
|
28
|
-
if (browserWindow === null)
|
|
29
|
-
return () => { };
|
|
30
|
-
const win = browserWindow;
|
|
31
|
-
let disposed = false;
|
|
32
|
-
let glass;
|
|
33
|
-
let sidebarColumn;
|
|
34
|
-
let animationFrame;
|
|
35
|
-
let resizeSettleTimer;
|
|
36
|
-
let resizing = false;
|
|
37
|
-
let appliedBounds;
|
|
38
|
-
let geometryDirty = true;
|
|
39
|
-
const reveal = createSidebarReveal(doc);
|
|
40
|
-
const clearResizeState = () => {
|
|
41
|
-
if (resizeSettleTimer !== undefined)
|
|
42
|
-
win.clearTimeout(resizeSettleTimer);
|
|
43
|
-
resizeSettleTimer = undefined;
|
|
44
|
-
resizing = false;
|
|
45
|
-
doc.documentElement.removeAttribute('data-xiaohei-sidebar-resizing');
|
|
46
|
-
};
|
|
47
|
-
const markResizeActivity = () => {
|
|
48
|
-
if (glass === undefined)
|
|
49
|
-
return;
|
|
50
|
-
if (!resizing) {
|
|
51
|
-
resizing = true;
|
|
52
|
-
doc.documentElement.setAttribute('data-xiaohei-sidebar-resizing', '');
|
|
53
|
-
}
|
|
54
|
-
if (resizeSettleTimer !== undefined)
|
|
55
|
-
win.clearTimeout(resizeSettleTimer);
|
|
56
|
-
resizeSettleTimer = win.setTimeout(() => {
|
|
57
|
-
resizeSettleTimer = undefined;
|
|
58
|
-
resizing = false;
|
|
59
|
-
doc.documentElement.removeAttribute('data-xiaohei-sidebar-resizing');
|
|
60
|
-
}, RESIZE_SETTLE_MS);
|
|
61
|
-
};
|
|
62
|
-
const resizeObserver = typeof win.ResizeObserver === 'function'
|
|
63
|
-
? new win.ResizeObserver(() => {
|
|
64
|
-
if (disposed)
|
|
65
|
-
return;
|
|
66
|
-
// RO runs after host layout and before paint. Update the independent
|
|
67
|
-
// paint layer now, not in next frame's RAF (which visibly trails).
|
|
68
|
-
const changed = applyBounds();
|
|
69
|
-
geometryDirty = false;
|
|
70
|
-
if (changed)
|
|
71
|
-
markResizeActivity();
|
|
72
|
-
})
|
|
73
|
-
: undefined;
|
|
74
|
-
const applyBounds = () => {
|
|
75
|
-
if (glass === undefined || sidebarColumn === undefined)
|
|
76
|
-
return false;
|
|
77
|
-
const bounds = resolveXiaoheiSidebarGlassBounds(sidebarColumn.getBoundingClientRect());
|
|
78
|
-
reveal.resize(bounds.width + HORIZONTAL_INSET_START + HORIZONTAL_INSET_END);
|
|
79
|
-
const changed = appliedBounds !== undefined && (bounds.left !== appliedBounds.left || bounds.top !== appliedBounds.top ||
|
|
80
|
-
bounds.width !== appliedBounds.width || bounds.height !== appliedBounds.height);
|
|
81
|
-
if (bounds.left !== appliedBounds?.left) {
|
|
82
|
-
glass.style.setProperty('--xiaohei-sidebar-glass-left', `${bounds.left}px`);
|
|
83
|
-
}
|
|
84
|
-
if (bounds.top !== appliedBounds?.top) {
|
|
85
|
-
glass.style.setProperty('--xiaohei-sidebar-glass-top', `${bounds.top}px`);
|
|
86
|
-
}
|
|
87
|
-
if (bounds.width !== appliedBounds?.width) {
|
|
88
|
-
glass.style.setProperty('--xiaohei-sidebar-glass-width', `${bounds.width}px`);
|
|
89
|
-
}
|
|
90
|
-
if (bounds.height !== appliedBounds?.height) {
|
|
91
|
-
glass.style.setProperty('--xiaohei-sidebar-glass-height', `${bounds.height}px`);
|
|
92
|
-
}
|
|
93
|
-
appliedBounds = bounds;
|
|
94
|
-
return changed;
|
|
95
|
-
};
|
|
96
|
-
const reconcile = () => {
|
|
97
|
-
if (disposed)
|
|
98
|
-
return;
|
|
99
|
-
const sceneLayer = doc.getElementById(XIAOHEI_SCENE_LAYER_ID);
|
|
100
|
-
const nextSidebarColumn = doc.querySelector(XIAOHEI_HOST_SELECTORS.sidebarColumn) ?? undefined;
|
|
101
|
-
if (nextSidebarColumn !== sidebarColumn) {
|
|
102
|
-
resizeObserver?.disconnect();
|
|
103
|
-
sidebarColumn = nextSidebarColumn;
|
|
104
|
-
geometryDirty = true;
|
|
105
|
-
if (sidebarColumn !== undefined)
|
|
106
|
-
resizeObserver?.observe(sidebarColumn);
|
|
107
|
-
}
|
|
108
|
-
if (sceneLayer === null || sidebarColumn === undefined) {
|
|
109
|
-
reveal.setColumn(undefined);
|
|
110
|
-
clearResizeState();
|
|
111
|
-
glass?.remove();
|
|
112
|
-
glass = undefined;
|
|
113
|
-
appliedBounds = undefined;
|
|
114
|
-
geometryDirty = true;
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
reveal.setColumn(sidebarColumn);
|
|
118
|
-
if (glass === undefined || glass.parentElement !== sceneLayer) {
|
|
119
|
-
doc.getElementById(XIAOHEI_SIDEBAR_GLASS_ID)?.remove();
|
|
120
|
-
glass = doc.createElement('div');
|
|
121
|
-
glass.id = XIAOHEI_SIDEBAR_GLASS_ID;
|
|
122
|
-
glass.setAttribute('aria-hidden', 'true');
|
|
123
|
-
appliedBounds = undefined;
|
|
124
|
-
geometryDirty = true;
|
|
125
|
-
const world = sceneLayer.querySelector(`.${XIAOHEI_SCENE_WORLD_CLASS}`);
|
|
126
|
-
// null is meaningful here: insertBefore(node, null) appends after a
|
|
127
|
-
// last-child wallpaper. Falling back to firstChild hides glass UNDER it.
|
|
128
|
-
sceneLayer.insertBefore(glass, world !== null ? world.nextSibling : sceneLayer.firstChild);
|
|
129
|
-
}
|
|
130
|
-
// Streamed text mutates the host tree frequently. Recheck slot identity,
|
|
131
|
-
// but do not force layout unless sidebar geometry actually changed.
|
|
132
|
-
if (geometryDirty) {
|
|
133
|
-
applyBounds();
|
|
134
|
-
geometryDirty = false;
|
|
135
|
-
}
|
|
136
|
-
};
|
|
137
|
-
function scheduleReconcile() {
|
|
138
|
-
if (disposed || animationFrame !== undefined)
|
|
139
|
-
return;
|
|
140
|
-
animationFrame = win.requestAnimationFrame(() => {
|
|
141
|
-
animationFrame = undefined;
|
|
142
|
-
reconcile();
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
const unsubscribeHostDom = subscribeXiaoheiHostDom(doc, scheduleReconcile);
|
|
146
|
-
const onViewportResize = () => {
|
|
147
|
-
geometryDirty = true;
|
|
148
|
-
scheduleReconcile();
|
|
149
|
-
};
|
|
150
|
-
win.addEventListener('resize', onViewportResize, { passive: true });
|
|
151
|
-
scheduleReconcile();
|
|
152
|
-
return () => {
|
|
153
|
-
disposed = true;
|
|
154
|
-
if (animationFrame !== undefined)
|
|
155
|
-
win.cancelAnimationFrame(animationFrame);
|
|
156
|
-
animationFrame = undefined;
|
|
157
|
-
unsubscribeHostDom();
|
|
158
|
-
resizeObserver?.disconnect();
|
|
159
|
-
reveal.dispose();
|
|
160
|
-
win.removeEventListener('resize', onViewportResize);
|
|
161
|
-
clearResizeState();
|
|
162
|
-
glass?.remove();
|
|
163
|
-
glass = undefined;
|
|
164
|
-
sidebarColumn = undefined;
|
|
165
|
-
appliedBounds = undefined;
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
//# sourceMappingURL=sidebar-glass.js.map
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
interface Point {
|
|
2
|
-
x: number;
|
|
3
|
-
y: number;
|
|
4
|
-
}
|
|
5
|
-
interface Box {
|
|
6
|
-
left: number;
|
|
7
|
-
top: number;
|
|
8
|
-
right: number;
|
|
9
|
-
bottom: number;
|
|
10
|
-
}
|
|
11
|
-
export interface XiaoheiSidebarEscapeSpace {
|
|
12
|
-
width: number;
|
|
13
|
-
height: number;
|
|
14
|
-
creatureWidth: number;
|
|
15
|
-
creatureHeight: number;
|
|
16
|
-
controls: readonly Box[];
|
|
17
|
-
}
|
|
18
|
-
export interface XiaoheiSidebarEscapeTarget {
|
|
19
|
-
creature: HTMLElement;
|
|
20
|
-
host: HTMLElement;
|
|
21
|
-
space: XiaoheiSidebarEscapeSpace;
|
|
22
|
-
}
|
|
23
|
-
interface XiaoheiSidebarEscapeControllerOptions {
|
|
24
|
-
doc: Document;
|
|
25
|
-
isDisabled: () => boolean;
|
|
26
|
-
resolveTarget: () => XiaoheiSidebarEscapeTarget | undefined;
|
|
27
|
-
onFreeze: (position: Point) => void;
|
|
28
|
-
onTeleport: (destination: Point) => void;
|
|
29
|
-
onComplete: (destination: Point) => void;
|
|
30
|
-
}
|
|
31
|
-
export interface XiaoheiSidebarEscapeController {
|
|
32
|
-
cancel: () => void;
|
|
33
|
-
dispose: () => void;
|
|
34
|
-
isRunning: () => boolean;
|
|
35
|
-
}
|
|
36
|
-
export declare const XIAOHEI_SIDEBAR_ESCAPE_CSS = "\n.xiaohei-sidebar-escape-layer {\n position: absolute;\n inset: 0;\n z-index: 5;\n overflow: hidden;\n contain: layout paint style;\n pointer-events: none;\n}\n\n.xiaohei-sidebar-escape-portal {\n position: absolute;\n left: var(--xiaohei-sidebar-portal-x, 50%);\n top: var(--xiaohei-sidebar-portal-y, 50%);\n display: block;\n width: 2rem;\n height: 2.8rem;\n border-radius: 48% 52% 45% 55% / 54% 46% 55% 45%;\n opacity: 0;\n background:\n radial-gradient(ellipse at 46% 50%, #010304 0%, #020608 57%, #0a2528 70%, rgb(77 194 171 / 40%) 77%, transparent 83%);\n box-shadow:\n inset 0 0 0.55rem rgb(0 0 0 / 94%),\n 0 0 0.65rem rgb(76 201 177 / 16%);\n transform: translate3d(-50%, -50%, 0) rotate(var(--xiaohei-sidebar-portal-angle, 0deg)) scale3d(.06, .16, 1);\n transform-origin: center;\n will-change: transform, opacity;\n}\n\n.xiaohei-sidebar-escape-portal::after {\n position: absolute;\n inset: 14% 19%;\n display: block;\n content: '';\n border-radius: inherit;\n background: #000102;\n box-shadow: inset 0.15rem 0 0.36rem rgb(18 68 67 / 42%);\n}\n\n.xiaohei-sidebar-escape-layer[data-xiaohei-sidebar-escape-phase='enter']\n .xiaohei-sidebar-escape-portal--entry,\n.xiaohei-sidebar-escape-layer[data-xiaohei-sidebar-escape-phase='exit']\n .xiaohei-sidebar-escape-portal--exit {\n animation: xiaohei-sidebar-escape-portal-open 520ms cubic-bezier(.2, .76, .24, 1) both;\n}\n\n.xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase]::before {\n opacity: 0;\n}\n\n.xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase]\n .xiaohei-scene__heixiu-body {\n position: absolute;\n inset: 0;\n display: block;\n transition: none;\n transform-origin: center;\n will-change: transform, opacity;\n}\n\n.xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase='enter']\n .xiaohei-scene__heixiu-body {\n animation: xiaohei-sidebar-heixiu-enter 460ms cubic-bezier(.42, 0, .72, .38) both;\n}\n\n.xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase='exit']\n .xiaohei-scene__heixiu-body {\n animation: xiaohei-sidebar-heixiu-exit 540ms cubic-bezier(.18, .76, .24, 1) both;\n}\n\n@keyframes xiaohei-sidebar-escape-portal-open {\n 0% {\n opacity: 0;\n transform: translate3d(-50%, -50%, 0) rotate(var(--xiaohei-sidebar-portal-angle, 0deg)) scale3d(.06, .16, 1);\n }\n 20%, 72% {\n opacity: .94;\n transform: translate3d(-50%, -50%, 0) rotate(var(--xiaohei-sidebar-portal-angle, 0deg)) scale3d(1, 1, 1);\n }\n 100% {\n opacity: 0;\n transform: translate3d(-50%, -50%, 0) rotate(var(--xiaohei-sidebar-portal-angle, 0deg)) scale3d(.06, .16, 1);\n }\n}\n\n@keyframes xiaohei-sidebar-heixiu-enter {\n 0%, 15% { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }\n 70% { opacity: .82; }\n 100% {\n transform: translate3d(var(--xiaohei-sidebar-escape-in-x), var(--xiaohei-sidebar-escape-in-y), 0) scale(.08);\n opacity: 0;\n }\n}\n\n@keyframes xiaohei-sidebar-heixiu-exit {\n 0%, 16% {\n transform: translate3d(var(--xiaohei-sidebar-escape-out-x), var(--xiaohei-sidebar-escape-out-y), 0) scale(.08);\n opacity: 0;\n }\n 38% { opacity: .72; }\n 100% { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }\n}\n\nhtml[data-xiaohei-appearance='light'] .xiaohei-sidebar-escape-portal {\n background:\n radial-gradient(ellipse at 46% 50%, #010304 0%, #030708 58%, #123231 70%, rgb(46 142 121 / 34%) 77%, transparent 83%);\n box-shadow:\n inset 0 0 0.55rem rgb(0 0 0 / 94%),\n 0 0 0.58rem rgb(44 139 118 / 18%);\n}\n\n@media (prefers-reduced-motion: reduce), (hover: none) and (pointer: coarse), (forced-colors: active) {\n .xiaohei-sidebar-escape-layer { display: none; }\n\n .xiaohei-scene__heixiu--sidebar[data-xiaohei-sidebar-escape-phase]\n .xiaohei-scene__heixiu-body {\n animation: none;\n will-change: auto;\n }\n}\n";
|
|
37
|
-
/** True when the pointer is close enough for the sidebar companion to flee. */
|
|
38
|
-
export declare function isXiaoheiSidebarPointerNear(pointer: Point, creatureCenter: Point): boolean;
|
|
39
|
-
/** Choose a low-obstruction endpoint that is meaningfully away from the pointer. */
|
|
40
|
-
export declare function chooseXiaoheiSidebarEscapeDestination(space: XiaoheiSidebarEscapeSpace, pointer: Point, current: Point, random?: () => number): Point;
|
|
41
|
-
/** Own pointer proximity and the enter/exit portal sequence; roaming owns position. */
|
|
42
|
-
export declare function createXiaoheiSidebarEscapeController(options: XiaoheiSidebarEscapeControllerOptions): XiaoheiSidebarEscapeController;
|
|
43
|
-
export {};
|
|
44
|
-
//# sourceMappingURL=sidebar-heixiu-escape.d.ts.map
|