@aicut/vue 0.1.0 → 0.2.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 +85 -27
- package/dist/LightingEditor.vue.d.ts +38 -0
- package/dist/LightingEditor.vue.d.ts.map +1 -0
- package/dist/Timeline.vue.d.ts +2 -2
- package/dist/Timeline.vue.d.ts.map +1 -1
- package/dist/VideoEditor.vue.d.ts +2 -2
- package/dist/lighting.cjs +2 -0
- package/dist/lighting.cjs.map +1 -0
- package/dist/lighting.d.ts +7 -0
- package/dist/lighting.d.ts.map +1 -0
- package/dist/lighting.js +71 -0
- package/dist/lighting.js.map +1 -0
- package/package.json +44 -3
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# @aicut/vue
|
|
2
2
|
|
|
3
|
-
Vue 3 wrapper
|
|
3
|
+
> Vue 3 wrapper for the **AiCut** video editor — canvas timeline, custom toolbar slots, theming, i18n, drop-in `<VideoEditor>`.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@aicut/vue)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
[](https://github.com/ziqiangai/AiCut)
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Install
|
|
4
12
|
|
|
5
13
|
```bash
|
|
6
14
|
pnpm add @aicut/vue @aicut/core
|
|
@@ -20,12 +28,14 @@ import "@aicut/core/styles.css";
|
|
|
20
28
|
|
|
21
29
|
const project: Project = {
|
|
22
30
|
version: 1,
|
|
23
|
-
sources: [
|
|
24
|
-
|
|
25
|
-
{ id: "t1", kind: "video", clips: [
|
|
26
|
-
{ id: "c1", sourceId: "s1", in: 0, out: 5000, start: 0 },
|
|
27
|
-
]},
|
|
31
|
+
sources: [
|
|
32
|
+
{ id: "s1", url: "/media/a.mp4", kind: "video", name: "a.mp4" },
|
|
28
33
|
],
|
|
34
|
+
tracks: [{
|
|
35
|
+
id: "t1",
|
|
36
|
+
kind: "video",
|
|
37
|
+
clips: [{ id: "c1", sourceId: "s1", in: 0, out: 5000, start: 0 }],
|
|
38
|
+
}],
|
|
29
39
|
};
|
|
30
40
|
|
|
31
41
|
const editor = ref<{ api(): EditorApi | null } | null>(null);
|
|
@@ -53,29 +63,36 @@ async function doExport(p: Project) {
|
|
|
53
63
|
</template>
|
|
54
64
|
```
|
|
55
65
|
|
|
56
|
-
The component is **uncontrolled for project state**. Restore later with
|
|
66
|
+
The component is **uncontrolled for project state**. Restore later with:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
editor.value?.api()?.setProject(saved);
|
|
70
|
+
```
|
|
57
71
|
|
|
58
72
|
## Props
|
|
59
73
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
```ts
|
|
75
|
+
interface VideoEditorProps {
|
|
76
|
+
defaultProject?: Project;
|
|
77
|
+
theme?: Theme; // CSS-var overrides; reactive
|
|
78
|
+
locale?: Partial<Locale>; // EN default; pass localeZh for ZH; reactive
|
|
79
|
+
}
|
|
80
|
+
```
|
|
65
81
|
|
|
66
82
|
## Events
|
|
67
83
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
84
|
+
```ts
|
|
85
|
+
ready (api: EditorApi)
|
|
86
|
+
change (project: Project)
|
|
87
|
+
export (project: Project) // fired by api.requestExport()
|
|
88
|
+
time-update (timeMs: number)
|
|
89
|
+
play ()
|
|
90
|
+
pause ()
|
|
91
|
+
selection-change (clipId: string | null)
|
|
92
|
+
error (error: Error)
|
|
93
|
+
```
|
|
77
94
|
|
|
78
|
-
The exposed `api()` returns the
|
|
95
|
+
The exposed `api()` returns the full **`EditorApi`** described in [@aicut/core](https://www.npmjs.com/package/@aicut/core) — `play`, `pause`, `seek`, `split`, `setProject`, `requestExport`, `setTheme`, `setLocale`, and more.
|
|
79
96
|
|
|
80
97
|
## Theming
|
|
81
98
|
|
|
@@ -93,8 +110,6 @@ The exposed `api()` returns the same `EditorApi` instance described in [`@aicut/
|
|
|
93
110
|
/>
|
|
94
111
|
```
|
|
95
112
|
|
|
96
|
-
The `theme` prop is reactive — swap the binding and the editor calls `setTheme` internally.
|
|
97
|
-
|
|
98
113
|
## i18n
|
|
99
114
|
|
|
100
115
|
```vue
|
|
@@ -103,7 +118,9 @@ import { ref, computed } from "vue";
|
|
|
103
118
|
import { VideoEditor, localeEn, localeZh, type Locale } from "@aicut/vue";
|
|
104
119
|
|
|
105
120
|
const lang = ref<"en" | "zh">("en");
|
|
106
|
-
const locale = computed<Locale>(() =>
|
|
121
|
+
const locale = computed<Locale>(() =>
|
|
122
|
+
lang.value === "zh" ? localeZh : localeEn,
|
|
123
|
+
);
|
|
107
124
|
</script>
|
|
108
125
|
|
|
109
126
|
<template>
|
|
@@ -111,6 +128,47 @@ const locale = computed<Locale>(() => (lang.value === "zh" ? localeZh : localeEn
|
|
|
111
128
|
</template>
|
|
112
129
|
```
|
|
113
130
|
|
|
131
|
+
`locale` swap re-titles the toolbar and re-paints canvas labels in place.
|
|
132
|
+
|
|
133
|
+
## `<LightingEditor>` (opt-in sub-entry)
|
|
134
|
+
|
|
135
|
+
A 3D lighting director for AI relighting flows — separate sub-entry; three.js bundles only here.
|
|
136
|
+
|
|
137
|
+
```vue
|
|
138
|
+
<script setup lang="ts">
|
|
139
|
+
import { ref } from "vue";
|
|
140
|
+
import { LightingEditor, type LightingConfig } from "@aicut/vue/lighting";
|
|
141
|
+
import "@aicut/core/styles.css";
|
|
142
|
+
|
|
143
|
+
const editor = ref<{ api(): any } | null>(null);
|
|
144
|
+
|
|
145
|
+
function onChange(cfg: LightingConfig) {
|
|
146
|
+
console.log(cfg);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function onGenerate(cfg: LightingConfig) {
|
|
150
|
+
fetch("/relight", { method: "POST", body: JSON.stringify(cfg) });
|
|
151
|
+
}
|
|
152
|
+
</script>
|
|
153
|
+
|
|
154
|
+
<template>
|
|
155
|
+
<LightingEditor
|
|
156
|
+
ref="editor"
|
|
157
|
+
subject-image-url="/frames/subject.jpg"
|
|
158
|
+
smart-enabled
|
|
159
|
+
@change="onChange"
|
|
160
|
+
@generate="onGenerate"
|
|
161
|
+
>
|
|
162
|
+
<template #smart>
|
|
163
|
+
<textarea placeholder="Describe the mood…" />
|
|
164
|
+
<button @click="editor?.api()?.requestGenerate()">Generate</button>
|
|
165
|
+
</template>
|
|
166
|
+
</LightingEditor>
|
|
167
|
+
</template>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Props: `subjectImageUrl`, `defaultConfig`, `defaultView`, `theme`, `locale`, `smartEnabled`, `smartOpen`. Events: `ready`, `change`, `generate`. Use the named `<slot name="smart">` for the smart-mode panel content.
|
|
171
|
+
|
|
114
172
|
## Standalone `<Timeline>`
|
|
115
173
|
|
|
116
174
|
```vue
|
|
@@ -131,6 +189,6 @@ const picked = ref(0);
|
|
|
131
189
|
</template>
|
|
132
190
|
```
|
|
133
191
|
|
|
134
|
-
|
|
192
|
+
---
|
|
135
193
|
|
|
136
|
-
|
|
194
|
+
[Full docs & demo](https://github.com/ziqiangai/AiCut) · [@aicut/core](https://www.npmjs.com/package/@aicut/core) · [@aicut/react](https://www.npmjs.com/package/@aicut/react)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LightingEditor as CoreLightingEditor, type LightingConfig, type LightingEditorOptions, type LightingView } from "@aicut/core/lighting";
|
|
2
|
+
import type { Theme } from "@aicut/core";
|
|
3
|
+
/**
|
|
4
|
+
* Vue 3 wrapper around the core `LightingEditor`. Same shape as the
|
|
5
|
+
* React component: `defaultConfig` is read once on mount, `theme` /
|
|
6
|
+
* `locale` / `subjectImageUrl` are reactive, the host AI UI goes into
|
|
7
|
+
* a `<slot name="smart">` that Vue teleports into the smart slot DOM.
|
|
8
|
+
*/
|
|
9
|
+
type __VLS_Props = {
|
|
10
|
+
subjectImageUrl?: string;
|
|
11
|
+
defaultConfig?: Partial<LightingConfig>;
|
|
12
|
+
defaultView?: LightingView;
|
|
13
|
+
theme?: Theme;
|
|
14
|
+
locale?: LightingEditorOptions["locale"];
|
|
15
|
+
};
|
|
16
|
+
declare var __VLS_5: {};
|
|
17
|
+
type __VLS_Slots = {} & {
|
|
18
|
+
smart?: (props: typeof __VLS_5) => any;
|
|
19
|
+
};
|
|
20
|
+
declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {
|
|
21
|
+
api: () => CoreLightingEditor | null;
|
|
22
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
23
|
+
ready: (api: CoreLightingEditor) => any;
|
|
24
|
+
change: (cfg: LightingConfig) => any;
|
|
25
|
+
generate: (cfg: LightingConfig) => any;
|
|
26
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
27
|
+
onReady?: ((api: CoreLightingEditor) => any) | undefined;
|
|
28
|
+
onChange?: ((cfg: LightingConfig) => any) | undefined;
|
|
29
|
+
onGenerate?: ((cfg: LightingConfig) => any) | undefined;
|
|
30
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
31
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
32
|
+
export default _default;
|
|
33
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
34
|
+
new (): {
|
|
35
|
+
$slots: S;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=LightingEditor.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LightingEditor.vue.d.ts","sourceRoot":"","sources":["../src/LightingEditor.vue"],"names":[],"mappings":"AA0FA,OAAO,EACL,cAAc,IAAI,kBAAkB,EACpC,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;GAKG;AACH,KAAK,WAAW,GAAG;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,CAAC,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC;CAC1C,CAAC;AAyFF,QAAA,IAAI,OAAO,IAAW,CAAE;AACxB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAuB7C,QAAA,MAAM,eAAe;eA1DV,kBAAkB,GAAG,IAAI;;;;;;;;;kFAkElC,CAAC;wBACkB,eAAe,CAAC,OAAO,eAAe,EAAE,WAAW,CAAC;AAAzE,wBAA0E;AAQ1E,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
|
package/dist/Timeline.vue.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ type __VLS_Props = {
|
|
|
18
18
|
declare const _default: import("vue").DefineComponent<__VLS_Props, {
|
|
19
19
|
api: () => CoreTimeline | null;
|
|
20
20
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
21
|
+
change: (project: Project) => any;
|
|
21
22
|
seek: (timeMs: number) => any;
|
|
22
23
|
selectClip: (clipId: string | null) => any;
|
|
23
24
|
scaleChange: (pxPerSec: number) => any;
|
|
@@ -26,8 +27,8 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {
|
|
|
26
27
|
trackId?: string;
|
|
27
28
|
}) => any;
|
|
28
29
|
resizeClip: (clipId: string, edits: Partial<Pick<Clip, "in" | "out" | "start">>) => any;
|
|
29
|
-
change: (project: Project) => any;
|
|
30
30
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
31
|
+
onChange?: ((project: Project) => any) | undefined;
|
|
31
32
|
onSeek?: ((timeMs: number) => any) | undefined;
|
|
32
33
|
onSelectClip?: ((clipId: string | null) => any) | undefined;
|
|
33
34
|
onScaleChange?: ((pxPerSec: number) => any) | undefined;
|
|
@@ -36,7 +37,6 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {
|
|
|
36
37
|
trackId?: string;
|
|
37
38
|
}) => any) | undefined;
|
|
38
39
|
onResizeClip?: ((clipId: string, edits: Partial<Pick<Clip, "in" | "out" | "start">>) => any) | undefined;
|
|
39
|
-
onChange?: ((project: Project) => any) | undefined;
|
|
40
40
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
41
41
|
export default _default;
|
|
42
42
|
//# sourceMappingURL=Timeline.vue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Timeline.vue.d.ts","sourceRoot":"","sources":["../src/Timeline.vue"],"names":[],"mappings":"AAwFA,OAAO,EACL,QAAQ,IAAI,YAAY,EACxB,KAAK,IAAI,EACT,KAAK,MAAM,EACX,KAAK,EAAE,EACP,KAAK,OAAO,EACb,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,EAAE,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B,CAAC;;eAuDS,YAAY,GAAG,IAAI
|
|
1
|
+
{"version":3,"file":"Timeline.vue.d.ts","sourceRoot":"","sources":["../src/Timeline.vue"],"names":[],"mappings":"AAwFA,OAAO,EACL,QAAQ,IAAI,YAAY,EACxB,KAAK,IAAI,EACT,KAAK,MAAM,EACX,KAAK,EAAE,EACP,KAAK,OAAO,EACb,MAAM,aAAa,CAAC;AAErB;;;;GAIG;AACH,KAAK,WAAW,GAAG;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,EAAE,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B,CAAC;;eAuDS,YAAY,GAAG,IAAI;;;;;;;gBAhDoB,EAAE;kBAAY,MAAM;;;;;;;;;gBAApB,EAAE;kBAAY,MAAM;;;;AAwFtE,wBAQG"}
|
|
@@ -14,8 +14,8 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {
|
|
|
14
14
|
/** Returns the underlying core API or null if not yet mounted. */
|
|
15
15
|
api: () => EditorApi | null;
|
|
16
16
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
|
-
change: (project: Project) => any;
|
|
18
17
|
ready: (api: EditorApi) => any;
|
|
18
|
+
change: (project: Project) => any;
|
|
19
19
|
export: (project: Project) => any;
|
|
20
20
|
timeUpdate: (timeMs: number) => any;
|
|
21
21
|
play: () => any;
|
|
@@ -23,8 +23,8 @@ declare const _default: import("vue").DefineComponent<__VLS_Props, {
|
|
|
23
23
|
selectionChange: (clipId: string | null) => any;
|
|
24
24
|
error: (error: Error) => any;
|
|
25
25
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
26
|
-
onChange?: ((project: Project) => any) | undefined;
|
|
27
26
|
onReady?: ((api: EditorApi) => any) | undefined;
|
|
27
|
+
onChange?: ((project: Project) => any) | undefined;
|
|
28
28
|
onExport?: ((project: Project) => any) | undefined;
|
|
29
29
|
onTimeUpdate?: ((timeMs: number) => any) | undefined;
|
|
30
30
|
onPlay?: (() => any) | undefined;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),o=require("@aicut/core/lighting"),s=e.defineComponent({__name:"LightingEditor",props:{subjectImageUrl:{},defaultConfig:{},defaultView:{},theme:{},locale:{}},emits:["ready","change","generate"],setup(c,{expose:g,emit:u}){const r=c,l=u,i=e.useTemplateRef("host");let t=null;const a=e.ref(null);return e.onMounted(()=>{i.value&&(t=o.LightingEditor.create({container:i.value,subjectImageUrl:r.subjectImageUrl,config:r.defaultConfig,view:r.defaultView,theme:r.theme,locale:r.locale,onChange:n=>l("change",n),onGenerate:n=>l("generate",n)}),a.value=t.smartSlot,l("ready",t))}),e.watch(()=>r.theme,n=>{n&&t&&t.setTheme(n)}),e.watch(()=>r.locale,n=>{n&&t&&t.setLocale(n)}),e.watch(()=>r.subjectImageUrl,n=>{n&&t&&t.setSubjectImage(n)}),e.onBeforeUnmount(()=>{t==null||t.destroy(),t=null,a.value=null}),g({api:()=>t}),(n,m)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"host",ref:i,"data-aicut-lighting-host":""},[a.value?(e.openBlock(),e.createBlock(e.Teleport,{key:0,to:a.value},[e.renderSlot(n.$slots,"smart")],8,["to"])):e.createCommentVNode("",!0)],512))}});Object.defineProperty(exports,"DEFAULT_LIGHTING_CONFIG",{enumerable:!0,get:()=>o.DEFAULT_LIGHTING_CONFIG});Object.defineProperty(exports,"PRESET_DIRECTIONS",{enumerable:!0,get:()=>o.PRESET_DIRECTIONS});Object.defineProperty(exports,"lightingLocaleEn",{enumerable:!0,get:()=>o.lightingLocaleEn});Object.defineProperty(exports,"lightingLocaleZh",{enumerable:!0,get:()=>o.lightingLocaleZh});Object.defineProperty(exports,"mergeLightingLocale",{enumerable:!0,get:()=>o.mergeLightingLocale});Object.defineProperty(exports,"snapToPreset",{enumerable:!0,get:()=>o.snapToPreset});exports.LightingEditor=s;
|
|
2
|
+
//# sourceMappingURL=lighting.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lighting.cjs","sources":["../src/LightingEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from \"vue\";\nimport {\n LightingEditor as CoreLightingEditor,\n type LightingConfig,\n type LightingEditorOptions,\n type LightingView,\n} from \"@aicut/core/lighting\";\nimport type { Theme } from \"@aicut/core\";\n\n/**\n * Vue 3 wrapper around the core `LightingEditor`. Same shape as the\n * React component: `defaultConfig` is read once on mount, `theme` /\n * `locale` / `subjectImageUrl` are reactive, the host AI UI goes into\n * a `<slot name=\"smart\">` that Vue teleports into the smart slot DOM.\n */\nconst props = defineProps<{\n subjectImageUrl?: string;\n defaultConfig?: Partial<LightingConfig>;\n defaultView?: LightingView;\n theme?: Theme;\n locale?: LightingEditorOptions[\"locale\"];\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\", api: CoreLightingEditor): void;\n (e: \"change\", cfg: LightingConfig): void;\n (e: \"generate\", cfg: LightingConfig): void;\n}>();\n\nconst host = useTemplateRef<HTMLDivElement>(\"host\");\nlet editor: CoreLightingEditor | null = null;\nconst smartSlot = ref<HTMLElement | null>(null);\n\nonMounted(() => {\n if (!host.value) return;\n editor = CoreLightingEditor.create({\n container: host.value,\n subjectImageUrl: props.subjectImageUrl,\n config: props.defaultConfig,\n view: props.defaultView,\n theme: props.theme,\n locale: props.locale,\n onChange: (cfg) => emit(\"change\", cfg),\n onGenerate: (cfg) => emit(\"generate\", cfg),\n });\n smartSlot.value = editor.smartSlot;\n emit(\"ready\", editor);\n});\n\nwatch(\n () => props.theme,\n (theme) => {\n if (theme && editor) editor.setTheme(theme);\n },\n);\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && editor) editor.setLocale(locale);\n },\n);\nwatch(\n () => props.subjectImageUrl,\n (url) => {\n if (url && editor) editor.setSubjectImage(url);\n },\n);\n\nonBeforeUnmount(() => {\n editor?.destroy();\n editor = null;\n smartSlot.value = null;\n});\n\ndefineExpose({\n api: (): CoreLightingEditor | null => editor,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-lighting-host=\"\">\n <Teleport v-if=\"smartSlot\" :to=\"smartSlot\">\n <slot name=\"smart\" />\n </Teleport>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","host","useTemplateRef","editor","smartSlot","ref","onMounted","CoreLightingEditor","cfg","watch","theme","locale","url","onBeforeUnmount","__expose","_createElementBlock","_createBlock","_Teleport","_renderSlot","_ctx"],"mappings":"mUAgBA,MAAMA,EAAQC,EAQRC,EAAOC,EAMPC,EAAOC,EAAAA,eAA+B,MAAM,EAClD,IAAIC,EAAoC,KACxC,MAAMC,EAAYC,EAAAA,IAAwB,IAAI,EAE9CC,OAAAA,EAAAA,UAAU,IAAM,CACTL,EAAK,QACVE,EAASI,EAAAA,eAAmB,OAAO,CACjC,UAAWN,EAAK,MAChB,gBAAiBJ,EAAM,gBACvB,OAAQA,EAAM,cACd,KAAMA,EAAM,YACZ,MAAOA,EAAM,MACb,OAAQA,EAAM,OACd,SAAWW,GAAQT,EAAK,SAAUS,CAAG,EACrC,WAAaA,GAAQT,EAAK,WAAYS,CAAG,CAAA,CAC1C,EACDJ,EAAU,MAAQD,EAAO,UACzBJ,EAAK,QAASI,CAAM,EACtB,CAAC,EAEDM,EAAAA,MACE,IAAMZ,EAAM,MACXa,GAAU,CACLA,GAASP,GAAQA,EAAO,SAASO,CAAK,CAC5C,CAAA,EAEFD,EAAAA,MACE,IAAMZ,EAAM,OACXc,GAAW,CACNA,GAAUR,GAAQA,EAAO,UAAUQ,CAAM,CAC/C,CAAA,EAEFF,EAAAA,MACE,IAAMZ,EAAM,gBACXe,GAAQ,CACHA,GAAOT,GAAQA,EAAO,gBAAgBS,CAAG,CAC/C,CAAA,EAGFC,EAAAA,gBAAgB,IAAM,CACpBV,GAAA,MAAAA,EAAQ,UACRA,EAAS,KACTC,EAAU,MAAQ,IACpB,CAAC,EAEDU,EAAa,CACX,IAAK,IAAiCX,CAAA,CACvC,wBAICY,EAAAA,mBAIM,MAAA,SAJG,OAAJ,IAAId,EAAO,2BAAyB,EAAA,GACvBG,EAAA,qBAAhBY,EAAAA,YAEWC,EAAAA,SAAA,OAFiB,GAAIb,EAAA,KAAA,GAC9Bc,aAAqBC,EAAA,OAAA,OAAA,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aicut/vue/lighting — separate entry that pulls three.js.
|
|
3
|
+
*/
|
|
4
|
+
export { default as LightingEditor } from "./LightingEditor.vue";
|
|
5
|
+
export { DEFAULT_LIGHTING_CONFIG, PRESET_DIRECTIONS, lightingLocaleEn, lightingLocaleZh, mergeLightingLocale, snapToPreset, } from "@aicut/core/lighting";
|
|
6
|
+
export type { KeyPreset, LightingConfig, LightingEditorOptions, LightingLocale, LightingView, } from "@aicut/core/lighting";
|
|
7
|
+
//# sourceMappingURL=lighting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lighting.d.ts","sourceRoot":"","sources":["../src/lighting.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,GACb,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,SAAS,EACT,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,YAAY,GACb,MAAM,sBAAsB,CAAC"}
|
package/dist/lighting.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { defineComponent as g, useTemplateRef as u, ref as f, onMounted as h, watch as r, onBeforeUnmount as p, openBlock as i, createElementBlock as d, createBlock as I, Teleport as L, renderSlot as E, createCommentVNode as _ } from "vue";
|
|
2
|
+
import { LightingEditor as v } from "@aicut/core/lighting";
|
|
3
|
+
import { DEFAULT_LIGHTING_CONFIG as k, PRESET_DIRECTIONS as y, lightingLocaleEn as w, lightingLocaleZh as B, mergeLightingLocale as G, snapToPreset as N } from "@aicut/core/lighting";
|
|
4
|
+
const U = /* @__PURE__ */ g({
|
|
5
|
+
__name: "LightingEditor",
|
|
6
|
+
props: {
|
|
7
|
+
subjectImageUrl: {},
|
|
8
|
+
defaultConfig: {},
|
|
9
|
+
defaultView: {},
|
|
10
|
+
theme: {},
|
|
11
|
+
locale: {}
|
|
12
|
+
},
|
|
13
|
+
emits: ["ready", "change", "generate"],
|
|
14
|
+
setup(c, { expose: s, emit: m }) {
|
|
15
|
+
const o = c, n = m, l = u("host");
|
|
16
|
+
let e = null;
|
|
17
|
+
const a = f(null);
|
|
18
|
+
return h(() => {
|
|
19
|
+
l.value && (e = v.create({
|
|
20
|
+
container: l.value,
|
|
21
|
+
subjectImageUrl: o.subjectImageUrl,
|
|
22
|
+
config: o.defaultConfig,
|
|
23
|
+
view: o.defaultView,
|
|
24
|
+
theme: o.theme,
|
|
25
|
+
locale: o.locale,
|
|
26
|
+
onChange: (t) => n("change", t),
|
|
27
|
+
onGenerate: (t) => n("generate", t)
|
|
28
|
+
}), a.value = e.smartSlot, n("ready", e));
|
|
29
|
+
}), r(
|
|
30
|
+
() => o.theme,
|
|
31
|
+
(t) => {
|
|
32
|
+
t && e && e.setTheme(t);
|
|
33
|
+
}
|
|
34
|
+
), r(
|
|
35
|
+
() => o.locale,
|
|
36
|
+
(t) => {
|
|
37
|
+
t && e && e.setLocale(t);
|
|
38
|
+
}
|
|
39
|
+
), r(
|
|
40
|
+
() => o.subjectImageUrl,
|
|
41
|
+
(t) => {
|
|
42
|
+
t && e && e.setSubjectImage(t);
|
|
43
|
+
}
|
|
44
|
+
), p(() => {
|
|
45
|
+
e == null || e.destroy(), e = null, a.value = null;
|
|
46
|
+
}), s({
|
|
47
|
+
api: () => e
|
|
48
|
+
}), (t, T) => (i(), d("div", {
|
|
49
|
+
ref_key: "host",
|
|
50
|
+
ref: l,
|
|
51
|
+
"data-aicut-lighting-host": ""
|
|
52
|
+
}, [
|
|
53
|
+
a.value ? (i(), I(L, {
|
|
54
|
+
key: 0,
|
|
55
|
+
to: a.value
|
|
56
|
+
}, [
|
|
57
|
+
E(t.$slots, "smart")
|
|
58
|
+
], 8, ["to"])) : _("", !0)
|
|
59
|
+
], 512));
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
export {
|
|
63
|
+
k as DEFAULT_LIGHTING_CONFIG,
|
|
64
|
+
U as LightingEditor,
|
|
65
|
+
y as PRESET_DIRECTIONS,
|
|
66
|
+
w as lightingLocaleEn,
|
|
67
|
+
B as lightingLocaleZh,
|
|
68
|
+
G as mergeLightingLocale,
|
|
69
|
+
N as snapToPreset
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=lighting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lighting.js","sources":["../src/LightingEditor.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from \"vue\";\nimport {\n LightingEditor as CoreLightingEditor,\n type LightingConfig,\n type LightingEditorOptions,\n type LightingView,\n} from \"@aicut/core/lighting\";\nimport type { Theme } from \"@aicut/core\";\n\n/**\n * Vue 3 wrapper around the core `LightingEditor`. Same shape as the\n * React component: `defaultConfig` is read once on mount, `theme` /\n * `locale` / `subjectImageUrl` are reactive, the host AI UI goes into\n * a `<slot name=\"smart\">` that Vue teleports into the smart slot DOM.\n */\nconst props = defineProps<{\n subjectImageUrl?: string;\n defaultConfig?: Partial<LightingConfig>;\n defaultView?: LightingView;\n theme?: Theme;\n locale?: LightingEditorOptions[\"locale\"];\n}>();\n\nconst emit = defineEmits<{\n (e: \"ready\", api: CoreLightingEditor): void;\n (e: \"change\", cfg: LightingConfig): void;\n (e: \"generate\", cfg: LightingConfig): void;\n}>();\n\nconst host = useTemplateRef<HTMLDivElement>(\"host\");\nlet editor: CoreLightingEditor | null = null;\nconst smartSlot = ref<HTMLElement | null>(null);\n\nonMounted(() => {\n if (!host.value) return;\n editor = CoreLightingEditor.create({\n container: host.value,\n subjectImageUrl: props.subjectImageUrl,\n config: props.defaultConfig,\n view: props.defaultView,\n theme: props.theme,\n locale: props.locale,\n onChange: (cfg) => emit(\"change\", cfg),\n onGenerate: (cfg) => emit(\"generate\", cfg),\n });\n smartSlot.value = editor.smartSlot;\n emit(\"ready\", editor);\n});\n\nwatch(\n () => props.theme,\n (theme) => {\n if (theme && editor) editor.setTheme(theme);\n },\n);\nwatch(\n () => props.locale,\n (locale) => {\n if (locale && editor) editor.setLocale(locale);\n },\n);\nwatch(\n () => props.subjectImageUrl,\n (url) => {\n if (url && editor) editor.setSubjectImage(url);\n },\n);\n\nonBeforeUnmount(() => {\n editor?.destroy();\n editor = null;\n smartSlot.value = null;\n});\n\ndefineExpose({\n api: (): CoreLightingEditor | null => editor,\n});\n</script>\n\n<template>\n <div ref=\"host\" data-aicut-lighting-host=\"\">\n <Teleport v-if=\"smartSlot\" :to=\"smartSlot\">\n <slot name=\"smart\" />\n </Teleport>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","host","useTemplateRef","editor","smartSlot","ref","onMounted","CoreLightingEditor","cfg","watch","theme","locale","url","onBeforeUnmount","__expose","_createElementBlock","_createBlock","_Teleport","_renderSlot","_ctx"],"mappings":";;;;;;;;;;;;;;AAgBA,UAAMA,IAAQC,GAQRC,IAAOC,GAMPC,IAAOC,EAA+B,MAAM;AAClD,QAAIC,IAAoC;AACxC,UAAMC,IAAYC,EAAwB,IAAI;AAE9C,WAAAC,EAAU,MAAM;AACd,MAAKL,EAAK,UACVE,IAASI,EAAmB,OAAO;AAAA,QACjC,WAAWN,EAAK;AAAA,QAChB,iBAAiBJ,EAAM;AAAA,QACvB,QAAQA,EAAM;AAAA,QACd,MAAMA,EAAM;AAAA,QACZ,OAAOA,EAAM;AAAA,QACb,QAAQA,EAAM;AAAA,QACd,UAAU,CAACW,MAAQT,EAAK,UAAUS,CAAG;AAAA,QACrC,YAAY,CAACA,MAAQT,EAAK,YAAYS,CAAG;AAAA,MAAA,CAC1C,GACDJ,EAAU,QAAQD,EAAO,WACzBJ,EAAK,SAASI,CAAM;AAAA,IACtB,CAAC,GAEDM;AAAA,MACE,MAAMZ,EAAM;AAAA,MACZ,CAACa,MAAU;AACT,QAAIA,KAASP,KAAQA,EAAO,SAASO,CAAK;AAAA,MAC5C;AAAA,IAAA,GAEFD;AAAA,MACE,MAAMZ,EAAM;AAAA,MACZ,CAACc,MAAW;AACV,QAAIA,KAAUR,KAAQA,EAAO,UAAUQ,CAAM;AAAA,MAC/C;AAAA,IAAA,GAEFF;AAAA,MACE,MAAMZ,EAAM;AAAA,MACZ,CAACe,MAAQ;AACP,QAAIA,KAAOT,KAAQA,EAAO,gBAAgBS,CAAG;AAAA,MAC/C;AAAA,IAAA,GAGFC,EAAgB,MAAM;AACpB,MAAAV,KAAA,QAAAA,EAAQ,WACRA,IAAS,MACTC,EAAU,QAAQ;AAAA,IACpB,CAAC,GAEDU,EAAa;AAAA,MACX,KAAK,MAAiCX;AAAA,IAAA,CACvC,mBAICY,EAIM,OAAA;AAAA,eAJG;AAAA,MAAJ,KAAId;AAAA,MAAO,4BAAyB;AAAA,IAAA;MACvBG,EAAA,cAAhBY,EAEWC,GAAA;AAAA;QAFiB,IAAIb,EAAA;AAAA,MAAA;QAC9Bc,EAAqBC,EAAA,QAAA,OAAA;AAAA,MAAA;;;;"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aicut/vue",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Vue 3 wrapper for the AiCut video editor — thin declarative
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Vue 3 wrapper for the AiCut video editor + lighting picker — thin declarative shells over @aicut/core.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"author": "ziqiang <ziqiangytu@gmail.com>",
|
|
7
|
+
"homepage": "https://github.com/ziqiangai/AiCut#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/ziqiangai/AiCut.git",
|
|
11
|
+
"directory": "packages/vue"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/ziqiangai/AiCut/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"video-editor",
|
|
18
|
+
"video-editing",
|
|
19
|
+
"vue",
|
|
20
|
+
"vue3",
|
|
21
|
+
"vue-component",
|
|
22
|
+
"timeline",
|
|
23
|
+
"timeline-editor",
|
|
24
|
+
"nle",
|
|
25
|
+
"video-cutter",
|
|
26
|
+
"video-clip",
|
|
27
|
+
"canvas",
|
|
28
|
+
"video",
|
|
29
|
+
"editor",
|
|
30
|
+
"mp4",
|
|
31
|
+
"component",
|
|
32
|
+
"capcut",
|
|
33
|
+
"premiere",
|
|
34
|
+
"final-cut",
|
|
35
|
+
"davinci",
|
|
36
|
+
"imovie",
|
|
37
|
+
"veed",
|
|
38
|
+
"filmora",
|
|
39
|
+
"lighting",
|
|
40
|
+
"three.js"
|
|
41
|
+
],
|
|
6
42
|
"type": "module",
|
|
7
43
|
"main": "./dist/index.cjs",
|
|
8
44
|
"module": "./dist/index.js",
|
|
@@ -12,6 +48,11 @@
|
|
|
12
48
|
"types": "./dist/index.d.ts",
|
|
13
49
|
"import": "./dist/index.js",
|
|
14
50
|
"require": "./dist/index.cjs"
|
|
51
|
+
},
|
|
52
|
+
"./lighting": {
|
|
53
|
+
"types": "./dist/lighting.d.ts",
|
|
54
|
+
"import": "./dist/lighting.js",
|
|
55
|
+
"require": "./dist/lighting.cjs"
|
|
15
56
|
}
|
|
16
57
|
},
|
|
17
58
|
"files": [
|
|
@@ -19,7 +60,7 @@
|
|
|
19
60
|
"README.md"
|
|
20
61
|
],
|
|
21
62
|
"dependencies": {
|
|
22
|
-
"@aicut/core": "0.
|
|
63
|
+
"@aicut/core": "0.2.0"
|
|
23
64
|
},
|
|
24
65
|
"peerDependencies": {
|
|
25
66
|
"vue": "^3.4.0"
|