@aicut/core 0.2.0 → 0.4.0
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 +12 -11
- package/dist/lighting/index.cjs +29 -170
- package/dist/lighting/index.cjs.map +1 -1
- package/dist/lighting/index.d.cts +15 -67
- package/dist/lighting/index.d.ts +15 -67
- package/dist/lighting/index.js +29 -170
- package/dist/lighting/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/theme.css +23 -95
|
@@ -15,11 +15,6 @@ interface LightingLocale {
|
|
|
15
15
|
lightingRim: string;
|
|
16
16
|
lightingViewPerspective: string;
|
|
17
17
|
lightingViewFront: string;
|
|
18
|
-
lightingResetParams: string;
|
|
19
|
-
/** Aria label / tooltip for the × button that closes the Smart panel. */
|
|
20
|
-
lightingSmartClose: string;
|
|
21
|
-
/** Tooltip / label for the controls-header Smart Mode toggle. */
|
|
22
|
-
lightingSmartToggle: string;
|
|
23
18
|
lightingDirLeft: string;
|
|
24
19
|
lightingDirRight: string;
|
|
25
20
|
lightingDirTop: string;
|
|
@@ -67,47 +62,26 @@ interface LightingEditorOptions {
|
|
|
67
62
|
config?: Partial<LightingConfig>;
|
|
68
63
|
/** Initial camera view. Default `"perspective"`. */
|
|
69
64
|
view?: LightingView;
|
|
70
|
-
/**
|
|
71
|
-
* Whether the Smart Mode feature is wired in at all. When false the
|
|
72
|
-
* slot column never renders and the controls header hides the
|
|
73
|
-
* Smart Mode toggle — the layout becomes a clean 2-column
|
|
74
|
-
* (scene + controls). Default `true`.
|
|
75
|
-
*/
|
|
76
|
-
smartEnabled?: boolean;
|
|
77
|
-
/**
|
|
78
|
-
* When `smartEnabled` is true, whether the Smart Mode slot panel
|
|
79
|
-
* starts open. Hosts toggle later via `api.setSmartOpen(bool)` or
|
|
80
|
-
* by clicking the library-rendered × button. Default `true`.
|
|
81
|
-
*/
|
|
82
|
-
smartOpen?: boolean;
|
|
83
65
|
/** Theme tokens — same shape as the video Editor's theme. */
|
|
84
66
|
theme?: Theme;
|
|
85
67
|
/** Locale overrides on top of English defaults (`localeEn` + `lightingLocaleEn`). */
|
|
86
68
|
locale?: Partial<Locale & LightingLocale>;
|
|
87
69
|
/** Fires on any config mutation (drag, slider, preset click, toggle). */
|
|
88
70
|
onChange?: (cfg: LightingConfig) => void;
|
|
89
|
-
/**
|
|
90
|
-
* Surface event for the host's own "Generate" button — the library
|
|
91
|
-
* never wires this. Use `api.requestGenerate()` from your UI.
|
|
92
|
-
*/
|
|
93
|
-
onGenerate?: (cfg: LightingConfig) => void;
|
|
94
|
-
/** Fires when the user toggles the Smart Mode panel via × / toggle. */
|
|
95
|
-
onSmartOpenChange?: (open: boolean) => void;
|
|
96
71
|
}
|
|
97
72
|
/** Safe, conservative defaults for first mount. */
|
|
98
73
|
declare const DEFAULT_LIGHTING_CONFIG: LightingConfig;
|
|
99
74
|
|
|
100
75
|
/**
|
|
101
|
-
* Top-level lighting picker.
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* the video Editor; the two can coexist in the same host page.
|
|
76
|
+
* Top-level lighting picker. Two columns: a 3D scene (sphere + subject
|
|
77
|
+
* plane + draggable light dot + cone beam) and a controls panel
|
|
78
|
+
* (brightness / color / 6-direction key-light grid / rim toggle).
|
|
105
79
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
80
|
+
* Deliberately scoped to JUST the picker — the host owns everything
|
|
81
|
+
* around it (smart-mode UI, generate buttons, layout, close handling,
|
|
82
|
+
* theming above the editor). Render <LightingEditor> alongside your
|
|
83
|
+
* own Smart panel in your own flex/grid; the library doesn't try to
|
|
84
|
+
* model "open / closed drawer" semantics for you.
|
|
111
85
|
*/
|
|
112
86
|
declare class LightingEditor {
|
|
113
87
|
private root;
|
|
@@ -115,22 +89,14 @@ declare class LightingEditor {
|
|
|
115
89
|
private config;
|
|
116
90
|
private view;
|
|
117
91
|
private locale;
|
|
118
|
-
private smartEnabled;
|
|
119
|
-
private smartOpen;
|
|
120
92
|
private scene;
|
|
121
93
|
private controls;
|
|
122
94
|
private sceneViewport;
|
|
123
95
|
private viewToggleEl;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
private smartToggleThumb;
|
|
129
|
-
/** Host slot the React/Vue wrapper portals/teleports into. Stable
|
|
130
|
-
* reference across smartOpen toggles — only the wrapper around it
|
|
131
|
-
* collapses/expands. Always present even when `smartEnabled: false`
|
|
132
|
-
* so portals don't blow up; just detached from the visible tree. */
|
|
133
|
-
readonly smartSlot: HTMLDivElement;
|
|
96
|
+
/** Footer slot in the controls column. Host appends Reset/Generate/
|
|
97
|
+
* preset-save/etc. buttons here. The library renders nothing into
|
|
98
|
+
* it — it's the same convention as the video editor's toolbar slots. */
|
|
99
|
+
readonly controlsFooter: HTMLDivElement;
|
|
134
100
|
private resizeObs;
|
|
135
101
|
private destroyed;
|
|
136
102
|
static create(opts: LightingEditorOptions): LightingEditor;
|
|
@@ -138,35 +104,17 @@ declare class LightingEditor {
|
|
|
138
104
|
getConfig(): LightingConfig;
|
|
139
105
|
setConfig(partial: Partial<LightingConfig>, _reason?: "external" | "reset"): void;
|
|
140
106
|
setSubjectImage(url: string): void;
|
|
107
|
+
/** Restore config to the safe defaults. Convenience for host's
|
|
108
|
+
* "Reset" button — equivalent to `setConfig(DEFAULT_LIGHTING_CONFIG)`. */
|
|
109
|
+
reset(): void;
|
|
141
110
|
setView(v: LightingView): void;
|
|
142
111
|
getView(): LightingView;
|
|
143
|
-
/** Enable/disable the entire Smart Mode feature at runtime. */
|
|
144
|
-
setSmartEnabled(enabled: boolean): void;
|
|
145
|
-
isSmartEnabled(): boolean;
|
|
146
|
-
/** Open/close the smart slot drawer when enabled. No-op when disabled. */
|
|
147
|
-
setSmartOpen(open: boolean): void;
|
|
148
|
-
isSmartOpen(): boolean;
|
|
149
112
|
setTheme(theme: Theme): void;
|
|
150
113
|
setLocale(locale: Partial<Locale & LightingLocale>): void;
|
|
151
|
-
requestGenerate(): void;
|
|
152
114
|
destroy(): void;
|
|
153
115
|
private applyMutation;
|
|
154
116
|
private buildViewToggle;
|
|
155
117
|
private syncViewToggle;
|
|
156
|
-
/**
|
|
157
|
-
* Build the smart slot column wrapper: × close button + the actual
|
|
158
|
-
* host slot. Wrapper handles the drawer animation; slot reference
|
|
159
|
-
* stays stable so portals don't have to relocate.
|
|
160
|
-
*/
|
|
161
|
-
private buildSmartWrapper;
|
|
162
|
-
/** Pill-style toggle that lives in the controls header. Re-opens
|
|
163
|
-
* the smart drawer when the host has closed it via ×. */
|
|
164
|
-
private buildSmartToggle;
|
|
165
|
-
/** Re-translate smart-related labels after a locale swap. */
|
|
166
|
-
private syncSmartLocale;
|
|
167
|
-
/** Mirror smart state to data-* attrs + toggle thumb position.
|
|
168
|
-
* Drives the CSS that collapses the column when closed. */
|
|
169
|
-
private syncSmartState;
|
|
170
118
|
}
|
|
171
119
|
|
|
172
120
|
/**
|
package/dist/lighting/index.d.ts
CHANGED
|
@@ -15,11 +15,6 @@ interface LightingLocale {
|
|
|
15
15
|
lightingRim: string;
|
|
16
16
|
lightingViewPerspective: string;
|
|
17
17
|
lightingViewFront: string;
|
|
18
|
-
lightingResetParams: string;
|
|
19
|
-
/** Aria label / tooltip for the × button that closes the Smart panel. */
|
|
20
|
-
lightingSmartClose: string;
|
|
21
|
-
/** Tooltip / label for the controls-header Smart Mode toggle. */
|
|
22
|
-
lightingSmartToggle: string;
|
|
23
18
|
lightingDirLeft: string;
|
|
24
19
|
lightingDirRight: string;
|
|
25
20
|
lightingDirTop: string;
|
|
@@ -67,47 +62,26 @@ interface LightingEditorOptions {
|
|
|
67
62
|
config?: Partial<LightingConfig>;
|
|
68
63
|
/** Initial camera view. Default `"perspective"`. */
|
|
69
64
|
view?: LightingView;
|
|
70
|
-
/**
|
|
71
|
-
* Whether the Smart Mode feature is wired in at all. When false the
|
|
72
|
-
* slot column never renders and the controls header hides the
|
|
73
|
-
* Smart Mode toggle — the layout becomes a clean 2-column
|
|
74
|
-
* (scene + controls). Default `true`.
|
|
75
|
-
*/
|
|
76
|
-
smartEnabled?: boolean;
|
|
77
|
-
/**
|
|
78
|
-
* When `smartEnabled` is true, whether the Smart Mode slot panel
|
|
79
|
-
* starts open. Hosts toggle later via `api.setSmartOpen(bool)` or
|
|
80
|
-
* by clicking the library-rendered × button. Default `true`.
|
|
81
|
-
*/
|
|
82
|
-
smartOpen?: boolean;
|
|
83
65
|
/** Theme tokens — same shape as the video Editor's theme. */
|
|
84
66
|
theme?: Theme;
|
|
85
67
|
/** Locale overrides on top of English defaults (`localeEn` + `lightingLocaleEn`). */
|
|
86
68
|
locale?: Partial<Locale & LightingLocale>;
|
|
87
69
|
/** Fires on any config mutation (drag, slider, preset click, toggle). */
|
|
88
70
|
onChange?: (cfg: LightingConfig) => void;
|
|
89
|
-
/**
|
|
90
|
-
* Surface event for the host's own "Generate" button — the library
|
|
91
|
-
* never wires this. Use `api.requestGenerate()` from your UI.
|
|
92
|
-
*/
|
|
93
|
-
onGenerate?: (cfg: LightingConfig) => void;
|
|
94
|
-
/** Fires when the user toggles the Smart Mode panel via × / toggle. */
|
|
95
|
-
onSmartOpenChange?: (open: boolean) => void;
|
|
96
71
|
}
|
|
97
72
|
/** Safe, conservative defaults for first mount. */
|
|
98
73
|
declare const DEFAULT_LIGHTING_CONFIG: LightingConfig;
|
|
99
74
|
|
|
100
75
|
/**
|
|
101
|
-
* Top-level lighting picker.
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* the video Editor; the two can coexist in the same host page.
|
|
76
|
+
* Top-level lighting picker. Two columns: a 3D scene (sphere + subject
|
|
77
|
+
* plane + draggable light dot + cone beam) and a controls panel
|
|
78
|
+
* (brightness / color / 6-direction key-light grid / rim toggle).
|
|
105
79
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
80
|
+
* Deliberately scoped to JUST the picker — the host owns everything
|
|
81
|
+
* around it (smart-mode UI, generate buttons, layout, close handling,
|
|
82
|
+
* theming above the editor). Render <LightingEditor> alongside your
|
|
83
|
+
* own Smart panel in your own flex/grid; the library doesn't try to
|
|
84
|
+
* model "open / closed drawer" semantics for you.
|
|
111
85
|
*/
|
|
112
86
|
declare class LightingEditor {
|
|
113
87
|
private root;
|
|
@@ -115,22 +89,14 @@ declare class LightingEditor {
|
|
|
115
89
|
private config;
|
|
116
90
|
private view;
|
|
117
91
|
private locale;
|
|
118
|
-
private smartEnabled;
|
|
119
|
-
private smartOpen;
|
|
120
92
|
private scene;
|
|
121
93
|
private controls;
|
|
122
94
|
private sceneViewport;
|
|
123
95
|
private viewToggleEl;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
private smartToggleThumb;
|
|
129
|
-
/** Host slot the React/Vue wrapper portals/teleports into. Stable
|
|
130
|
-
* reference across smartOpen toggles — only the wrapper around it
|
|
131
|
-
* collapses/expands. Always present even when `smartEnabled: false`
|
|
132
|
-
* so portals don't blow up; just detached from the visible tree. */
|
|
133
|
-
readonly smartSlot: HTMLDivElement;
|
|
96
|
+
/** Footer slot in the controls column. Host appends Reset/Generate/
|
|
97
|
+
* preset-save/etc. buttons here. The library renders nothing into
|
|
98
|
+
* it — it's the same convention as the video editor's toolbar slots. */
|
|
99
|
+
readonly controlsFooter: HTMLDivElement;
|
|
134
100
|
private resizeObs;
|
|
135
101
|
private destroyed;
|
|
136
102
|
static create(opts: LightingEditorOptions): LightingEditor;
|
|
@@ -138,35 +104,17 @@ declare class LightingEditor {
|
|
|
138
104
|
getConfig(): LightingConfig;
|
|
139
105
|
setConfig(partial: Partial<LightingConfig>, _reason?: "external" | "reset"): void;
|
|
140
106
|
setSubjectImage(url: string): void;
|
|
107
|
+
/** Restore config to the safe defaults. Convenience for host's
|
|
108
|
+
* "Reset" button — equivalent to `setConfig(DEFAULT_LIGHTING_CONFIG)`. */
|
|
109
|
+
reset(): void;
|
|
141
110
|
setView(v: LightingView): void;
|
|
142
111
|
getView(): LightingView;
|
|
143
|
-
/** Enable/disable the entire Smart Mode feature at runtime. */
|
|
144
|
-
setSmartEnabled(enabled: boolean): void;
|
|
145
|
-
isSmartEnabled(): boolean;
|
|
146
|
-
/** Open/close the smart slot drawer when enabled. No-op when disabled. */
|
|
147
|
-
setSmartOpen(open: boolean): void;
|
|
148
|
-
isSmartOpen(): boolean;
|
|
149
112
|
setTheme(theme: Theme): void;
|
|
150
113
|
setLocale(locale: Partial<Locale & LightingLocale>): void;
|
|
151
|
-
requestGenerate(): void;
|
|
152
114
|
destroy(): void;
|
|
153
115
|
private applyMutation;
|
|
154
116
|
private buildViewToggle;
|
|
155
117
|
private syncViewToggle;
|
|
156
|
-
/**
|
|
157
|
-
* Build the smart slot column wrapper: × close button + the actual
|
|
158
|
-
* host slot. Wrapper handles the drawer animation; slot reference
|
|
159
|
-
* stays stable so portals don't have to relocate.
|
|
160
|
-
*/
|
|
161
|
-
private buildSmartWrapper;
|
|
162
|
-
/** Pill-style toggle that lives in the controls header. Re-opens
|
|
163
|
-
* the smart drawer when the host has closed it via ×. */
|
|
164
|
-
private buildSmartToggle;
|
|
165
|
-
/** Re-translate smart-related labels after a locale swap. */
|
|
166
|
-
private syncSmartLocale;
|
|
167
|
-
/** Mirror smart state to data-* attrs + toggle thumb position.
|
|
168
|
-
* Drives the CSS that collapses the column when closed. */
|
|
169
|
-
private syncSmartState;
|
|
170
118
|
}
|
|
171
119
|
|
|
172
120
|
/**
|
package/dist/lighting/index.js
CHANGED
|
@@ -33,6 +33,13 @@ var LightingControls = class {
|
|
|
33
33
|
/** Exposed so the editor can append host-level chrome (e.g. the
|
|
34
34
|
* Smart Mode toggle) without LightingControls knowing about it. */
|
|
35
35
|
headerSlot;
|
|
36
|
+
/**
|
|
37
|
+
* Footer slot — sits where the built-in Reset used to live. Host
|
|
38
|
+
* appends any action buttons (Reset, Generate, Save preset, etc.)
|
|
39
|
+
* via the React wrapper's `controlsFooter` prop / Vue's
|
|
40
|
+
* `<slot name="controlsFooter">`. Library renders nothing here.
|
|
41
|
+
*/
|
|
42
|
+
footerSlot;
|
|
36
43
|
brightnessInput;
|
|
37
44
|
colorInput;
|
|
38
45
|
dirButtons;
|
|
@@ -45,7 +52,6 @@ var LightingControls = class {
|
|
|
45
52
|
colorLabelEl;
|
|
46
53
|
keyLabelEl;
|
|
47
54
|
rimLabelEl;
|
|
48
|
-
resetBtn;
|
|
49
55
|
locale;
|
|
50
56
|
lastConfig = null;
|
|
51
57
|
constructor(locale, cb) {
|
|
@@ -135,15 +141,12 @@ var LightingControls = class {
|
|
|
135
141
|
});
|
|
136
142
|
rimSection.appendChild(this.rimToggle);
|
|
137
143
|
this.root.appendChild(rimSection);
|
|
138
|
-
|
|
139
|
-
this.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
this.
|
|
144
|
-
this.resetBtn.addEventListener("click", () => cb.onReset());
|
|
145
|
-
footer.appendChild(this.resetBtn);
|
|
146
|
-
this.root.appendChild(footer);
|
|
144
|
+
this.footerSlot = mkDiv("aicut-lighting-controls-footer");
|
|
145
|
+
this.footerSlot.setAttribute(
|
|
146
|
+
"data-testid",
|
|
147
|
+
"aicut-lighting-controls-footer"
|
|
148
|
+
);
|
|
149
|
+
this.root.appendChild(this.footerSlot);
|
|
147
150
|
}
|
|
148
151
|
/** Idempotent — mirror the given config into all visible controls. */
|
|
149
152
|
render(cfg) {
|
|
@@ -172,7 +175,6 @@ var LightingControls = class {
|
|
|
172
175
|
this.colorLabelEl.textContent = locale.lightingColor;
|
|
173
176
|
this.keyLabelEl.textContent = locale.lightingKeyTitle;
|
|
174
177
|
this.rimLabelEl.textContent = locale.lightingRim;
|
|
175
|
-
this.resetBtn.textContent = locale.lightingResetParams;
|
|
176
178
|
const dirLabels = {
|
|
177
179
|
left: "lightingDirLeft",
|
|
178
180
|
right: "lightingDirRight",
|
|
@@ -208,9 +210,6 @@ var lightingLocaleEn = {
|
|
|
208
210
|
lightingRim: "Rim light",
|
|
209
211
|
lightingViewPerspective: "Perspective",
|
|
210
212
|
lightingViewFront: "Front",
|
|
211
|
-
lightingResetParams: "Reset",
|
|
212
|
-
lightingSmartClose: "Close Smart mode",
|
|
213
|
-
lightingSmartToggle: "Smart mode",
|
|
214
213
|
lightingDirLeft: "Left",
|
|
215
214
|
lightingDirRight: "Right",
|
|
216
215
|
lightingDirTop: "Top",
|
|
@@ -227,9 +226,6 @@ var lightingLocaleZh = {
|
|
|
227
226
|
lightingRim: "\u8F6E\u5ED3\u5149",
|
|
228
227
|
lightingViewPerspective: "\u900F\u89C6",
|
|
229
228
|
lightingViewFront: "\u6B63\u9762",
|
|
230
|
-
lightingResetParams: "\u91CD\u7F6E\u53C2\u6570",
|
|
231
|
-
lightingSmartClose: "\u5173\u95ED\u667A\u80FD\u6A21\u5F0F",
|
|
232
|
-
lightingSmartToggle: "\u667A\u80FD\u6A21\u5F0F",
|
|
233
229
|
lightingDirLeft: "\u5DE6\u4FA7",
|
|
234
230
|
lightingDirRight: "\u53F3\u4FA7",
|
|
235
231
|
lightingDirTop: "\u9876\u90E8",
|
|
@@ -18984,22 +18980,14 @@ var LightingEditor = class _LightingEditor {
|
|
|
18984
18980
|
config;
|
|
18985
18981
|
view;
|
|
18986
18982
|
locale;
|
|
18987
|
-
smartEnabled;
|
|
18988
|
-
smartOpen;
|
|
18989
18983
|
scene;
|
|
18990
18984
|
controls;
|
|
18991
18985
|
sceneViewport;
|
|
18992
18986
|
viewToggleEl;
|
|
18993
|
-
|
|
18994
|
-
|
|
18995
|
-
|
|
18996
|
-
|
|
18997
|
-
smartToggleThumb = null;
|
|
18998
|
-
/** Host slot the React/Vue wrapper portals/teleports into. Stable
|
|
18999
|
-
* reference across smartOpen toggles — only the wrapper around it
|
|
19000
|
-
* collapses/expands. Always present even when `smartEnabled: false`
|
|
19001
|
-
* so portals don't blow up; just detached from the visible tree. */
|
|
19002
|
-
smartSlot;
|
|
18987
|
+
/** Footer slot in the controls column. Host appends Reset/Generate/
|
|
18988
|
+
* preset-save/etc. buttons here. The library renders nothing into
|
|
18989
|
+
* it — it's the same convention as the video editor's toolbar slots. */
|
|
18990
|
+
controlsFooter;
|
|
19003
18991
|
resizeObs = null;
|
|
19004
18992
|
destroyed = false;
|
|
19005
18993
|
static create(opts) {
|
|
@@ -19010,8 +18998,6 @@ var LightingEditor = class _LightingEditor {
|
|
|
19010
18998
|
this.root = opts.container;
|
|
19011
18999
|
this.config = { ...DEFAULT_LIGHTING_CONFIG, ...opts.config };
|
|
19012
19000
|
this.view = opts.view ?? "perspective";
|
|
19013
|
-
this.smartEnabled = opts.smartEnabled !== false;
|
|
19014
|
-
this.smartOpen = opts.smartOpen !== false;
|
|
19015
19001
|
this.locale = {
|
|
19016
19002
|
...mergeLocale(opts.locale),
|
|
19017
19003
|
...mergeLightingLocale(opts.locale)
|
|
@@ -19020,9 +19006,9 @@ var LightingEditor = class _LightingEditor {
|
|
|
19020
19006
|
this.root.innerHTML = "";
|
|
19021
19007
|
if (!this.root.style.position) this.root.style.position = "relative";
|
|
19022
19008
|
applyTheme(this.root, opts.theme);
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
this.root.appendChild(
|
|
19009
|
+
const body = document.createElement("div");
|
|
19010
|
+
body.className = "aicut-lighting-body";
|
|
19011
|
+
this.root.appendChild(body);
|
|
19026
19012
|
const sceneCol = document.createElement("div");
|
|
19027
19013
|
sceneCol.className = "aicut-lighting-scene-col";
|
|
19028
19014
|
this.viewToggleEl = this.buildViewToggle();
|
|
@@ -19031,7 +19017,7 @@ var LightingEditor = class _LightingEditor {
|
|
|
19031
19017
|
this.sceneViewport.className = "aicut-lighting-scene-viewport";
|
|
19032
19018
|
this.sceneViewport.setAttribute("data-testid", "aicut-lighting-scene");
|
|
19033
19019
|
sceneCol.appendChild(this.sceneViewport);
|
|
19034
|
-
|
|
19020
|
+
body.appendChild(sceneCol);
|
|
19035
19021
|
this.controls = new LightingControls(this.locale, {
|
|
19036
19022
|
onBrightnessChange: (level) => this.applyMutation({ brightness: level }),
|
|
19037
19023
|
onColorChange: (hex) => this.applyMutation({ color: hex }),
|
|
@@ -19039,20 +19025,10 @@ var LightingEditor = class _LightingEditor {
|
|
|
19039
19025
|
keyDirection: PRESET_DIRECTIONS[preset],
|
|
19040
19026
|
keyPreset: preset
|
|
19041
19027
|
}),
|
|
19042
|
-
onRimToggle: (on) => this.applyMutation({ rim: on })
|
|
19043
|
-
onReset: () => this.setConfig(DEFAULT_LIGHTING_CONFIG, "reset")
|
|
19028
|
+
onRimToggle: (on) => this.applyMutation({ rim: on })
|
|
19044
19029
|
});
|
|
19045
|
-
|
|
19046
|
-
this.
|
|
19047
|
-
this.smartSlot.className = "aicut-lighting-smart-slot";
|
|
19048
|
-
this.smartSlot.setAttribute("data-testid", "aicut-lighting-smart");
|
|
19049
|
-
if (this.smartEnabled) {
|
|
19050
|
-
this.smartWrapper = this.buildSmartWrapper();
|
|
19051
|
-
this.body.appendChild(this.smartWrapper);
|
|
19052
|
-
this.smartToggleEl = this.buildSmartToggle();
|
|
19053
|
-
this.controls.headerSlot.appendChild(this.smartToggleEl);
|
|
19054
|
-
}
|
|
19055
|
-
this.syncSmartState();
|
|
19030
|
+
body.appendChild(this.controls.root);
|
|
19031
|
+
this.controlsFooter = this.controls.footerSlot;
|
|
19056
19032
|
this.scene = new LightingScene(this.sceneViewport, this.view);
|
|
19057
19033
|
this.scene.setLightDirection(this.config.keyDirection);
|
|
19058
19034
|
this.scene.setBrightness(this.config.brightness);
|
|
@@ -19096,6 +19072,11 @@ var LightingEditor = class _LightingEditor {
|
|
|
19096
19072
|
this.opts.subjectImageUrl = url;
|
|
19097
19073
|
this.scene.setSubjectImage(url);
|
|
19098
19074
|
}
|
|
19075
|
+
/** Restore config to the safe defaults. Convenience for host's
|
|
19076
|
+
* "Reset" button — equivalent to `setConfig(DEFAULT_LIGHTING_CONFIG)`. */
|
|
19077
|
+
reset() {
|
|
19078
|
+
this.setConfig(DEFAULT_LIGHTING_CONFIG, "reset");
|
|
19079
|
+
}
|
|
19099
19080
|
setView(v) {
|
|
19100
19081
|
if (v === this.view) return;
|
|
19101
19082
|
this.view = v;
|
|
@@ -19105,42 +19086,6 @@ var LightingEditor = class _LightingEditor {
|
|
|
19105
19086
|
getView() {
|
|
19106
19087
|
return this.view;
|
|
19107
19088
|
}
|
|
19108
|
-
/** Enable/disable the entire Smart Mode feature at runtime. */
|
|
19109
|
-
setSmartEnabled(enabled) {
|
|
19110
|
-
if (enabled === this.smartEnabled) return;
|
|
19111
|
-
this.smartEnabled = enabled;
|
|
19112
|
-
if (enabled) {
|
|
19113
|
-
if (!this.smartWrapper) {
|
|
19114
|
-
this.smartWrapper = this.buildSmartWrapper();
|
|
19115
|
-
this.body.appendChild(this.smartWrapper);
|
|
19116
|
-
}
|
|
19117
|
-
if (!this.smartToggleEl) {
|
|
19118
|
-
this.smartToggleEl = this.buildSmartToggle();
|
|
19119
|
-
this.controls.headerSlot.appendChild(this.smartToggleEl);
|
|
19120
|
-
}
|
|
19121
|
-
} else {
|
|
19122
|
-
this.smartWrapper?.remove();
|
|
19123
|
-
this.smartWrapper = null;
|
|
19124
|
-
this.smartCloseBtn = null;
|
|
19125
|
-
this.smartToggleEl?.remove();
|
|
19126
|
-
this.smartToggleEl = null;
|
|
19127
|
-
this.smartToggleThumb = null;
|
|
19128
|
-
}
|
|
19129
|
-
this.syncSmartState();
|
|
19130
|
-
}
|
|
19131
|
-
isSmartEnabled() {
|
|
19132
|
-
return this.smartEnabled;
|
|
19133
|
-
}
|
|
19134
|
-
/** Open/close the smart slot drawer when enabled. No-op when disabled. */
|
|
19135
|
-
setSmartOpen(open) {
|
|
19136
|
-
if (!this.smartEnabled || open === this.smartOpen) return;
|
|
19137
|
-
this.smartOpen = open;
|
|
19138
|
-
this.syncSmartState();
|
|
19139
|
-
this.opts.onSmartOpenChange?.(open);
|
|
19140
|
-
}
|
|
19141
|
-
isSmartOpen() {
|
|
19142
|
-
return this.smartOpen;
|
|
19143
|
-
}
|
|
19144
19089
|
setTheme(theme) {
|
|
19145
19090
|
applyTheme(this.root, theme);
|
|
19146
19091
|
}
|
|
@@ -19151,10 +19096,6 @@ var LightingEditor = class _LightingEditor {
|
|
|
19151
19096
|
};
|
|
19152
19097
|
this.controls.setLocale(this.locale);
|
|
19153
19098
|
this.syncViewToggle();
|
|
19154
|
-
this.syncSmartLocale();
|
|
19155
|
-
}
|
|
19156
|
-
requestGenerate() {
|
|
19157
|
-
this.opts.onGenerate?.(this.getConfig());
|
|
19158
19099
|
}
|
|
19159
19100
|
destroy() {
|
|
19160
19101
|
if (this.destroyed) return;
|
|
@@ -19163,8 +19104,6 @@ var LightingEditor = class _LightingEditor {
|
|
|
19163
19104
|
this.scene.destroy();
|
|
19164
19105
|
this.root.innerHTML = "";
|
|
19165
19106
|
this.root.classList.remove("aicut-root", "aicut-lighting-editor");
|
|
19166
|
-
this.root.removeAttribute("data-smart-enabled");
|
|
19167
|
-
this.root.removeAttribute("data-smart-open");
|
|
19168
19107
|
}
|
|
19169
19108
|
// ---- Internal ------------------------------------------------------
|
|
19170
19109
|
applyMutation(partial) {
|
|
@@ -19214,86 +19153,6 @@ var LightingEditor = class _LightingEditor {
|
|
|
19214
19153
|
if (v === "front") btn.textContent = this.locale.lightingViewFront;
|
|
19215
19154
|
}
|
|
19216
19155
|
}
|
|
19217
|
-
/**
|
|
19218
|
-
* Build the smart slot column wrapper: × close button + the actual
|
|
19219
|
-
* host slot. Wrapper handles the drawer animation; slot reference
|
|
19220
|
-
* stays stable so portals don't have to relocate.
|
|
19221
|
-
*/
|
|
19222
|
-
buildSmartWrapper() {
|
|
19223
|
-
const wrap = document.createElement("div");
|
|
19224
|
-
wrap.className = "aicut-lighting-smart-wrapper";
|
|
19225
|
-
this.smartCloseBtn = document.createElement("button");
|
|
19226
|
-
this.smartCloseBtn.type = "button";
|
|
19227
|
-
this.smartCloseBtn.className = "aicut-lighting-smart-close";
|
|
19228
|
-
this.smartCloseBtn.title = this.locale.lightingSmartClose;
|
|
19229
|
-
this.smartCloseBtn.setAttribute("aria-label", this.locale.lightingSmartClose);
|
|
19230
|
-
this.smartCloseBtn.setAttribute("data-testid", "aicut-lighting-smart-close");
|
|
19231
|
-
this.smartCloseBtn.innerHTML = "×";
|
|
19232
|
-
this.smartCloseBtn.addEventListener("click", () => this.setSmartOpen(false));
|
|
19233
|
-
wrap.appendChild(this.smartCloseBtn);
|
|
19234
|
-
wrap.appendChild(this.smartSlot);
|
|
19235
|
-
return wrap;
|
|
19236
|
-
}
|
|
19237
|
-
/** Pill-style toggle that lives in the controls header. Re-opens
|
|
19238
|
-
* the smart drawer when the host has closed it via ×. */
|
|
19239
|
-
buildSmartToggle() {
|
|
19240
|
-
const row = document.createElement("div");
|
|
19241
|
-
row.className = "aicut-lighting-smart-toggle-row";
|
|
19242
|
-
const label = document.createElement("span");
|
|
19243
|
-
label.className = "aicut-lighting-smart-toggle-label";
|
|
19244
|
-
label.textContent = this.locale.lightingSmartToggle;
|
|
19245
|
-
row.appendChild(label);
|
|
19246
|
-
const toggle = document.createElement("div");
|
|
19247
|
-
toggle.className = "aicut-lighting-toggle aicut-lighting-smart-toggle";
|
|
19248
|
-
toggle.setAttribute("role", "switch");
|
|
19249
|
-
toggle.setAttribute("tabindex", "0");
|
|
19250
|
-
toggle.setAttribute("data-testid", "aicut-lighting-smart-toggle");
|
|
19251
|
-
toggle.title = this.locale.lightingSmartToggle;
|
|
19252
|
-
this.smartToggleThumb = document.createElement("div");
|
|
19253
|
-
this.smartToggleThumb.className = "aicut-lighting-toggle-thumb";
|
|
19254
|
-
toggle.appendChild(this.smartToggleThumb);
|
|
19255
|
-
toggle.addEventListener("click", () => this.setSmartOpen(!this.smartOpen));
|
|
19256
|
-
row.appendChild(toggle);
|
|
19257
|
-
return row;
|
|
19258
|
-
}
|
|
19259
|
-
/** Re-translate smart-related labels after a locale swap. */
|
|
19260
|
-
syncSmartLocale() {
|
|
19261
|
-
if (this.smartCloseBtn) {
|
|
19262
|
-
this.smartCloseBtn.title = this.locale.lightingSmartClose;
|
|
19263
|
-
this.smartCloseBtn.setAttribute("aria-label", this.locale.lightingSmartClose);
|
|
19264
|
-
}
|
|
19265
|
-
if (this.smartToggleEl) {
|
|
19266
|
-
const label = this.smartToggleEl.querySelector(
|
|
19267
|
-
".aicut-lighting-smart-toggle-label"
|
|
19268
|
-
);
|
|
19269
|
-
if (label) label.textContent = this.locale.lightingSmartToggle;
|
|
19270
|
-
const toggle = this.smartToggleEl.querySelector(
|
|
19271
|
-
".aicut-lighting-smart-toggle"
|
|
19272
|
-
);
|
|
19273
|
-
if (toggle) toggle.title = this.locale.lightingSmartToggle;
|
|
19274
|
-
}
|
|
19275
|
-
}
|
|
19276
|
-
/** Mirror smart state to data-* attrs + toggle thumb position.
|
|
19277
|
-
* Drives the CSS that collapses the column when closed. */
|
|
19278
|
-
syncSmartState() {
|
|
19279
|
-
this.root.setAttribute(
|
|
19280
|
-
"data-smart-enabled",
|
|
19281
|
-
this.smartEnabled ? "true" : "false"
|
|
19282
|
-
);
|
|
19283
|
-
this.root.setAttribute(
|
|
19284
|
-
"data-smart-open",
|
|
19285
|
-
this.smartOpen ? "true" : "false"
|
|
19286
|
-
);
|
|
19287
|
-
if (this.smartToggleEl) {
|
|
19288
|
-
const toggle = this.smartToggleEl.querySelector(
|
|
19289
|
-
".aicut-lighting-smart-toggle"
|
|
19290
|
-
);
|
|
19291
|
-
if (toggle) {
|
|
19292
|
-
toggle.classList.toggle("active", this.smartOpen);
|
|
19293
|
-
toggle.setAttribute("aria-checked", this.smartOpen ? "true" : "false");
|
|
19294
|
-
}
|
|
19295
|
-
}
|
|
19296
|
-
}
|
|
19297
19156
|
};
|
|
19298
19157
|
/*! Bundled license information:
|
|
19299
19158
|
|