diff --git a/apps/dotlottie-vue-example/src/App.vue b/apps/dotlottie-vue-example/src/App.vue index 4bd450e3..32adc036 100644 --- a/apps/dotlottie-vue-example/src/App.vue +++ b/apps/dotlottie-vue-example/src/App.vue @@ -5,6 +5,10 @@ import wasmUrl from '../../../packages/web/src/core/dotlottie-player.wasm?url'; setWasmUrl(wasmUrl); +function dotLottieRefCallback(dotLottie: DotLottieVueInstance) { + console.log('dotLottieRefCallback', dotLottie); +} + const player: Ref = ref(null); function toggleLoop() { @@ -52,6 +56,8 @@ onMounted(() => { loop ref="player" src="https://lottie.host/5525262b-4e57-4f0a-8103-cfdaa7c8969e/VCYIkooYX8.json" + :dot-lottie-ref-callback="dotLottieRefCallback" + play-on-hover />
diff --git a/packages/vue/src/abstract-dotlottie-vue.ts b/packages/vue/src/abstract-dotlottie-vue.ts new file mode 100644 index 00000000..34c02071 --- /dev/null +++ b/packages/vue/src/abstract-dotlottie-vue.ts @@ -0,0 +1,137 @@ +import type { DotLottieWorker, DotLottie, Mode } from '@lottiefiles/dotlottie-web'; +import { type Config } from '@lottiefiles/dotlottie-web'; +import { type VNode, onMounted, watch, type SetupContext, onBeforeUnmount, defineComponent, h, ref } from 'vue'; + +export { type DotLottie }; + +export interface AbstractDotLottieVueProps extends Omit { + _createDotLottieInstance: (config: Config & { workerId?: string }) => DotLottie | DotLottieWorker; + animationId?: string; + dotLottieRefCallback?: (dotLottie: DotLottie | DotLottieWorker) => void; + playOnHover?: boolean; + themeData?: string; + themeId?: string; + workerId?: string; +} + +export const dotLottieVuePropsDefinition = defineProps({ + animationId: String, + autoplay: Boolean, + backgroundColor: String, + data: [String, ArrayBuffer], + loop: Boolean, + mode: String, + renderConfig: Object, + segment: Array, + speed: Number, + src: String, + useFrameInterpolation: Boolean, + marker: String, + playOnHover: Boolean, + themeData: String, + themeId: String, + workerId: String, + _createDotLottieInstance: { Function, required: true }, + dotLottieRefCallback: Function, +}); + +export const AbstractDotLottieVue = defineComponent({ + props: dotLottieVuePropsDefinition, + setup(props, { attrs, expose }: SetupContext): () => VNode { + let dotLottie: DotLottie | DotLottieWorker | null = null; + const canvasRef = ref(null); + + watch( + () => props.backgroundColor, + (newVal) => { + dotLottie?.setBackgroundColor(newVal ?? ''); + }, + ); + watch( + () => props.marker, + (newVal) => { + dotLottie?.setMarker(newVal ?? ''); + }, + ); + watch( + () => props.loop, + (newVal) => { + dotLottie?.setLoop(newVal); + }, + ); + watch( + () => props.mode, + (newVal) => { + if (newVal) { + dotLottie?.setMode(newVal as Mode); + } else { + dotLottie?.setMode('forward'); + } + }, + ); + watch( + () => props.segment, + (_newVal) => { + // const startFrame = newVal?.[0] ?? 0; + // const endFrame = newVal?.[1] ?? 0; + // dotLottie?.setSegment(startFrame, endFrame); + }, + ); + watch( + () => props.speed, + (newVal) => { + dotLottie?.setSpeed(newVal ?? 1); + }, + ); + watch( + () => props.useFrameInterpolation, + (newVal) => { + dotLottie?.setUseFrameInterpolation(newVal); + }, + ); + watch( + () => props.animationId, + (newVal) => { + dotLottie?.loadAnimation(newVal ?? ''); + }, + ); + watch( + () => props.themeData, + (newVal) => { + dotLottie?.setTheme(newVal ?? ''); + }, + ); + watch( + () => props.themeId, + (newVal) => { + dotLottie?.setThemeData(newVal ?? ''); + }, + ); + + onMounted(() => { + const canvas = canvasRef.value; + + const { _createDotLottieInstance, dotLottieRefCallback, ...config } = props; + + dotLottie = _createDotLottieInstance?.({ + ...config, + canvas, + }); + + if (typeof dotLottieRefCallback === 'function') { + dotLottieRefCallback(dotLottie); + } + }); + + onBeforeUnmount(() => { + dotLottie?.destroy(); + dotLottie = null; + }); + + expose({ + getDotLottieInstance: (): DotLottie | DotLottieWorker | null => dotLottie, + }); + + return () => h('div', { ...attrs }, [h('canvas', { ref: canvasRef, style: 'height: 100%; width: 100%' })]); + }, +}); diff --git a/packages/vue/src/dotlottie-vue.ts b/packages/vue/src/dotlottie-vue.ts new file mode 100644 index 00000000..93a83607 --- /dev/null +++ b/packages/vue/src/dotlottie-vue.ts @@ -0,0 +1,20 @@ +/* eslint-disable no-warning-comments */ +import type { Config } from '@lottiefiles/dotlottie-web'; +import { DotLottie } from '@lottiefiles/dotlottie-web'; +import type { VNode } from 'vue'; +import { defineComponent, h } from 'vue'; + +import { AbstractDotLottieVue, dotLottieVuePropsDefinition } from './abstract-dotlottie-vue'; + +export const DotLottieVue = defineComponent({ + // TODO: omit from the props the createDotLottieInstance function + props: dotLottieVuePropsDefinition, + setup(props, { attrs }) { + console.log('DotLottieVue Props', props); + const _createDotLottieInstance = (config: Config): DotLottie => { + return new DotLottie(config); + }; + + return (): VNode => h(AbstractDotLottieVue, { ...props, ...attrs, _createDotLottieInstance }); + }, +}); diff --git a/packages/vue/src/dotlottie-worker-vue.ts b/packages/vue/src/dotlottie-worker-vue.ts new file mode 100644 index 00000000..2a3200d0 --- /dev/null +++ b/packages/vue/src/dotlottie-worker-vue.ts @@ -0,0 +1,21 @@ +/* eslint-disable no-warning-comments */ +import type { Config } from '@lottiefiles/dotlottie-web'; +import { DotLottieWorker } from '@lottiefiles/dotlottie-web'; +import type { VNode } from 'vue'; +import { defineComponent, h } from 'vue'; + +import { AbstractDotLottieVue, dotLottieVuePropsDefinition } from './abstract-dotlottie-vue'; + +export const DotLottieWorkerVue = defineComponent({ + // TODO: omit from the props the createDotLottieInstance function + props: dotLottieVuePropsDefinition, + setup(props, { attrs }) { + const _createDotLottieInstance = (config: Config & { workerId?: string }): DotLottieWorker => { + console.log('DotLottieWorkerVue _createDotLottieInstance', config); + + return new DotLottieWorker(config); + }; + + return (): VNode => h(AbstractDotLottieVue, { ...props, ...attrs, _createDotLottieInstance }); + }, +}); diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts index 1bf91628..91fde16e 100644 --- a/packages/vue/src/index.ts +++ b/packages/vue/src/index.ts @@ -1 +1,9 @@ -export * from './dotlottie'; +import { DotLottie, DotLottieWorker } from '@lottiefiles/dotlottie-web'; + +export * from './dotlottie-vue'; +export * from './dotlottie-worker-vue'; + +export const setWasmUrl = (url: string): void => { + DotLottie.setWasmUrl(url); + DotLottieWorker.setWasmUrl(url); +}; diff --git a/packages/vue/tsup.config.cjs b/packages/vue/tsup.config.cjs index 09e86a55..1a7ab8b1 100644 --- a/packages/vue/tsup.config.cjs +++ b/packages/vue/tsup.config.cjs @@ -1,17 +1,16 @@ const { defineConfig } = require('tsup'); module.exports = defineConfig({ - bundle: true, + bundle: false, metafile: false, - splitting: false, treeshake: true, clean: true, dts: true, minify: false, - sourcemap: false, + sourcemap: true, entry: ['./src/**/*.ts'], format: ['esm'], platform: 'browser', - target: ['es2020', 'node18'], + target: ['es2020'], tsconfig: 'tsconfig.build.json', });