Skip to content

Commit cea3b42

Browse files
committed
[add] encapsulation to a plugin
1 parent 02f0150 commit cea3b42

File tree

7 files changed

+200
-81
lines changed

7 files changed

+200
-81
lines changed

src/components/VueTrailerScene.ts

Lines changed: 73 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable vue/require-default-prop */
12
import type { DefineComponent, StyleValue } from "vue";
23
import {
34
h,
@@ -10,8 +11,12 @@ import {
1011
ref,
1112
watch,
1213
} from "vue";
13-
import { SceneProps } from "../types";
14-
import { InjectionSpotlightOptions } from "../constants";
14+
import { SceneProps, ResolvedSceneProps, GlobalOptions } from "../types";
15+
import {
16+
InjectionGlobalOptions,
17+
InjectionSpotlightOptions,
18+
} from "../constants";
19+
import { defaultOptions } from "../options";
1520
import { useAct } from "../composables/act";
1621
import { useBodyScrollFixed } from "../composables/bodyScrollFixed";
1722
import { useWindowSize, useElementBounding } from "@vueuse/core";
@@ -31,63 +36,87 @@ export const VueTrailerScene = defineComponent({
3136

3237
cameraFollow: {
3338
type: Boolean,
34-
default: true,
39+
required: false,
40+
default: undefined,
3541
},
3642
cameraFollowOptions: {
3743
type: Object as () => ScrollIntoViewOptions,
38-
default: () => ({
39-
behavior: "smooth",
40-
block: "start",
41-
inline: "nearest",
42-
}),
44+
required: false,
4345
},
4446
cameraFixAfterFollow: {
4547
type: Boolean,
46-
default: true,
48+
required: false,
49+
default: undefined,
4750
},
4851

4952
voiceOverPlacement: {
5053
type: String as () => "top" | "bottom" | "left" | "right",
51-
default: "left",
54+
required: false,
5255
},
5356
voiceOverAutoPlacement: {
5457
type: Boolean,
55-
default: true,
58+
required: false,
59+
default: undefined,
5660
},
5761
voiceOverAlign: {
5862
type: String as () => "start" | "center" | "end",
59-
default: "center",
63+
required: false,
6064
},
6165
voiceOverWidth: {
6266
type: Number,
63-
default: 300,
67+
required: false,
6468
},
6569
voiceOverTitle: {
6670
type: String,
67-
default: "Voice Over",
71+
required: false,
6872
},
6973
voiceOverContent: {
7074
type: String,
71-
default:
72-
"It takes a strong man to save himself,\nand a great man to save another.",
75+
required: false,
7376
},
7477
voiceOverPrevButtonText: {
7578
type: String,
76-
default: "Back",
79+
required: false,
7780
},
7881
voiceOverNextButtonText: {
7982
type: String,
80-
default: "Next",
83+
required: false,
8184
},
8285
voiceOverDoneButtonText: {
8386
type: String,
84-
default: "Done",
87+
required: false,
8588
},
8689
},
8790
setup(props, { slots }) {
8891
const spotlight = ref<HTMLElement | null>(null);
8992
const voiceOver = ref<HTMLElement | null>(null);
9093

94+
const globalOptions = inject(InjectionGlobalOptions, {});
95+
const spotlightOptions = inject(InjectionSpotlightOptions);
96+
const localOptions = ref<GlobalOptions>({});
97+
const options = computed<ResolvedSceneProps>(() => ({
98+
...defaultOptions,
99+
...globalOptions,
100+
...spotlightOptions,
101+
...localOptions.value,
102+
actName: props.actName,
103+
sceneNumber: props.sceneNumber,
104+
}));
105+
106+
function setLocalOptions(options: GlobalOptions = {}) {
107+
localOptions.value = JSON.parse(JSON.stringify(options));
108+
}
109+
110+
watch(
111+
() => props,
112+
async () => {
113+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
114+
const { actName, sceneNumber, ...options } = props;
115+
setLocalOptions(options);
116+
},
117+
{ deep: true, immediate: true },
118+
);
119+
91120
const {
92121
actorWalkIn,
93122
currentActName,
@@ -102,7 +131,7 @@ export const VueTrailerScene = defineComponent({
102131
prevScene,
103132
jumpToScene,
104133
cut,
105-
} = useAct(props.actName);
134+
} = useAct(options.value.actName);
106135

107136
const slotProp = reactive({
108137
hasPrevScene,
@@ -120,22 +149,22 @@ export const VueTrailerScene = defineComponent({
120149

121150
const isCurrentScene = computed(() => {
122151
return (
123-
currentActName.value === props.actName &&
124-
currentSceneNumber.value === props.sceneNumber
152+
currentActName.value === options.value.actName &&
153+
currentSceneNumber.value === options.value.sceneNumber
125154
);
126155
});
127156

128157
const defaultVoiceOverStyle = computed<StyleValue>(() => {
129158
return {
130-
width: `${props.voiceOverWidth}px`,
159+
width: `${options.value.voiceOverWidth}px`,
131160
};
132161
});
133162

134-
const spotlightConfig = inject(InjectionSpotlightOptions);
135163
const spotlightStyle = computed<StyleValue>(() => {
136164
return {
137-
inset: `-${spotlightConfig?.padding || 0}px`,
138-
borderRadius: `${spotlightConfig?.borderRadius || 0}px`,
165+
inset: `-${options.value.spotlightPadding || 0}px`,
166+
borderRadius: `${options.value.spotlightBorderRadius || 0}px`,
167+
overflow: "none",
139168
};
140169
});
141170

@@ -151,10 +180,11 @@ export const VueTrailerScene = defineComponent({
151180
const { width: windowWidth, height: windowHeight } = useWindowSize();
152181

153182
const autoVoiceOverPlacement = computed<string>(() => {
154-
if (!props.voiceOverAutoPlacement) return props.voiceOverPlacement;
183+
if (!options.value.voiceOverAutoPlacement)
184+
return options.value.voiceOverPlacement;
155185

156186
let possiblePositions: string[] = [];
157-
switch (props.voiceOverPlacement) {
187+
switch (options.value.voiceOverPlacement) {
158188
case "top":
159189
possiblePositions = ["top", "bottom", "left", "right"];
160190
break;
@@ -208,7 +238,7 @@ export const VueTrailerScene = defineComponent({
208238
);
209239
}
210240

211-
return possiblePositions[0] || props.voiceOverPlacement;
241+
return possiblePositions[0] || options.value.voiceOverPlacement;
212242
});
213243

214244
const isScrollFixed = ref(false);
@@ -219,7 +249,9 @@ export const VueTrailerScene = defineComponent({
219249
let same = 0;
220250
let lastPos: number;
221251

222-
el.scrollIntoView(props.cameraFollowOptions as ScrollIntoViewOptions);
252+
el.scrollIntoView(
253+
options.value.cameraFollowOptions as ScrollIntoViewOptions,
254+
);
223255
requestAnimationFrame(check);
224256

225257
function check() {
@@ -243,22 +275,22 @@ export const VueTrailerScene = defineComponent({
243275
if (!val) return;
244276

245277
actorWalkIn(val);
246-
if (props.cameraFollow) {
278+
if (options.value.cameraFollow) {
247279
isScrollFixed.value = true;
248280
await smoothScroll(val);
249281
isScrollFixed.value = false;
250282
}
251283

252-
if (props.cameraFixAfterFollow) fixed();
284+
if (options.value.cameraFixAfterFollow) fixed();
253285
});
254286

255287
onMounted(() => {
256-
addScene(props.sceneNumber);
288+
addScene(options.value.sceneNumber);
257289
});
258290

259291
onBeforeUnmount(() => {
260292
cut();
261-
removeScene(props.sceneNumber);
293+
removeScene(options.value.sceneNumber);
262294
});
263295

264296
return () => {
@@ -274,7 +306,7 @@ export const VueTrailerScene = defineComponent({
274306
h(
275307
"div",
276308
{
277-
id: `vue-trailer__spotlight-${props.actName}-${props.sceneNumber}`,
309+
id: `vue-trailer__spotlight-${options.value.actName}-${options.value.sceneNumber}`,
278310
class: "vue-trailer__spotlight",
279311
ref: spotlight,
280312
style: spotlightStyle.value,
@@ -286,7 +318,7 @@ export const VueTrailerScene = defineComponent({
286318
class: [
287319
"vue-trailer__voice-over",
288320
autoVoiceOverPlacement.value,
289-
props.voiceOverAlign,
321+
options.value.voiceOverAlign,
290322
],
291323
ref: voiceOver,
292324
},
@@ -306,7 +338,7 @@ export const VueTrailerScene = defineComponent({
306338
{
307339
class: "efault__voice-over__header__content",
308340
},
309-
props.voiceOverTitle,
341+
options.value.voiceOverTitle,
310342
),
311343
slots.voCloseIcon?.() ||
312344
h(
@@ -329,7 +361,7 @@ export const VueTrailerScene = defineComponent({
329361
]),
330362
h("div", { class: "default__voice-over__body" }, [
331363
slots.voBody?.() ||
332-
h("div", null, props.voiceOverContent),
364+
h("div", null, options.value.voiceOverContent),
333365
]),
334366
h("div", { class: "default__voice-over__footer" }, [
335367
slots.voFooterScene?.() ||
@@ -356,7 +388,7 @@ export const VueTrailerScene = defineComponent({
356388
"default__voice-over__footer__btn",
357389
onClick: () => prevScene(),
358390
},
359-
props.voiceOverPrevButtonText,
391+
options.value.voiceOverPrevButtonText,
360392
),
361393
hasNextScene.value &&
362394
h(
@@ -366,7 +398,7 @@ export const VueTrailerScene = defineComponent({
366398
"default__voice-over__footer__btn",
367399
onClick: () => nextScene(),
368400
},
369-
props.voiceOverNextButtonText,
401+
options.value.voiceOverNextButtonText,
370402
),
371403
!hasNextScene.value &&
372404
h(
@@ -376,7 +408,7 @@ export const VueTrailerScene = defineComponent({
376408
"default__voice-over__footer__btn",
377409
onClick: () => cut(),
378410
},
379-
props.voiceOverDoneButtonText,
411+
options.value.voiceOverDoneButtonText,
380412
),
381413
],
382414
),

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy