s4s-packager / src /scaffolding /context-menu.js
soiz1's picture
Upload 225 files
7aec436 verified
import styles from './style.css';
class ContextMenu {
constructor (parent) {
this.parent = parent;
this.root = document.createElement('div');
this.root.className = styles.contextMenu;
this._onmousedown = this._onmousedown.bind(this);
this._onresize = this._onresize.bind(this);
this._onblur = this._onblur.bind(this);
}
_onmousedown (e) {
if (!this.root.contains(e.target)) {
this.destroy();
}
}
_onresize () {
this.destroy();
}
_onblur () {
this.destroy();
}
add (option) {
const item = document.createElement('button');
item.className = styles.contextMenuItem;
item.textContent = option.text;
item.addEventListener('click', () => {
this.destroy();
option.callback();
});
item.addEventListener('contextmenu', (e) => {
e.preventDefault();
});
this.root.appendChild(item);
}
show (mouseEvent) {
document.addEventListener('mousedown', this._onmousedown);
window.addEventListener('resize', this._onresize);
window.addEventListener('blur', this._onblur);
this.parent._addLayer(this.root);
const layersRect = this.parent.layersRect;
const menuRect = this.root.getBoundingClientRect();
let x = mouseEvent.clientX - layersRect.left;
let y = mouseEvent.clientY - layersRect.top;
if (x + menuRect.width > layersRect.width) {
x -= menuRect.width;
}
if (y + menuRect.height > layersRect.height) {
y -= menuRect.height;
}
this.root.style.transform = `translate(${x}px, ${y}px)`;
getComputedStyle(this.root).opacity;
this.root.style.opacity = '1';
}
destroy () {
document.removeEventListener('mousedown', this._onmousedown);
window.removeEventListener('resize', this._onresize);
window.removeEventListener('blur', this._onblur);
this.root.style.opacity = '0';
this.root.style.pointerEvents = 'none';
setTimeout(() => {
this.root.remove();
}, 200);
}
}
export default ContextMenu;