diff --git a/js/controllers/clipper_controller.js b/js/controllers/clipper_controller.js new file mode 100644 index 0000000..07551a2 --- /dev/null +++ b/js/controllers/clipper_controller.js @@ -0,0 +1,74 @@ +// Global ATON +import { Controller } from "@hotwired/stimulus" +import AppState from "../state.js"; +import { addClippingPlane, resetClipping } from "../utils/clipping.js"; +import { toggleAmbientOcclusion } from "../utils/environment.js"; + +/** + * Handle events for the clipper toolbar, + * related to the clipping module + */ +export default class extends Controller { + static targets = ['trigger', 'clipper', 'axis']; + static values = { enabled: Boolean }; + + connect() { + console.log('#clipper controller connected'); + } + + clip(event) { + /** + * @type {string} + */ + const label = event.params.axis; + /** + * @type {HTMLButtonElement} + */ + const target = event.target; + /** + * @type {NodeListOf} + */ + const axes = this.axisTargets; + const classes = ['border', 'border-2', 'border-warning']; + + addClippingPlane(label, -1); + target.classList.add(...classes); + + for (const btn of axes) { + if (btn.id !== target.id) { + btn.classList.remove(...classes); + } + } + } + /** + * Toggle clipper toolbar + */ + toggleClipper() { + /** + * @type {HTMLElement} + */ + const trigger = this.triggerTarget; + this.clipperTarget.classList.toggle('d-none'); + // If the toolbar is shown, clipping is enabled and vice versa + this.enabledValue = !this.clipperTarget.classList.contains('d-none'); + + this.axisTargets.forEach(btn => { + btn.classList.remove('border', 'border-2', 'border-warning'); + }); + + // AO should be turned off if clipping is enabled + toggleAmbientOcclusion(!this.enabledValue); + + if (this.enabledValue) { + trigger.className += ' border border-2 border-white'; + } + + if (!this.enabledValue) { + resetClipping(); + trigger.className = trigger.className.replace(/ border.*$/g, ''); + } + + AppState.clipping.enabled = this.enabledValue; + } +} + diff --git a/js/controllers/settings_controller.js b/js/controllers/settings_controller.js new file mode 100644 index 0000000..17491c8 --- /dev/null +++ b/js/controllers/settings_controller.js @@ -0,0 +1,28 @@ +import { Controller } from "@hotwired/stimulus" +import AppState from "../state.js"; + +export default class extends Controller { + static targets = ['ao', 'shadows']; + + connect() { + console.log('#settings controller connected'); + this.aoTarget.checked = AppState.ambientOcclusion; + this.shadowsTarget.checked = AppState.shadows; + } + /** + * Toggle Ambient Occlusion + * @param {Event} event + */ + toggleAO(event) { + ATON.FX.togglePass(ATON.FX.PASS_AO, event.target.checked); + AppState.ambientOcclusion = event.target.checked; + } + /** + * Toggle shadows + * @param {Event} event + */ + toggleShadows(event) { + ATON.toggleShadows(event.target.checked); + AppState.shadows = event.target.checked; + } +} diff --git a/js/controllers/tabs_controller.js b/js/controllers/tabs_controller.js new file mode 100644 index 0000000..df79146 --- /dev/null +++ b/js/controllers/tabs_controller.js @@ -0,0 +1,42 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ['active', 'tab', 'content']; + + connect() { + console.log('#tabs controller connected'); + } + /** + * + * @param {Event} event + */ + activate(event) { + event.preventDefault(); + this.deactivate(); + const activeId = event.currentTarget.dataset.id; + + event.currentTarget.parentElement.classList.add('active'); + this.contentTargets.find(c => c.dataset.id === activeId) + .classList.remove('d-hide'); + } + + reset() { + this.deactivate(); + const activeId = this.activeTarget.dataset.id; + + this.activeTarget.classList.add('active'); + this.contentTargets.find(c => c.dataset.id === activeId) + .classList.remove('d-hide'); + } + + deactivate() { + this.tabTargets.forEach(tab => { + tab.classList.remove('active'); + }); + + this.contentTargets.forEach(content => { + content.classList.add('d-hide'); + }); + } +} + diff --git a/js/controllers/toolbar_controller.js b/js/controllers/toolbar_controller.js new file mode 100644 index 0000000..b181e58 --- /dev/null +++ b/js/controllers/toolbar_controller.js @@ -0,0 +1,50 @@ +// Global ATON +import { Controller } from "@hotwired/stimulus" +import AppState from "../state.js"; +import { createLightSlider } from "../utils/environment.js"; + +const html = String.raw; +const panelHeader = html` + Impostazioni +`; + +export default class extends Controller { + static targets = ['settings']; + + connect() { + console.log('#toolbar controller connected'); + } + /** + * Open settings panel + * @param {Event} event + */ + toggleSettings(event) { + ATON.UI.setSidePanelLeft(); + ATON.UI.showSidePanel({header: panelHeader}); + this.#buildSettingsPanel(ATON.UI.elSidePanel); + } + /** + * Clone a