How to display a basic autodesk forge viewer in a vue-cli app? - vuejs2

I was trying to convert the basic viewer example code into a simple vue.js viewer app. When I try to run `npm run serve'(vue-cli).Things are getting rendered correctly and I am getting all the console logs in the console.
But even before the script getting executed the eslint-loader is showing Autodesk is not defined error. But I can see the viewer loaded the document in the background.I will attach a screenshot of it here.
Can someone correct me with the code for creating a basic viewer as a simple vue.js app?
/public/index.html
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<!-- Autodesk Forge Viewer files -->
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css" type="text/css">
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
/src/App.vue
<div id="forgeViewer"></div>
</template>
<script>
export default {
mounted(){
var viewer;
var options = {
env: 'AutodeskProduction',
api: 'derivativeV2', // for models uploaded to EMEA change this option to 'derivativeV2_EU'
getAccessToken: function(onTokenReady) {
var token = 'eyJhbGciOiJIUzI1NiIsImtpZCI6Imp3dF9zeW1tZXRyaWNfa2V5In0.eyJzY29wZSI6WyJidWNrZXQ6Y3JlYXRlIiwiYnVja2V0OnJlYWQiLCJkYXRhOnJlYWQiLCJkYXRhOndyaXRlIl0sImNsaWVudF9pZCI6Ikp2Vk40bzdBQ0V0ZE81TVpnZ21QMk9WM1RoNFJnRW54IiwiYXVkIjoiaHR0cHM6Ly9hdXRvZGVzay5jb20vYXVkL2p3dGV4cDYwIiwianRpIjoiMXBQcVhxOFBZVVU0WmtpTURsaGpUSUxCM3I1UEpBWk9kbTY4dTY2R1ZjajhDY3VzYjB3VFVId0E3emZPVk5JRCIsImV4cCI6MTU4ODIzNDEwOX0.zmY_BFmoZgL4TbtSVyTWKlrFdImEKbQTUsfQxBjsPV4';
var timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
onTokenReady(token, timeInSeconds);
}
};
Autodesk.Viewing.Initializer(options, function() {
var htmlDiv = document.getElementById('forgeViewer');
viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
var startedCode = viewer.start();
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
return;
}
console.log('Initialization complete, loading a model next...');
});
var documentId = 'urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6ZmFjaWxpb25ld2NsaWVudGJ1Y2tldC9yYWNfYWR2YW5jZWRfc2FtcGxlX3Byb2plY3QucnZ0';
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
}
},
methods:{
onDocumentLoadSuccess:function(viewerDocument){
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
viewer.addEventListener( Autodesk.Viewing.SELECTION_CHANGED_EVENT, event=>{
})
},
onDocumentLoadFailure:function(){
console.error('Failed fetching Forge manifest');
}
}
}
</script>
<style>
</style>

You have to fix your Eslint errors one by one.
1.- Declare autodesk as a global in .eslintrc
"globals": {
"Autodesk": true
}
2.- Declare viewer
const viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
3.- Remove event listeners if not being used or just console.log(event)
Alternatively you can disable eslint but I'd never recommend that.

check out these working samples here:
https://github.com/dukedhx/forge-tools-hub/blob/master/components/Viewer.vue
https://github.com/alvpickmans/forge-vuer

In the main.js you can add:
Vue.prototype.$Autodesk = window.Autodesk;
And use it in the vue components like below:
this.$Autodesk

Related

Downloading a pdf document corrupts it when deployed to firebase hosting using Flutter Web

Flutter Web
I want to download a local pdf document stored in assets/doc.pdf
The code that works in my dev environment. I.e. I'm able to download valid pdf in debug mode locally.
ByteData bytes = await rootBundle.load("doc.pdf");
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
//--
// Downloads the file
var link = html.AnchorElement(href: url);
link.download = 'doc.pdf';
link.click();
html.Url.revokeObjectUrl(url);
Problem
When I build the release build and host it on Firebase hosting, after downloading the same file, the file is only 2KB and contains this text with an error message:
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
Fore more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
-->
<base href="/">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<link rel="stylesheet" href="loader.css">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="web_portfolio">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>web_portfolio</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<div id="loader">
<div class="lds-circle"><div></div></div>
</div>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/headjs/1.0.3/head.min.js" ></script>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('flutter-first-frame', function () {
navigator.serviceWorker.register('flutter_service_worker.js?v=2745115030');
});
}
</script>
<script>
head.js("main.dart.js?version=3", function() {
document.getElementById('loader').remove();
});
</script>
<!-- <script src="" type="application/javascript"
onendload="document.getElementById('loader').remove();"></script> -->
</body>
</html>
I have tried multiple browsers.
If I go to build\web\assets\assets, the pdf file is still valid.
I have tried opening the pdf in a new browser tab like so:
ByteData bytes = await rootBundle.load("doc.pdf");
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
//** opens a new tab with the containing pdf
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
But the path is still wrong and the pdf can't be displayed.
I wonder why it works locally, but paths get messed up when live on firebase hosting?

FAST and BLAZOR - How to change the Color Palette of fluent-design-system-provider with Blazor

I am evaluating the new Microsoft fast.design https://www.fast.design/ with fluent-design-system-provider and trying to customize the accent color for Blazor project but no luck...
This is what I did so far as per the official documentation (https://www.fast.design/docs/design-systems/fast-frame):
In my asp.net core Blazor Server Project's _Host.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title </title>
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link href="Test.Main.styles.css" rel="stylesheet" />
</head>
<body>
<fluent-design-system-provider use-defaults>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
Reload
<a class="dismiss">🗙</a>
</div>
</fluent-design-system-provider>
<script src="_framework/blazor.server.js"></script>
<script type="module" src="https://unpkg.com/##microsoft/fast-components"></script>
<script type="module" src="https://unpkg.com/##fluentui/web-components"></script>
<script type="module" src="~/script/site.js"></script>
</body>
</html>
After this in my site.js I am trying to generate and replace the color pallete as mentioned in the documentation https://www.fast.design/docs/design-systems/fast-frame#generating-and-replacing-palettes
import { parseColorHexRGB } from "#microsoft/fast-colors";
import { createColorPalette } from "#microsoft/fast-components";
// Initialization
(function () {
const palette = createColorPalette(parseColorHexRGB("#28EBD7"));
const provider = document.querySelector("fluent-design-system-provider");
// change the neutral color pallete
provider.neutralPalette = palette;
})();
I get the following error,
Uncaught TypeError: Failed to resolve module specifier "#microsoft/fast-colors". Relative references must start with either "/", "./", or "../".
How do i resolve this ?
As far as I know, the import is used in the client application (such as Angular, Teactjs), instead of Asp.net Core Blazor. If you are create a Client application, you could check the Fast Integrations.
To integrate Fast with Asp.net Core Blazor, after installing the Fast using the following command:
npm install --save #microsoft/fast-components
You can locate the single file script build in the following location:
node_modules/#microsoft/fast-components/dist/fast-components.min.js
Copy this to your wwwroot/script folder and reference it with a script tag as described above. Code in the Razor page like this:
<script type="module" src="script/fast-components.min.js"></script>
More detail information, see Fast Integrations for Asp.net Core Blazor.
I missed to add the complete path to the fluent components js files, referencing the correct path works well!
import { neutralLayerL1Behavior, parseColorString } from "https://unpkg.com/#fluentui/web-components";
import { createColorPalette } from "https://unpkg.com/#microsoft/fast-components";
export function initDesignSystemProvider() {
const designSystemProvider = document.querySelector("fluent-design-system-provider");
var accentBaseColor = "#204320";
const accentPalette = createColorPalette(parseColorString(accentBaseColor));
designSystemProvider.accentBaseColor = accentBaseColor;
designSystemProvider.accentPalette = accentPalette;
}

use vue js variables in index.html

I need to use vue js variables inside the index.html page.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="shortcut icon" :href="$store.state.siteLogo" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="static/layui/css/layui.css" />
<link rel="stylesheet" type="text/css" href="static/layui/common.css" />
<title id="siteTitle">{{$store.state.siteTitle}}</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
There, for the title, I need to get a value from the service. That value was able to get from a service and assigned it to a store js variable. My attempt is as in above and it's not working since it's an html file. Anyone, knows how can I achieve this? It worked like this. Inside App.vue created method if we set document.title as below.
created() {
document.title = this.$store.state.siteTitle;
}
But now I need to know how can I change the shortcut icon as well from the service. Does anyone know?
Simply you can do this. You can change favicon dynamically from your service or your vuex state. But If you don't want to work with these vanilajs stuffs, so vue-meta.nuxtjs.org is for you.
created () {
var link =
document.querySelector("link[rel*='icon']") ||
document.createElement("link");
link.type = "image/x-icon";
link.rel = "shortcut icon";
link.href =
"https://cdn.sstatic.net/Sites/stackoverflow/Img/favicon.ico?v=ec617d715196";
document.getElementsByTagName("head")[0].appendChild(link);
}
or you can put it into a method so it can be used dynamically on watch or during click event.
created() {
this.initIcon();
},
methods: {
initIcon() {
var link =
document.querySelector("link[rel*='icon']") ||
document.createElement("link");
link.type = "image/x-icon";
link.rel = "shortcut icon";
link.href = this.icon;
document.getElementsByTagName("head")[0].appendChild(link);
},
click() {
this.icon = '' // new updated icon here
this.initIcon();
},
},

Nuxt project output as UI plugin

How can I host spa project output in CDN and load it in html page like a plugin ? For example Swagger UI can load from CDN and load UI in an HTML tag.
Currently I can do it manually by something like this
const nuxtApp = document.createElement('div');
nuxtApp.id = '__nuxt';
document.querySelector(config.selector).appendChild(nuxtApp);
[
'http://cdn_link/_nuxt/runtime.XXXXX.js',
'http://cdn_link/_nuxt/app.XXXXX.js'
].forEach(src => {
const tag = document.createElement('script');
tag.src = src;
document.body.appendChild(tag);
})
}
The above file I'd manually created based on build output and then in my local html file I can do like this.
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app"></div>
<script src="http://cdn_link/lib.js"></script>
<script >
initApp({
selector: '#app'
})
</script>
</body>
</html>
Is there any easier way to create the lib file along with the build of nuxt ?

Importing stripe to a Vue.js component

https://alligator.io/vuejs/stripe-elements-vue-integration/
On this website, it says we need to import the file with the script tag in the index.html file, which I did, but I noticed I get a js error.
It's only when I imported directly the script inside the component that the error "'Stripe' is not defined" disappeared.
<template>
<div>
</div>
</template>
<script src="https://js.stripe.com/v3/"></script>
<script>
export default {
name: 'component',
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
I don't want to import it directly inside my component, because it's not clean, what can I do?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://js.stripe.com/v3/"></script>
<title>vue-app</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
Late to the party, but here is a solution that works for me
Your index.html file looks fine:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://js.stripe.com/v3/"></script>
<title>vue-app</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
Then in the component where you want to use it, you can access stripe with the window object, and set the publishable key. This can be done locally in a method, or globally for the component, like this:
<script>
const stripe = window.Stripe(process.env.VUE_APP_STRIPE_PK)
export default {
data() {
return {
// ...
}
},
methods: {
async confirmPayment() {
const paymentResult = await stripe.confirmCardPayment(this.clientSecret, {
receipt_email: 'email#example.com',
})
console.log('paymentResult:', paymentResult)
},
},
}
</script>
I think you should move the script tag of Stripe before the rest of your JavaScript code. The code is probably trying to access the Stripe object before it's been loaded.