{"id":15213018,"url":"https://github.com/thenbs/ng2-adsk-forge-viewer","last_synced_at":"2025-10-29T22:31:16.772Z","repository":{"id":32353127,"uuid":"115947743","full_name":"theNBS/ng2-adsk-forge-viewer","owner":"theNBS","description":"Angular wrapper for the Autodesk Forge Viewer.","archived":false,"fork":false,"pushed_at":"2023-10-07T06:01:42.000Z","size":2983,"stargazers_count":23,"open_issues_count":10,"forks_count":13,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-02-02T05:25:08.245Z","etag":null,"topics":["angular","autodesk","forge-viewer"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/theNBS.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-01T21:03:23.000Z","updated_at":"2024-11-04T13:00:45.000Z","dependencies_parsed_at":"2024-06-21T14:11:52.969Z","dependency_job_id":"026d4c4b-19d2-4010-8309-24aacd67a230","html_url":"https://github.com/theNBS/ng2-adsk-forge-viewer","commit_stats":{"total_commits":228,"total_committers":7,"mean_commits":32.57142857142857,"dds":0.6578947368421053,"last_synced_commit":"070103304a91521514d51179cd70cfd80f58d594"},"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theNBS%2Fng2-adsk-forge-viewer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theNBS%2Fng2-adsk-forge-viewer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theNBS%2Fng2-adsk-forge-viewer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theNBS%2Fng2-adsk-forge-viewer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theNBS","download_url":"https://codeload.github.com/theNBS/ng2-adsk-forge-viewer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238909248,"owners_count":19550836,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","autodesk","forge-viewer"],"created_at":"2024-09-28T09:09:12.602Z","updated_at":"2025-10-29T22:31:11.322Z","avatar_url":"https://github.com/theNBS.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Angular Autodesk Forge Viewer\n\n[![CI](https://github.com/theNBS/ng2-adsk-forge-viewer/actions/workflows/ci.yaml/badge.svg)](https://github.com/theNBS/ng2-adsk-forge-viewer/actions/workflows/ci.yaml)\n[![Viewer](https://img.shields.io/badge/Viewer-v7-green.svg)](https://forge.autodesk.com/)\n\nAngular wrapper for the [Autodesk Forge Viewer](https://developer.autodesk.com).\n\nThe wrapper was designed to meet the following requirements:\n\n- A viewer component that can be dropped in to an angular anywhere; the component would take care of loading required Scripts and CSS from Autodesk's servers, rather than requiring these to be declared in the index.html.\n  - Ensure the viewer can be displayed and removed from the DOM via *ngIf \n- A basic viewer extension to subscribe to common viewer events - such as Seletion changed, object tree loaded etc. and expose these events on the component\n- TypeScript typings - which are now provided via Autodesk's official forge-viewer typings.\n- A component that can be dropped in to display a document thumbnail.\n\n## Dependencies\n\nThe library targets Angular 8 and newer.\n\n## Using the viewer component\n\nFollow these steps to get the viewer working in your app.\n\nA full demonstration of how to use the the library can be found on StackBlitz - https://stackblitz.com/edit/angular-forge-viewer.\n\n### Step 1\nAdd the ng2-adsk-forge-viewer NPM package to your app - npm install `ng2-adsk-forge-viewer --save` or `yarn add ng2-adsk-forge-viewer`\n\n### Step 2\nAdd `\u003cadsk-forge-viewer\u003e\u003c/adsk-forge-viewer\u003e` element to your component html\n\ncomponent.html:\n```html\n\u003cadsk-forge-viewer [viewerOptions]=\"viewerOptions3d\"\u003e\n\u003c/adsk-forge-viewer\u003e\n```\n\n### Step 3\nThere is a specific flow of logic to initialize the viewer:\n\n1. Set viewerOptions\n2. The viewer is constructed, loads scripts/resources from Autodesk's servers\n2. The onViewerScriptsLoaded callback (optional) is called to indicate all viewer resources have been loaded\n3. A onViewerInitialized callback is called indicating the Viewer is ready (i.e. Autodesk.Viewing.Initializer has been called) and a model can be loaded\n4. The `onViewerInitialized` event is emitted and you can now load a model. The event arguments contain a reference to the viewer which can be used to set the documentId to load. E.g.:\n  ```typescript\n  public loadDocument(args: ViewerInitializedEvent) {\n    args.viewerComponent.DocumentId = DOCUMENT_URN_GOES_HERE;\n  }\n  ```\n  - A helper method `getDefaultViewerOptions` can be used to get the most basic viewer options\n\n### Step 4\nWhen the model has been loaded the `onDocumentChanged` event is emitted. This event can be used to define the view to display (by default, the viewer will load the first 3D viewable it can find).\n\nAn example of displaying a 2D viewable:\n\ncomponent.html:\n```html\n\u003cadsk-forge-viewer [viewerOptions]=\"viewerOptions2d\"\n                    (onDocumentChanged)=\"documentChanged($event)\"\u003e\u003c/adsk-forge-viewer\u003e\n```\n\ncomponent.ts:\n```typescript\npublic documentChanged(event: DocumentChangedEvent) {\n  const { document } = event;\n\n  if (!document.getRoot()) return;\n\n  const viewables = document.getRoot().search({ type: 'geometry', role: '2d' });\n  if (viewables \u0026\u0026 viewables.length \u003e 0) {\n    event.viewerComponent.loadDocumentNode(document, viewables[0]);\n  }\n}\n```\n\n## FAQ\n\n### 1. What ViewerOptions can be used to initialise the Viewer Component?\n\nThe ViewerOptions interface is as follows:\n\n```typescript\ninterface ViewerOptions {\n  initializerOptions: Autodesk.Viewing.InitializerOptions;\n  viewerConfig?: Autodesk.Viewing.ViewerConfig;\n  headlessViewer?: boolean;\n  showFirstViewable?: boolean;\n  enableMemoryManagement?: boolean;\n  onViewerScriptsLoaded?: () =\u003e void;\n  onViewerInitialized: (args: ViewerInitializedEvent) =\u003e void;\n}\n```\n\n`initializerOptions` allows you to provide arguments for the [Autodesk.Viewing.Initializer](https://developer.autodesk.com/en/docs/viewer/v2/reference/javascript/initializer/). One of the most important settings is how the Forge viewer is to obtain it's access token.\n\nYou can provide an access key as a string, but I'd recommend using the function - the viewer will call the function you provide to obtain a new token when required - e.g. when the viewer first initialises or when the current token held by the viewer is shortly expiring.\n\nYour viewer options code would look something like this:\n\n```typescript\nthis.viewerOptions3d = {\n  initializerOptions: {\n    env: 'AutodeskProduction',\n    getAccessToken: (onGetAccessToken: (token: string, expire: number) =\u003e void) =\u003e {\n      // Call back-end API endpoint to get a new token\n      // Pass new token and expire time to Viewer's callback method\n      onGetAccessToken(ACCESS_TOKEN, EXPIRE_TIME);\n    },\n    api: 'derivativeV2',\n  },\n  onViewerInitialized: (args: ViewerInitializedEvent) =\u003e {\n    // Load document in the viewer\n    args.viewerComponent.DocumentId = 'DOCUMENT_URN_HERE';\n  },\n};\n```\n\n`viewerConfig` allows you to provide additional options to Viewer3D's registered with the viewing application. Such as whether to ues the light or dark theme, any extensions to register with the viewer etc.\n\n### 2. How do I configure a 'headless' viewer?\n\nBy default, the viewer component will intialise a 'full' `ViewingApplication` with toolbar, navigation controls etc. If you want a 'headless viewer' without these additional bits of UI, set the `headlessViewer` of the ViewOptions to true:\n\n```typescript\nthis.viewerOptions3d = {\n  initializerOptions: {\n    env: 'AutodeskProduction',\n    getAccessToken: (onGetAccessToken: (token: string, expire: number) =\u003e void) =\u003e {\n      // Call back-end API endpoint to get a new token\n      // Pass new token and expire time to Viewer's callback method\n      onGetAccessToken(ACCESS_TOKEN, EXPIRE_TIME);\n    },\n    api: 'derivativeV2',\n  },\n  headlessViewer: true,\n  onViewerInitialized: (args: ViewerInitializedEvent) =\u003e {\n    // Load document in the viewer\n    args.viewerComponent.DocumentId = 'DOCUMENT_URN_HERE';\n  },\n};\n```\n\n### 3. My model doesn't load\n\nSome users have reported that the default viewable is not rendered and have had to resort to using the onDocumentChanged changed event to load a model in the viewer.\n\nAn implementation might look like the following:\n\napp.component.html\n\n```html\n\u003cadsk-forge-viewer [viewerOptions]=\"viewerOptions2d\"\n                    (onDocumentChanged)=\"documentChanged($event)\"\u003e\u003c/adsk-forge-viewer\u003e\n```\n\napp.component.ts\n\n```typescript\npublic documentChanged(event: DocumentChangedEvent) {\n  const { document } = event;\n\n  if (!document.getRoot()) return;\n\n  const viewables = document.getRoot().search({ type: 'geometry', role: '2d' });\n  if (viewables \u0026\u0026 viewables.length \u003e 0) {\n    event.viewerComponent.loadDocumentNode(document, viewables[0]);\n  }\n}\n```\n\n## Extensions\n\n### BasicExtension\n\nThe viewer component comes with a `BasicExtension` that it registers against all viewers. The basic extension captures a handful of events including:\n\n- Autodesk.Viewing.FIT_TO_VIEW_EVENT,\n- Autodesk.Viewing.FULLSCREEN_MODE_EVENT,\n- Autodesk.Viewing.GEOMETRY_LOADED_EVENT,\n- Autodesk.Viewing.HIDE_EVENT,\n- Autodesk.Viewing.ISOLATE_EVENT,\n- Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT,\n- Autodesk.Viewing.OBJECT_TREE_UNAVAILABLE_EVENT,\n- Autodesk.Viewing.RESET_EVENT,\n- Autodesk.Viewing.SELECTION_CHANGED_EVENT,\n- Autodesk.Viewing.SHOW_EVENT,\n\nThe viewer emits these events and should support most use cases. It's possible to obtain a reference to the BasicExtension via the viewer's `basicExtension` getter. \n\n### Creating your own extension\n\nThe `BasicExtension` is derived from an `Extension` that wraps up all the logic to register and unregister extensions with the Forge Viewer. It also contains logic to cast Forge Viewer event arguments to strongly typed TypeScript classes.\n\nYour extension should derive from `Extension` and have a few basic properties and methods.\n\n```typescript\nexport class MyExtension extends Extension {\n  // Extension must have a name\n  public static extensionName: string = 'MyExtension';\n\n  public load() {\n    // Called when Forge Viewer loads your extension\n  }\n\n  public unload() {\n    // Called when Forge Viewer unloads your extension\n  }\n}\n```\n\nExample viewer options to register and load the above extension:\n\n```typescript\nthis.viewerOptions3d = {\n  initializerOptions: {\n    env: 'AutodeskProduction',\n    getAccessToken: (onGetAccessToken: (token: string, expire: number) =\u003e void) =\u003e {\n      // Call back-end API endpoint to get a new token\n      // Pass new token and expire time to Viewer's callback method\n      onGetAccessToken(ACCESS_TOKEN, EXPIRE_TIME);\n    },\n    api: 'derivativeV2',\n  },\n  onViewerScriptsLoaded: () =\u003e {\n    Extension.registerExtension(MyExtension.extensionName, MyExtension);\n  },\n  onViewerInitialized: (args: ViewerInitializedEvent) =\u003e {\n    // Load document in the viewer\n    args.viewerComponent.DocumentId = 'DOCUMENT_URN_HERE';\n  },\n};\n```\n\nMost of the methods in the abstract `Extension` class are protected. So they can be overriden in derived classes if required. For example, the BasicExtension overrides the `registerExtension` method to take a callback to let the viewer component know when the Extension has been registered.\n\n## Building the component\n\nFor instructions on how to develop the component (build, debug, test etc.), see (README_dev.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthenbs%2Fng2-adsk-forge-viewer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthenbs%2Fng2-adsk-forge-viewer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthenbs%2Fng2-adsk-forge-viewer/lists"}