Docking Panel resizable and scroll container - autodesk-forge

How can Docking Panel be made resizable? How to create scroll container in Docking Panel?
I have extended Docking Panel with the Simple Panel given in this answer How to create a Docking Panel. So ideal would be know how to make them in
SimplePanel.prototype.initialize = function()
or somewhere when creating the docking panel.

I prefer the Extension mechanism, that way you can define JavaScript file that self-contain it. Here is an example. Now the style.resize="auto" line of code and how you can appendChild with other elements (e.g. a DIV full of other elements). With this extension you just need to call viewer.loadExtension().
AutodeskNamespace('Autodesk.ADN.Viewing.Extension');
Autodesk.ADN.Viewing.Extension.MyExtension = function (viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
var _self = this;
///////////////////////////////////////////////////////////////////////////
// load callback
///////////////////////////////////////////////////////////////////////////
_self.load = function () {
// need to access geometry? wait until is loaded
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, function () {
createDockPanel();
});
return true;
};
var _dockPanel;
function createDockPanel() {
_dockPanel = new Autodesk.Viewing.UI.DockingPanel(viewer.container, 'ecom', 'Cart');
_dockPanel.container.style.top = "10px";
_dockPanel.container.style.left = "10px";
_dockPanel.container.style.width = "auto";
_dockPanel.container.style.height = "auto";
_dockPanel.container.style.resize = "auto";
_dockPanel.container.appendChild(document.getElementById(‘someOtherElement’)); // for instance, a DIV
_dockPanel.setVisible(true);
}
///////////////////////////////////////////////////////////////////////////
// unload callback
///////////////////////////////////////////////////////////////////////////
_self.unload = function () {
_dockPanel.setVisible(false)
return true;
};
};
Autodesk.ADN.Viewing.Extension.MyExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
Autodesk.ADN.Viewing.Extension.MyExtension.prototype.constructor = Autodesk.ADN.Viewing.Extension.MyExtension;
Autodesk.Viewing.theExtensionManager.registerExtension('Autodesk.ADN.Viewing.Extension.MyExtension', Autodesk.ADN.Viewing.Extension.MyExtension);

Related

Implementing Three.js SSAOPass in AFrame

I was able to successfully integrate Threejs Effect composer in aframe as a component by exporting everything as THREE.Effectcomposer, THREE.SSAOPass etc. and adding the effect inside a aframe component and i tweaked the AFrame renderer to update the effects in the scene. OutlinePass from threejs worked fine in this code but SSAO is not working and i don't get any errors. Please someone help me figure out the problem. the code for SSAOPass looks like this
AFRAME.registerComponent('ssao', {
init: function () {
this.el.addEventListener('that', evt => this.onEnter());
this.el.addEventListener('mouseleave', evt => this.onLeave());
setTimeout(() => this.el.emit("that"), 2000);
},
onEnter: function () {
const scene = this.el.sceneEl.object3D;
const camera = this.el.sceneEl.camera;
const renderer = this.el.sceneEl.renderer;
const render = renderer.render;
const composer = new THREE.EffectComposer(renderer);
//let renderPass = new THREE.RenderPass(scene, camera);
//let outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
const ssaoPass = new THREE.SSAOPass( scene, camera, window.innerWidth, window.innerHeight );
//composer.addPass(renderPass);
//composer.addPass(outlinePass);
ssaoPass.kernelRadius = 16;
composer.addPass( ssaoPass );
// let objects = [];
// this.el.object3D.traverse(node => {
// if (!node.isMesh) return;
// objects.push(node);
// });
// outlinePass.selectedObjects = objects;
// outlinePass.renderToScreen = true;
// outlinePass.edgeStrength = this.data.strength;
// outlinePass.edgeGlow = this.data.glow;
// outlinePass.visibleEdgeColor.set(this.data.color);
// HACK the AFRAME render method (a bit ugly)
const clock = new THREE.Clock();
this.originalRenderMethod = render;
let calledByComposer = false;
renderer.render = function () {
if (calledByComposer) {
render.apply(renderer, arguments);
} else {
calledByComposer = true;
composer.render(clock.getDelta());
calledByComposer = false;
}
};
},
onLeave: function () {
this.el.sceneEl.renderer.render = this.originalRenderMethod;
},
remove: function () {
this.onLeave();
}
});
I have also created a glitch project which i am sharing here. Please feel free to join and collaborate in my project
Edit link: https://glitch.com/edit/#!/accessible-torpid-partridge
Site link:https://accessible-torpid-partridge.glitch.me
Thanks in advance
The code is correct, all you need is to tweak the exposed SSAOShader uniforms: SSAOPass.kernelRadius, SSAOPass.minDistance, SSAOPass.maxDistance - like in the Three.js example.
Keep in mind - the scale in the example is huge, so the values will need to be different in a default aframe scene.
It's a good idea to be able to dynamically update a component (via setAttribute() if you properly handle updates), so you can see what's going on in realtime. Something like I did here - SSAO in a-frame (also based on Don McCurdys gist.
I've used some basic HTML elements, most threejs examples use dat.GUI - it is made for demo / debug tweaks.

Forge Viewer Extension for Toolbar: How to add a custom combox

I am trying to add a custom combobox to the toolbar in the forge viewer. Below is the code for it. I am able to successfully able to add buttons and they are functional. But combobox is not. It adds a combobox but it does show the fly out menu when I click on it. Not sure what I am doing wrong. help!
function BuildingToolbarExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
}
BuildingToolbarExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
BuildingToolbarExtension.prototype.constructor = BuildingToolbarExtension;
BuildingToolbarExtension.prototype.load = function () {
// Set background environment to "Infinity Pool"
// and make sure the environment background texture is visible
this.viewer.setLightPreset(6);
this.viewer.setEnvMapBackground(true);
// Ensure the model is centered
//this.viewer.fitToView();
return true;
};
BuildingToolbarExtension.prototype.unload = function () {
// nothing yet
if (this.subToolbar) {
this.viewer.toolbar.removeControl(this.subToolbar);
this.subToolbar = null;
}
};
BuildingToolbarExtension.prototype.onToolbarCreated = function (toolbar) {
alert('TODO: customize Viewer toolbar');
var viewer = this.viewer;
// Button 1
var button1 = new Autodesk.Viewing.UI.Button('show-env-bg-button');
button1.onClick = function (e) {
viewer.setEnvMapBackground(true);
};
button1.addClass('show-env-bg-button');
button1.setToolTip('Show Environment');
// Button 2
var button2 = new Autodesk.Viewing.UI.Button('hide-env-bg-button');
button2.onClick = function (e) {
viewer.setEnvMapBackground(false);
};
button2.addClass('hide-env-bg-button');
button2.setToolTip('Hide Environment');
var comboButton = new Autodesk.Viewing.UI.ComboButton('buildings');
comboButton.setToolTip('buildings');
this.floors = new Autodesk.Viewing.UI.ControlGroup('my-custom-toolbar1');
this.floors.addControl(button1);
this.floors.addControl(button2);
comboButton.addControl(this.floors);
comboButton._isCollapsed = true;
comboButton.onClick = function (e) {
this.setCollapsed(false);
}
// SubToolbar
this.subToolbar = new Autodesk.Viewing.UI.ControlGroup('my-custom-toolbar');
this.subToolbar.addControl(button1);
this.subToolbar.addControl(button2);
this.subToolbar.addControl(comboButton);
toolbar.addControl(this.subToolbar);
};
Autodesk.Viewing.theExtensionManager.registerExtension('BuildingToolbarExtension', BuildingToolbarExtension);
The ControlGroup is unnecessary in your case, please refer the following to add buttons to ComboButton
var comboButton = new Autodesk.Viewing.UI.ComboButton('buildings');
comboButton.setToolTip('buildings');
// Button 1
var button1 = new Autodesk.Viewing.UI.Button('show-env-bg-button');
button1.onClick = function (e) {
viewer.setEnvMapBackground(true);
};
button1.addClass('show-env-bg-button');
button1.setToolTip('Show Environment');
comboButton.addControl(button1);
// Button 2
var button2 = new Autodesk.Viewing.UI.Button('hide-env-bg-button');
button2.onClick = function (e) {
viewer.setEnvMapBackground(false);
};
button2.addClass('hide-env-bg-button');
button2.setToolTip('Hide Environment');
comboButton.addControl(button2);
Here are snapshots:
Before opening
After opening

Autodesk Forge - How to stop recoloring of object when selected

Our elements are color coded so when a user selects one we just want to isolate it in the views (which works as expected) BUT we don't want it to change to the selection color - where can we control this?
Use selection event to find which object has been selected, cancel the selection and isolate the selected dbId, is this the behavior you are looking for?
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");
Autodesk.ADN.Viewing.Extension.Basic = function (viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
var _this = this;
_this.load = function () {
console.log('LOAD')
viewer.addEventListener(
Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, function(e) {
//console.log(e)
if(e.selections.length) {
var dbId = e.selections[0].dbIdArray[0]
viewer.select([])
viewer.isolate(dbId)
}
})
return true;
};
_this.unload = function () {
Autodesk.Viewing.theExtensionManager.unregisterExtension(
"Autodesk.ADN.Viewing.Extension.Basic");
return true;
};
};
Autodesk.ADN.Viewing.Extension.Basic.prototype =
Object.create(Autodesk.Viewing.Extension.prototype);
Autodesk.ADN.Viewing.Extension.Basic.prototype.constructor =
Autodesk.ADN.Viewing.Extension.Basic;
Autodesk.Viewing.theExtensionManager.registerExtension(
"Autodesk.ADN.Viewing.Extension.Basic",
Autodesk.ADN.Viewing.Extension.Basic);
In case you want to keep the selection just not make it blue in the UI, you can change the selection material's opacity to see-through:
viewer.impl.selectionMaterialBase.opacity = 0;
viewer.impl.selectionMaterialTop.opacity = 0;
Now when you click on an object it won't turn blue.

Unable to access subfolder html file through <a> tag

I have a main folder with index.html file for my html app. I have written a code in index.html of main folder to access the file (index.html) present in the sub folder as follows,
SubFile
When i click on the above link, it is not navigating to the subfile and instead the link of main folder index.html file changes to mainfolder/index.html#!/subfolder/index.html
I even tried changing the name of subfolder file but no success. What could be the problem?
I also want to navigate back to the main folder index.html from subfolder as follow,
Mainfile
But it is also not working. How can I achieve this as well?
Edited:
The file my-app.js is creating the issue. The code of my-app.js is as follows,
// Initialize your app
var myApp = new Framework7({
animateNavBackIcon: true,
// Enable templates auto precompilation
precompileTemplates: true,
// Enabled pages rendering using Template7
swipeBackPage: false,
swipeBackPageThreshold: 1,
swipePanel: "left",
swipePanelCloseOpposite: true,
pushState: true,
pushStateRoot: undefined,
pushStateNoAnimation: false,
pushStateSeparator: '#!/',
template7Pages: true
});
// Export selectors engine
var $$ = Dom7;
// Add main View
var mainView = myApp.addView('.view-main', {
// Enable dynamic Navbar
dynamicNavbar: false
});
$$(document).on('pageInit', function (e) {
$(".swipebox").swipebox();
$("#ContactForm").validate({
submitHandler: function(form) {
ajaxContact(form);
return false;
}
});
$('a.backbutton').click(function(){
parent.history.back();
return false;
});
$(".posts li").hide();
size_li = $(".posts li").size();
x=4;
$('.posts li:lt('+x+')').show();
$('#loadMore').click(function () {
x= (x+1 <= size_li) ? x+1 : size_li;
$('.posts li:lt('+x+')').show();
if(x == size_li){
$('#loadMore').hide();
$('#showLess').show();
}
});
$("a.switcher").bind("click", function(e){
e.preventDefault();
var theid = $(this).attr("id");
var theproducts = $("ul#photoslist");
var classNames = $(this).attr('class').split(' ');
if($(this).hasClass("active")) {
// if currently clicked button has the active class
// then we do nothing!
return false;
} else {
// otherwise we are clicking on the inactive button
// and in the process of switching views!
if(theid == "view13") {
$(this).addClass("active");
$("#view11").removeClass("active");
$("#view11").children("img").attr("src","images/switch_11.png");
$("#view12").removeClass("active");
$("#view12").children("img").attr("src","images/switch_12.png");
var theimg = $(this).children("img");
theimg.attr("src","images/switch_13_active.png");
// remove the list class and change to grid
theproducts.removeClass("photo_gallery_11");
theproducts.removeClass("photo_gallery_12");
theproducts.addClass("photo_gallery_13");
}
else if(theid == "view12") {
$(this).addClass("active");
$("#view11").removeClass("active");
$("#view11").children("img").attr("src","images/switch_11.png");
$("#view13").removeClass("active");
$("#view13").children("img").attr("src","images/switch_13.png");
var theimg = $(this).children("img");
theimg.attr("src","images/switch_12_active.png");
// remove the list class and change to grid
theproducts.removeClass("photo_gallery_11");
theproducts.removeClass("photo_gallery_13");
theproducts.addClass("photo_gallery_12");
}
else if(theid == "view11") {
$("#view12").removeClass("active");
$("#view12").children("img").attr("src","images/switch_12.png");
$("#view13").removeClass("active");
$("#view13").children("img").attr("src","images/switch_13.png");
var theimg = $(this).children("img");
theimg.attr("src","images/switch_11_active.png");
// remove the list class and change to grid
theproducts.removeClass("photo_gallery_12");
theproducts.removeClass("photo_gallery_13");
theproducts.addClass("photo_gallery_11");
}
}
});
document.addEventListener('touchmove', function(event) {
if(event.target.parentNode.className.indexOf('navbarpages') != -1 || event.target.className.indexOf('navbarpages') != -1 ) {
event.preventDefault(); }
}, false);
// Add ScrollFix
var scrollingContent = document.getElementById("pages_maincontent");
new ScrollFix(scrollingContent);
var ScrollFix = function(elem) {
// Variables to track inputs
var startY = startTopScroll = deltaY = undefined,
elem = elem || elem.querySelector(elem);
// If there is no element, then do nothing
if(!elem)
return;
// Handle the start of interactions
elem.addEventListener('touchstart', function(event){
startY = event.touches[0].pageY;
startTopScroll = elem.scrollTop;
if(startTopScroll <= 0)
elem.scrollTop = 1;
if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)
elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
}, false);
};
})
What shall i remove from it to solve my problem?
#!/subfolder/index.html
This make me feel that you are using a single page application framework/library, like Angular or something related. So maybe your problem is not in the html but in your javascript code.
Please remove all javascript and check it will work fine then revert all js one by one and test you will find the conflict javascript resolve that conflict. it will work fine.

How to include a link in the HTML5 notification?

I would like to be able to set a link/permalink to each notification, so when user clicks on it; then he is taken to the permalink location,
I've seen this answer which has a solution that's a little bit different because static link is used,
I would like to, somehow:
var noti = window.webkitNotifications.createNotification(
'http://funcook.com/img/favicon.png',
'HTML5 Notification',
'HTML5 Notification content...',
'http://mycustom.dynamic.link.com/' /* invented code */
)
noti.onclose = function(){ alert(':(') };
noti.onclick = function(){
window.location.href = $(this).url; /* invented code */
};
noti.show();
Any chance? (I really don't like the static html file solution... I would like to keep this syntax)
How about something like this?
var createNotificationWithLink = function(image, title, content, link) {
var notification = window.webkitNotifications.createNotification(image, title, content);
notification.onclose = function() {
alert(':(');
};
notification.onclick = function() {
window.location.href = link;
};
return notification;
};
Now you can call createNotificationWithLink whenever you want to create a notification:
var noti = createNotificationWithLink(
'http://funcook.com/img/favicon.png',
'HTML5 Notification',
'HTML5 Notification content...',
'http://mycustom.dynamic.link.com/'
);
noti.show();
You can also move noti.show(); into the createNotificationWithLink function if you like (notification.show();). I don't know if you want the notification to be shown automatically when you create it...
You can pass a data property that you can read from within the onclick event handler as e.target.data.
var notification = new window.Notification("Hello!",
{
body: "Hello world!",
data: "https://www.example.com/?id=" + 123
});
notification.onclick = function(e) {
window.location.href = e.target.data;
}
noti.onclick = function() {
window.open("http://www.stackoverflow.com")
};
More on how to use window.open: http://www.w3schools.com/jsref/met_win_open.asp4
HTML5 Notification Resource: http://www.html5rocks.com/en/tutorials/notifications/quick/ (If this doesn't answer you're question)
For Each one you could have:
var noti1 = window.webkitNotifications.createNotification(
'http://funcook.com/img/favicon.png',
'HTML5 Notification',
'HTML5 Notification content...',
var noti2 = window.webkitNotifications.createNotification(
'http://funcook.com/img/favicon.png',
'HTML5 Notification #2',
'HTML5 Notification #2 content...',
etc
and then
noti1.onclick = function() {
window.open("http://www.stackoverflow.com")
};
noti2.onclick = function() {
window.open("http://www.example.com")
};
hope that helps :)
You can add the url as a property to 'noti', then call that property with this.yourpropertyname
example:
noti.myurl = 'http://stackoverflow.com';
...
noti.onclick = function(){
window.location.href = this.myurl;
};
hope this helps.
For anyone, who needs to open a new browser window(tab), but does not want the parent window(tab) to be replaced and focused upon notification click, this code snippet will do the trick:
var notification = new window.Notification("Hello!", {
body: "Hello world!",
data: "https://www.google.com/"
});
notification.onclick = function(event) {
event.preventDefault(); //prevent the browser from focusing the Notification's tab, while it stays also open
var new_window = window.open('','_blank'); //open empty window(tab)
new_window.location = event.target.data; //set url of newly created window(tab) and focus
};