DockingPanel
sRect 2022-2-18
/**
* 创建forge UI 面板
* https://forge.autodesk.com/en/docs/viewer/v2/reference/javascript/dockingpanel/
* @param {HTMLElement} parentContainer 挂载到目标节点的位置
* @param {String} id 容器id
* @param {String} title 容器名称
* @param {HTMLElement} content 容器内容
* @param {Object} position 容器位置
* @param {Number} containerWidth 容器默认宽度
* @param {Number} containerWidth 容器默认高度
* @param {Number} containerMinWidth 容器最小宽度
* @param {Number} containerMinHeight 容器最小高度
* @param {Object} viewer 模型对象实例
* @param {String} scrollBodyClassName
* @param {Function} afterCloseCallback 关闭后的回调
* @param {Function} footerResizeCallback panel放大缩小后回调
* @param {Object} options 附加参数
*/
class CustomDockingPanel extends window.Autodesk.Viewing.UI.DockingPanel {
constructor({
parentContainer,
id,
title,
content,
position = {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
containerHeight,
containerWidth,
containerMinWidth = 320,
containerMinHeight = 300,
viewer,
scrollBodyClassName,
afterCloseCallback = () => {},
footerResizeCallback = () => {},
options,
}) {
super(parentContainer, id, title, options);
this.viewer = viewer;
this.content = content;
this.panelTitle = title;
this.containerWidth = containerWidth;
this.containerHeight = containerHeight;
this.containerMinWidth = containerMinWidth;
this.containerMinHeight = containerMinHeight;
this.scrollBodyClassName = scrollBodyClassName || 'scrollBody';
this.afterCloseCallback = afterCloseCallback;
this.footerResizeCallback = footerResizeCallback;
// 保持滚动条
this.overrideBringToFront = function () {
const oldBringToFront = this.bringToFront;
this.bringToFront = function (...args) {
const viewpointTree = this.container?.querySelector(`.${this.scrollBodyClassName}`);
const oldScrollTop = viewpointTree?.scrollTop || 0;
oldBringToFront.apply(this, args);
if (viewpointTree) viewpointTree.scrollTop = oldScrollTop;
};
};
// Auto-fit to the content and don't allow resize. Position at the coordinates given.
this.container.style.height = `${this.containerHeight}px`;
this.container.style.width = `${this.containerWidth}px`;
this.container.style.minHeight = `${this.containerMinHeight}px`;
this.container.style.minWidth = `${this.containerMinWidth}px`;
this.container.style.backgroundColor = '#ffffff';
// this.container.style.resize = 'none';
this.container.style.left = `${isNaN(position.left) ? position.left : position.left + 'px'}`;
this.container.style.top = `${isNaN(position.top) ? position.top : position.top + 'px'}`;
this.container.style.bottom = `${
isNaN(position.bottom) ? position.bottom : position.bottom + 'px'
}`;
this.container.style.right = `${
isNaN(position.right) ? position.right : position.right + 'px'
}`;
}
// listenerWindowResize() {
// setTimeout(() => {
// const { offsetWidth, offsetHeight } = this.viewer && this.viewer.canvasWrap;
// let [resultWidth, resultHeight] = [0, 0];
// resultWidth = this.containerMinWidth > offsetWidth ? offsetWidth : this.containerMinWidth;
// resultHeight =
// this.containerMinHeight > offsetHeight ? offsetHeight - 100 : this.containerMinHeight;
// this.container.style.minWidth = `${resultWidth}px`;
// this.container.style.minHeight = `${resultHeight}px`;
// });
// }
initialize() {
setTimeout(() => {
// Override DockingPanel initialize() to:
// - create a standard title bar
// - click anywhere on the panel to move
// - create a close element at the bottom right
let dragFlag = false;
// const listenerWindowResize = this.listenerWindowResize.bind(this);
const handleDocumentMouseUp = () => {
if (dragFlag) {
const scrollWrapBody =
this.scrollBodyClassName && document.querySelector(`.${this.scrollBodyClassName}`);
dragFlag = false;
// this.resizeToContent();
this.footerResizeCallback(scrollWrapBody);
}
};
const handleresizeFooterMouseDown = () => {
dragFlag = true;
};
this.title = this.createTitleBar(this.panelTitle || this.container.id);
// this.title.style.borderBottom = 0;
this.container.appendChild(this.title);
this.scrollContainer = this.createScrollContainer();
this.scrollContainer.appendChild(this.content);
// this.container.appendChild(this.scrollContainer);
this.initializeMoveHandlers(this.title);
// this.closer = document.createElement('div');
// this.closer.className = 'simplePanelClose';
// this.closer.textContent = 'Close';
this.closer = this.createCloseButton();
this.initializeCloseHandler(this.closer);
this.container.appendChild(this.closer);
// window.addEventListener('resize', listenerWindowResize, false);
// listenerWindowResize();
if (this.options.addFooter) {
this.footer = this.createFooter();
this.container.appendChild(this.footer);
}
const resizeFooter =
this.footer && this.footer.querySelector('.docking-panel-footer-resizer');
if (resizeFooter) {
resizeFooter.addEventListener('mousedown', handleresizeFooterMouseDown, false);
document.addEventListener('mouseup', handleDocumentMouseUp, false);
}
// 关闭后的回调
this.addVisibilityListener(() => {
setTimeout(() => {
const isVisible = this.isVisible();
!isVisible && this.afterCloseCallback();
// window.removeEventListener('resize', listenerWindowResize);
document.removeEventListener('mouseup', handleDocumentMouseUp);
resizeFooter &&
resizeFooter.removeEventListener('mousedown', handleresizeFooterMouseDown);
});
});
this.resizeToContent();
this.overrideBringToFront();
});
}
}
export default CustomDockingPanel;