Skip to content
This repository has been archived by the owner on Dec 12, 2022. It is now read-only.

Commit

Permalink
feat: flatten component options and export Marmoset types
Browse files Browse the repository at this point in the history
  • Loading branch information
DerYeger committed Jul 15, 2021
1 parent 324e506 commit 109eb84
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 88 deletions.
44 changes: 27 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
## Features

-**Dynamic**: Dynamically loads the Marmoset Viewer source code as soon as its rendered required.
-**Dynamic**: Dynamically loads the Marmoset Viewer source code as soon as its required.
- 📱 **Responsive**: Fully responsive. Supports touch controls.
- ⚒️ **Manual access**: If required, directly access the Marmoset with provided type declarations.

## Installation

Expand All @@ -55,7 +56,7 @@ Vue.use(MarmosetViewer)

```vue
<template>
<marmoset-viewer src="/file.mview" :options="{ width: 800, height: 600 }" />
<marmoset-viewer src="/file.mview" :width="800" :width="800" :auto-start="true" />
</template>
```

Expand All @@ -71,27 +72,12 @@ If `responsive` is set to true, the component will fill the available space of i

> Note: No property of the component is reactive.
You can also call `loadMarmoset()` to load the script eagerly. Keep in mind, that this can only be done client-side, as it requires `document` to be available.

### Events

- `load`: Emitted when the MarmosetViewer is done loading.
- `unload`: Emitted when the MarmosetViewer has been unloaded before the component is destroyed.
- `resize`: Emitted when the MarmosetViewer has been resized, because the `responsive` property is set to `true`.

### Options

The following options are available (taken from https://marmoset.co/posts/viewer-integration-guide/):

| Type | Name | Default | Description |
|---------|--------------|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| number | width | 800 | Width of viewer frame in points. This setting is ignored in full frame mode. |
| number | height | 600 | Height of viewer frame in points. This setting is ignored in full frame mode. |
| boolean | autoStart | false | Starts the viewer loading process immediately upon load (user does not have to press the play button). Leaving this disabled can save bandwidth and page load time. |
| boolean | fullFrame | false | When enabled, stretches the viewer rectangle to fill the available frame (the containing window or iframe). This setting is ignored when the “pagePreset” option is enabled. |
| boolean | pagePreset | false | When enabled, constructs a full standalone web page around the viewer, with a resizable frame. Useful for creating a simple, decent-looking presentation without having to construct a page yourself. |
| string | thumbnailURL | undefined | If supplied, this image URL will be used for the load screen instead of the thumbnail extracted from the mview file. For best results, ensure that the given URL will not cause a cross-origin conflict. |

### Nuxt

1. Create the file `plugins/marmosetViewer.ts` with the following content.
Expand All @@ -113,6 +99,30 @@ export default {
}
```

### Manual usage

In addition to the component, this library also allows for direct access of the Marmoset script.
After the `Promise` returned by `loadMarmoset()` is resolved, the script can be accessed at `document.marmoset`.
While the required types are included in this library, keep in mind that this can only be done client-side, as it requires `document` to be available.

### Options

The following options are available (taken from https://marmoset.co/posts/viewer-integration-guide/):

| Type | Name | Default | Description |
|---------|--------------|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| number | width | 800 | Width of viewer frame in points. This setting is ignored in full frame mode. |
| number | height | 600 | Height of viewer frame in points. This setting is ignored in full frame mode. |
| boolean | autoStart | false | Starts the viewer loading process immediately upon load (user does not have to press the play button). Leaving this disabled can save bandwidth and page load time. |

In addition, the following options can be set when embedding a Marmoset viewer manually.

| Type | Name | Default | Description |
|---------|--------------|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| boolean | fullFrame | false | When enabled, stretches the viewer rectangle to fill the available frame (the containing window or iframe). This setting is ignored when the “pagePreset” option is enabled. |
| boolean | pagePreset | false | When enabled, constructs a full standalone web page around the viewer, with a resizable frame. Useful for creating a simple, decent-looking presentation without having to construct a page yourself. |
| string | thumbnailURL | undefined | If supplied, this image URL will be used for the load screen instead of the thumbnail extracted from the mview file. For best results, ensure that the given URL will not cause a cross-origin conflict. |

## Development

```bash
Expand Down
12 changes: 6 additions & 6 deletions dev/serve.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<script lang="ts">
import Vue from 'vue';
import MarmosetViewer from '@/marmoset-viewer.vue';
import Vue from 'vue'
import MarmosetViewer from "@/marmoset-viewer.vue";
export default Vue.extend({
name: 'ServeDev',
components: {
MarmosetViewer
}
});
MarmosetViewer,
},
})
</script>

<template>
<div id="app">
<marmoset-viewer src="test.mview" responsive />
<marmoset-viewer src="test.mview" :responsive="false" auto-start :width="800" :height="500" />
</div>
</template>
128 changes: 128 additions & 0 deletions marmoset-viewer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,132 @@ import Vue, { PluginFunction, VueConstructor } from 'vue'
declare const MarmosetViewer: VueConstructor<Vue> & { install: PluginFunction<any> }
export default MarmosetViewer

/**
* Loads the Marmoset script asynchronously and only once.
* @return Promise that resolves when Marmoset is available.
*/
export declare function loadMarmoset(): Promise<void>

/**
* The id of the Marmoset script tag.
*/
export declare const marmosetScriptId: String

export declare interface Marmoset {
/**
* Embeds a viewer instance to the document body.
* @param src URL of the mview file.
* @param options Options for the viewer.
* @return Marmoset.WebViewer that has been embedded.
*/
embed(src: string, options: Marmoset.WebViewerOptions): Marmoset.WebViewer

/**
* Fetches the thumbnail of a mview file. Request size will be around 64KB.
* @param src URL of the mview file.
* @param onLoad Callback that receives the fetched image.
* @param onError Callback for error scenarios.
* @param image Target image buffer. If not present, a new buffer will be created.
*/
fetchThumbnail(src: string, onLoad: (image: any) => void, onError?: () => void, image?: any): void

/**
* Custom viewer URL. Must be set before any viewer instances are created.
*/
hostURL?: string

/**
* Custom viewer logo URL. Must be set before any viewer instances are created.
*/
hostImage?: string

/**
* Enable transparent background. Must be set before any viewer instances are created.
*/
transparentBackground?: boolean

/**
* Hide the user interface. Must be set before any viewer instances are created.
*/
noUserInterface?: boolean
}

export declare namespace Marmoset {
export class WebViewer {
/**
* Creates a Marmoset viewer with the given size and file.
* @param width Width of the viewer.
* @param height Height of the viewer.
* @param src URL of the mview file.
*/
constructor(width: number, height: number, src: string)

/**
* HTMLDivElement containing the viewer.
*/
domRoot: HTMLDivElement

/**
* Loads the scene immediately.
*/
loadScene(): void

/**
* Callback that is called once the scene has been loaded.
*/
onLoad?: () => void

/**
* Resizes the viewer instance using the given dimensions.
* @param width New width of the viewer.
* @param height New height of the viewer.
*/
resize(width: number, height: number): void

/**
* Unloads the viewer instance and frees used resources.
*/
unload(): void
}

/**
* Options for the Marmoset WebViewer.
*/
export interface WebViewerOptions {
/**
* Width of the viewer instance.
*/
width?: number

/**
* Height of the viewer instance.
*/
height?: number

/**
* If true, the viewer instance loads the scene without user interaction.
*/
autoStart?: boolean

/**
* If true, the viewer instance starts in fullscreen mode.
*/
fullFrame?: boolean

/**
* If true, the viewer instance will wrap itself in a prebuilt HTML page.
*/
pagePreset?: boolean

/**
* Thumbnail of the viewer instance.
*/
thumbnailURL?: string
}
}

declare global {
interface Window {
marmoset: Marmoset & typeof Marmoset
}
}
2 changes: 1 addition & 1 deletion src/entry.esm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ export default /*#__PURE__*/ ((): InstallableComponent => {
// It's possible to expose named exports when writing components that can
// also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo';
// export const RollupDemoDirective = directive;
export { loadMarmoset } from '@/marmoset'
export { loadMarmoset, marmosetScriptId } from '@/marmoset'
40 changes: 20 additions & 20 deletions src/marmoset-viewer.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
<template>
<div
ref="marmosetViewerHost"
class="marmoset-viewer-host"
:class="{ 'marmoset-viewer-host__responsive': responsive }"
/>
<div ref="marmosetViewerHost" class="marmoset-viewer-host" :class="{ 'marmoset-viewer-host__responsive': responsive }" />
</template>

<script lang="ts">
import { defineComponent, PropType } from "@vue/composition-api"
import { loadMarmoset, marmosetDefaultOptions } from "@/marmoset"
import { defineComponent } from '@vue/composition-api'
import { loadMarmoset, marmosetViewerDefaultOptions } from '@/marmoset'
import { Marmoset } from 'marmoset-viewer'
export default defineComponent({
props: {
src: {
type: String,
required: true,
},
options: {
type: Object as PropType<Marmoset.WebViewerOptions>,
default: () => marmosetDefaultOptions,
width: {
type: Number,
default: marmosetViewerDefaultOptions.width,
},
height: {
type: Number,
default: marmosetViewerDefaultOptions.height,
},
responsive: {
type: Boolean,
default: false,
},
autoStart: {
type: Boolean,
default: false,
},
},
data() {
return {
Expand All @@ -35,12 +40,7 @@ export default defineComponent({
return this.$refs.marmosetViewerHost as HTMLDivElement
},
viewer(): Marmoset.WebViewer {
const { width, height } = this.options
return new window.marmoset.WebViewer(
width ?? marmosetDefaultOptions.width,
height ?? marmosetDefaultOptions.height,
this.src
)
return new window.marmoset.WebViewer(this.width, this.height, this.src)
},
},
mounted() {
Expand All @@ -59,13 +59,13 @@ export default defineComponent({
this.resizeObserver = new ResizeObserver(() => this.onResize())
this.resizeObserver.observe(this.viewerHost)
}
if (this.autoStart) {
this.viewer.loadScene()
}
},
onResize() {
try {
this.viewer.resize(
this.viewerHost.clientWidth,
this.viewerHost.clientHeight
)
this.viewer.resize(this.viewerHost.clientWidth, this.viewerHost.clientHeight)
} catch (_) {
// marmoset.js throws a typeError on resize
}
Expand Down
7 changes: 1 addition & 6 deletions src/marmoset.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
export const marmosetDefaultOptions: Required<Omit<Marmoset.WebViewerOptions, 'thumbnailURL'>> &
Pick<Marmoset.WebViewerOptions, 'thumbnailURL'> = {
export const marmosetViewerDefaultOptions = {
width: 800,
height: 600,
autoStart: false,
fullFrame: false,
pagePreset: false,
thumbnailURL: undefined,
}

export const marmosetScriptId = 'marmoset-script'
Expand All @@ -27,7 +23,6 @@ export function loadMarmoset(): Promise<void> {
loadingInProgress = true
const marmosetScript = document.createElement('script')
marmosetScript.setAttribute('src', marmosetScriptUrl)
marmosetScript.async = false
marmosetScript.id = marmosetScriptId
marmosetScript.addEventListener('load', () => {
loadingInProgress = false
Expand Down
35 changes: 0 additions & 35 deletions src/types.ts

This file was deleted.

Loading

0 comments on commit 109eb84

Please sign in to comment.