From bebe807da541c4123ede774b1ba8df4bc19663cf Mon Sep 17 00:00:00 2001 From: Nathan Lively <60303904+LiveNathan@users.noreply.github.com> Date: Thu, 19 Oct 2023 18:32:34 -0500 Subject: [PATCH 1/4] Add dynamic form fields for array alignment adjustment Updated the HTML form and related JavaScript to make some inputs dynamic, depending on checkbox values. Introduced a new JavaScript file "updated-alignment-position-fields.js" to handle changes in form field values based on user inputs. The changes allow users to dynamically adjust the array alignment position and automatically update other related fields. An event listener has been added to handle real-time changes in "sub depth relative to mains on x-axis" and "units" fields. This allows for a more interactive, use-friendly experience. --- index.html | 202 +++++++++++++++++++++-- src/main.js | 8 +- src/updated-alignment-position-fields.js | 42 +++++ 3 files changed, 237 insertions(+), 15 deletions(-) create mode 100644 src/updated-alignment-position-fields.js diff --git a/index.html b/index.html index 59fcfe0..506a746 100644 --- a/index.html +++ b/index.html @@ -1,18 +1,192 @@ - - - - + + + Vite App - - - -
- -
- - + + + + + + + +
+
+
+

Select an Alignment Position

+
+ +
+ +
+
+ +
+
+ Center + +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ + +
+
+ + +
+
+
+ +
+ +
+
+ + +
+
+ + +
+
+
+
+ +
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
+ + diff --git a/src/main.js b/src/main.js index f17b258..79fdc56 100644 --- a/src/main.js +++ b/src/main.js @@ -1,4 +1,5 @@ import './index.css' +import './updated-alignment-position-fields' import * as THREE from 'three'; import {OrbitControls} from 'three/addons/controls/OrbitControls.js'; import WebGL from 'three/addons/capabilities/WebGL.js'; @@ -35,7 +36,12 @@ mirroredMain.add(lineMirroredMain); mirroredMain.position.set(0, -mainY, 10); scene.add(mirroredMain); -let subLocationX = 1.5; +const subConfigCheckbox = document.getElementById("subConfigCheckbox"); +const subDepthInput = document.getElementById("sx"); +let subLocationX = 0; +subDepthInput.addEventListener('input', (event) => { + let subLocationX = event.target.value; +}); const subDimensions = {depth: 1, width: 1, height: 1}; const subGeometry = new THREE.BoxGeometry(subDimensions.width, subDimensions.height, subDimensions.depth); const subMaterial = new THREE.MeshBasicMaterial({color: 0x0000ff}); diff --git a/src/updated-alignment-position-fields.js b/src/updated-alignment-position-fields.js new file mode 100644 index 0000000..1c0a7db --- /dev/null +++ b/src/updated-alignment-position-fields.js @@ -0,0 +1,42 @@ +document.addEventListener("DOMContentLoaded", function() { + const metersRadio = document.getElementById("meters-radio"); + const feetRadio = document.getElementById("feet-radio"); + const seatedRadio = document.getElementById("seated-radio"); + const standingRadio = document.getElementById("standing-radio"); + const form = document.getElementById('alignment-position-form'); + const xoffCheckbox = document.getElementById('xoff'); + + function updateRadioValues() { + if (metersRadio.checked) { + seatedRadio.value = "1.26"; + standingRadio.value = "1.623"; + } else if (feetRadio.checked) { + seatedRadio.value = "4.13"; + standingRadio.value = "5.32"; + } + } + metersRadio.addEventListener("change", updateRadioValues); + feetRadio.addEventListener("change", updateRadioValues); + + updateRadioValues(); // Initialize the radio button values on page load + + form.addEventListener('submit', function(event) { + event.preventDefault(); + const formData = new FormData(form); + const searchParams = new URLSearchParams(formData); + if (!form.querySelector('#subConfigCheckbox').checked) { + const fields = ["as", "abz", "sy", "axf", "axl", "az"]; // replace with actual ids of your inputs + fields.forEach(field => { + if (searchParams.has(field)) { + searchParams.delete(field); + } + }); + } + + if (!xoffCheckbox.checked) { + searchParams.delete('ad'); + } + + window.location = form.getAttribute('action') + '?' + searchParams.toString(); + }); +}); \ No newline at end of file From 4c3803bfff29564711bd3feaf60106f1f77bb2a6 Mon Sep 17 00:00:00 2001 From: Nathan Lively <60303904+LiveNathan@users.noreply.github.com> Date: Thu, 19 Oct 2023 18:49:20 -0500 Subject: [PATCH 2/4] "Corrected and animated submarine movement in main.js" This commit fixes a bug where the sub's X position was not updating and the scene not re-rendering due to missing code in the event listener. A conversion from the input event value into a number was also added for correct positioning calculation. Now the submarine properly moves along the x-axis on input and the animation is triggered on each change. --- src/main.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.js b/src/main.js index 79fdc56..57e2e68 100644 --- a/src/main.js +++ b/src/main.js @@ -40,7 +40,9 @@ const subConfigCheckbox = document.getElementById("subConfigCheckbox"); const subDepthInput = document.getElementById("sx"); let subLocationX = 0; subDepthInput.addEventListener('input', (event) => { - let subLocationX = event.target.value; + let subLocationX = Number(event.target.value); + sub.position.x = -subDimensions.depth / 2 + subLocationX; // Update sub's x position here. + animate(); }); const subDimensions = {depth: 1, width: 1, height: 1}; const subGeometry = new THREE.BoxGeometry(subDimensions.width, subDimensions.height, subDimensions.depth); From 7fa5af02a65e0cef79dcc5337ffc439c7cc8a8ed Mon Sep 17 00:00:00 2001 From: Nathan Lively <60303904+LiveNathan@users.noreply.github.com> Date: Thu, 19 Oct 2023 19:28:55 -0500 Subject: [PATCH 3/4] Refactor cube creation and positioning in main.js This commit encompasses a significant refactor of the cube creation and positioning in the main.js file. Originally, the cubes were created and placed directly within the main script. Now, I have introduced a utility class, "Location", for encapsulating a 3D location (x, y, z), and a helper function, "createCube", to portion out the creation of cubes. This enhancement adds more readability, maintains code cleanliness, and allows easy reusability of the logic for creating a cube. --- src/main.js | 74 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/src/main.js b/src/main.js index 57e2e68..4d36227 100644 --- a/src/main.js +++ b/src/main.js @@ -18,42 +18,62 @@ addAxes(); const labelRenderer = addAxesLabels(); // OBJECTS -const geometry = new THREE.BoxGeometry(); -const material = new THREE.MeshBasicMaterial({color: 0xff0000}); -const main = new THREE.Mesh(geometry, material); -const edges = new THREE.EdgesGeometry(geometry); -const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({color: 0x000000})); -main.add(line); -let mainY = 20; -main.position.set(0, mainY, 10); -scene.add(main); - -const mirroredMainMaterial = new THREE.MeshBasicMaterial({color: 0xff0000}); -const mirroredMain = new THREE.Mesh(geometry, mirroredMainMaterial); -const edgesMirroredMain = new THREE.EdgesGeometry(geometry); -const lineMirroredMain = new THREE.LineSegments(edgesMirroredMain, new THREE.LineBasicMaterial({color: 0x000000})); -mirroredMain.add(lineMirroredMain); -mirroredMain.position.set(0, -mainY, 10); -scene.add(mirroredMain); +class Location { + constructor(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + } +} + +function createCube(location, color) { + const geometry = new THREE.BoxGeometry(); + const material = new THREE.MeshBasicMaterial({color: color}); + const mesh = new THREE.Mesh(geometry, material); + const edges = new THREE.EdgesGeometry(geometry); + const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({color: 0x000000})); + mesh.add(line); + mesh.position.set(location.x, location.y, location.z); + scene.add(mesh); + return mesh; +} + +let mainLocation = new Location(0, 20, 10); +createCube(mainLocation, 0xff0000); + +let mainMirrorLocation = new Location(0, -20, 10); +createCube(mainMirrorLocation, 0xff0000); const subConfigCheckbox = document.getElementById("subConfigCheckbox"); +let subConfigurationCenter = !subConfigCheckbox.checked; + +const subDimensions = {depth: 1, width: 1, height: 1}; +let subLocation = new Location(-subDimensions.depth / 2, 0, subDimensions.height / 2) +if (subConfigurationCenter) { + subLocation.y = 0; +} else { + subLocation.y = mainLocation.y; +} + +let sub = createCube(subLocation, 0x0000ff); + + + + +subConfigCheckbox.addEventListener('change', (event) => { + subConfigurationCenter = event.target.checked; + console.log(subConfigurationCenter) +}); const subDepthInput = document.getElementById("sx"); let subLocationX = 0; subDepthInput.addEventListener('input', (event) => { - let subLocationX = Number(event.target.value); + subLocationX = Number(event.target.value); sub.position.x = -subDimensions.depth / 2 + subLocationX; // Update sub's x position here. animate(); }); -const subDimensions = {depth: 1, width: 1, height: 1}; -const subGeometry = new THREE.BoxGeometry(subDimensions.width, subDimensions.height, subDimensions.depth); -const subMaterial = new THREE.MeshBasicMaterial({color: 0x0000ff}); -const sub = new THREE.Mesh(subGeometry, subMaterial); -const edgesSub = new THREE.EdgesGeometry(geometry); -const lineSub = new THREE.LineSegments(edgesSub, new THREE.LineBasicMaterial({color: 0x000000})); -sub.add(lineSub); -sub.position.set(-subDimensions.depth / 2 + subLocationX, 0, subDimensions.height / 2); -scene.add(sub); + +// FUNCTIONS function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); From 4ca5a86498f9c3cbebf8bfa4a398ebd372ffca3c Mon Sep 17 00:00:00 2001 From: Nathan Lively <60303904+LiveNathan@users.noreply.github.com> Date: Thu, 19 Oct 2023 19:55:56 -0500 Subject: [PATCH 4/4] Refactor main.js to improve code readability The code's structure was rearranged to clarify what each section does. Some parts have been repositioned and others extracted into seperate functions to make it easier to understand. The 'Location' class was moved to the top, and event listeners were moved to the bottom. Moreover, the inline code for the 'sub' y location setting was extracted into a separate function 'setSubLocationY', resulting in more straightforward, easier-to-read code. --- src/main.js | 97 +++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/src/main.js b/src/main.js index 4d36227..e787dc3 100644 --- a/src/main.js +++ b/src/main.js @@ -4,6 +4,13 @@ import * as THREE from 'three'; import {OrbitControls} from 'three/addons/controls/OrbitControls.js'; import WebGL from 'three/addons/capabilities/WebGL.js'; import {CSS2DRenderer, CSS2DObject} from 'three/addons/renderers/CSS2DRenderer.js'; +class Location { + constructor(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + } +} // SETUP const scene = new THREE.Scene(); @@ -17,62 +24,23 @@ setupControls(); addAxes(); const labelRenderer = addAxesLabels(); -// OBJECTS -class Location { - constructor(x, y, z) { - this.x = x; - this.y = y; - this.z = z; - } -} - -function createCube(location, color) { - const geometry = new THREE.BoxGeometry(); - const material = new THREE.MeshBasicMaterial({color: color}); - const mesh = new THREE.Mesh(geometry, material); - const edges = new THREE.EdgesGeometry(geometry); - const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({color: 0x000000})); - mesh.add(line); - mesh.position.set(location.x, location.y, location.z); - scene.add(mesh); - return mesh; -} +// PAGE ELEMENTS +const subConfigCheckbox = document.getElementById("subConfigCheckbox"); +const subDepthInput = document.getElementById("sx"); +// OBJECTS let mainLocation = new Location(0, 20, 10); createCube(mainLocation, 0xff0000); let mainMirrorLocation = new Location(0, -20, 10); createCube(mainMirrorLocation, 0xff0000); -const subConfigCheckbox = document.getElementById("subConfigCheckbox"); -let subConfigurationCenter = !subConfigCheckbox.checked; - +let subConfigurationLR = subConfigCheckbox.checked; const subDimensions = {depth: 1, width: 1, height: 1}; let subLocation = new Location(-subDimensions.depth / 2, 0, subDimensions.height / 2) -if (subConfigurationCenter) { - subLocation.y = 0; -} else { - subLocation.y = mainLocation.y; -} - +setSubLocationY(subConfigurationLR); let sub = createCube(subLocation, 0x0000ff); - - - -subConfigCheckbox.addEventListener('change', (event) => { - subConfigurationCenter = event.target.checked; - console.log(subConfigurationCenter) -}); -const subDepthInput = document.getElementById("sx"); -let subLocationX = 0; -subDepthInput.addEventListener('input', (event) => { - subLocationX = Number(event.target.value); - sub.position.x = -subDimensions.depth / 2 + subLocationX; // Update sub's x position here. - animate(); -}); - - // FUNCTIONS function animate() { requestAnimationFrame(animate); @@ -91,8 +59,6 @@ if (WebGL.isWebGLAvailable()) { } -window.addEventListener('resize', onWindowResize, false); - function setupCamera(container) { const camera = new THREE.PerspectiveCamera(75, container.offsetWidth / container.offsetHeight, 0.1, 1000); camera.up.set(0, 0, 1); @@ -152,8 +118,43 @@ function addAxesLabels() { return labelRenderer; } +function createCube(location, color) { + const geometry = new THREE.BoxGeometry(); + const material = new THREE.MeshBasicMaterial({color: color}); + const mesh = new THREE.Mesh(geometry, material); + const edges = new THREE.EdgesGeometry(geometry); + const line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({color: 0x000000})); + mesh.add(line); + mesh.position.set(location.x, location.y, location.z); + scene.add(mesh); + return mesh; +} + +function setSubLocationY(subConfigurationLR) { + if (subConfigurationLR) { + return mainLocation.y; + } else { + return 0; + } +} + function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); -} \ No newline at end of file +} + +// EVENT LISTENERS +window.addEventListener('resize', onWindowResize, false); + +subConfigCheckbox.addEventListener('change', (event) => { + subConfigurationLR = event.target.checked; + sub.position.y = setSubLocationY(subConfigurationLR); + animate(); +}); + +subDepthInput.addEventListener('input', (event) => { + let subLocationX = Number(event.target.value); + sub.position.x = -subDimensions.depth / 2 + subLocationX; // Update sub's x position here. + animate(); +}); \ No newline at end of file