Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 188 additions & 14 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,192 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Vite App</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<div id="container" class="h-screen w-screen">
<canvas id="canvas" class="absolute z-1"></canvas>
</div>
<script type="module" src="./src/main.js"></script>
</body>
<!-- <style>-->
<!-- body {-->
<!-- margin: 0;-->
<!-- }-->
<!-- </style>-->
</head>
<body class="h-full">
<div class="h-screen">
<main class="flex-1 py-6">
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
<h1 class="text-2xl font-semibold text-gray-900">Select an Alignment Position</h1>
</div>

<form id="alignment-position-form" th:object="${alignmentPositionDTO}"
th:action="@{/align/pre-alignment/{id}(id=${alignmentPositionDTO.preAlignmentId})}"
method="get" class="max-w-7xl bg-white p-6 mb-4 rounded-md">

<div class="mb-6 flex items-center w-full sm:w-1/2">
<div class="w-1/3">
<label class="mb-1 block pr-4 font-bold text-gray-500 text-right" for="subConfigCheckbox">Sub
configuration</label>
</div>
<div class="flex items-center">
<span class="mr-3 text-gray-900 dark:text-gray-300">Center</span>
<label class="relative inline-flex cursor-pointer items-center">
<input id="subConfigCheckbox" type="checkbox" value="true" name="lr" class="peer sr-only"
@change="checked = $event.target.checked"/>
<span class="peer h-6 w-11 rounded-full bg-gray-200 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-blue-500 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:border-gray-600 dark:bg-gray-700 dark:peer-focus:ring-blue-800"></span>
<span class="ml-3 text-gray-900 dark:text-gray-300">L/R</span>
</label>
</div>
</div>

<div class="flex flex-wrap" x-show="checked">
<div class="mb-6 flex items-center w-full sm:w-1/2">
<div class="relative w-1/3">
<label class="mb-1 block pr-4 text-3xl font-bold text-red-500 text-right" for="as">A</label>
</div>
<div class="w-2/3">
<input class="w-full appearance-none rounded-md border-2 border-red-500 bg-gray-200 pl-4 md:pl-4 py-2 leading-tight text-gray-700 focus:border-blue-500 focus:bg-white focus:outline-none"
id="as" name="as" type="number" placeholder="Array span" min="0.1" step="0.01"
x-bind:required="checked"/>
</div>
</div>

<div class="mb-6 flex items-center w-full sm:w-1/2">
<div class="relative w-1/3">
<label class="mb-1 block pr-4 text-3xl font-bold text-orange-500 text-right" for="abz">B</label>
</div>
<div class="w-2/3">
<input class="w-full appearance-none rounded-md border-2 border-orange-500 bg-gray-200 pl-4 md:pl-4 py-2 leading-tight text-gray-700 focus:border-blue-500 focus:bg-white focus:outline-none"
id="abz" name="abz" type="number" placeholder="Array bottom height" min="0.1" step="0.01"
x-bind:required="checked"/>
</div>
</div>
</div>

<div class="flex flex-wrap">
<div id="sub-distance-from-center-container" class="mb-6 flex items-center w-full sm:w-1/2"
x-show="checked">
<div class="w-1/3">
<label class="mb-1 block pr-4 text-3xl font-bold text-yellow-500 text-right" for="sy">C</label>
</div>
<div class="w-2/3">
<input class="w-full appearance-none rounded-md border-2 border-yellow-500 bg-gray-200 pl-4 md:pl-4 py-2 leading-tight text-gray-700 focus:border-blue-500 focus:bg-white focus:outline-none"
id="sy" name="sy" type="number" placeholder="Sub distance from center" min="0.1"
step="0.01" x-bind:required="checked"/>
</div>
</div>

<div class="mb-6 flex items-center w-full sm:w-1/2">
<div class="w-1/3">
<label class="mb-1 block pr-4 text-3xl font-bold text-green-500 text-right" for="sx">D</label>
</div>
<div class="w-2/3">
<input class="w-full appearance-none rounded-md border-2 border-green-500 bg-gray-200 pl-4 py-2 leading-tight text-gray-700 focus:border-blue-500 focus:bg-white focus:outline-none"
id="sx" name="sx" type="number" placeholder="Sub depth relative to mains on x-axis" min="-100.1"
step="0.01" required/>
</div>
</div>
</div>

<div class="flex flex-wrap" x-show="checked">
<div class="mb-6 flex items-center w-full sm:w-1/2">
<div class="w-1/3">
<label class="mb-1 block pr-4 text-3xl font-bold text-blue-500 text-right" for="axf">E</label>
</div>
<div class="w-2/3">
<input class="w-full appearance-none rounded-md border-2 border-blue-500 bg-gray-200 pl-4 py-2 leading-tight text-gray-700 focus:border-blue-500 focus:bg-white focus:outline-none"
id="axf" name="axf" type="number" placeholder="Audience depth first row" min="0.1"
step="0.01" x-bind:required="checked"/>
</div>
</div>

<div class="mb-6 flex items-center w-full sm:w-1/2">
<div class="w-1/3">
<label class="mb-1 block pr-4 text-3xl font-bold text-indigo-500 text-right" for="axl">F</label>
</div>
<div class="w-2/3">
<input class="w-full appearance-none rounded-md border-2 border-indigo-500 bg-gray-200 pl-4 py-2 leading-tight text-gray-700 focus:border-blue-500 focus:bg-white focus:outline-none"
id="axl" name="axl" type="number" placeholder="Audience depth last row" min="0.1"
step="0.01" x-bind:required="checked"/>
</div>
</div>
</div>

<div class="flex flex-wrap">
<div id="audience-height-container" class="mb-6 flex items-center w-full sm:w-1/2" x-show="checked">
<label class="w-1/3 mb-1 block pr-4 font-bold text-gray-500 text-right">Audience</label>
<div class="flex">
<div class="mr-4 flex items-center">
<input id="seated-radio" type="radio" name="az" value="1.2"
class="h-4 w-4 border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600"
x-bind:required="checked"/>
<label for="seated-radio" class="ml-2 text-gray-900 dark:text-gray-300">Seated</label>
</div>
<div class="mr-4 flex items-center">
<input id="standing-radio" type="radio" name="az" value="1.6" checked
class="h-4 w-4 border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600"
x-bind:required="checked"/>
<label for="standing-radio" class="ml-2 text-gray-900 dark:text-gray-300">Standing</label>
</div>
</div>
</div>

<div id="unit-container" class="mb-6 flex items-center w-full sm:w-1/2">
<label class="w-1/3 mb-1 block pr-4 font-bold text-gray-500 text-right">Unit</label>
<div class="flex">
<div class="mr-4 flex items-center">
<input id="meters-radio" type="radio" name="u" th:field="*{u}"
th:value="${T(nathanlively.subalignercss.Models.Enums.UnitsEnum).METERS.abbreviation}"
checked
class="h-4 w-4 border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600"
x-bind:required="checked"/>
<label for="meters-radio" class="ml-2 text-gray-900 dark:text-gray-300">meters</label>
</div>
<div class="mr-4 flex items-center">
<input id="feet-radio" type="radio" name="u" th:field="*{u}"
th:value="${T(nathanlively.subalignercss.Models.Enums.UnitsEnum).FEET.abbreviation}"
class="h-4 w-4 border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600"
x-bind:required="checked"/>
<label for="feet-radio" class="ml-2 text-gray-900 dark:text-gray-300">feet</label>
</div>
</div>
</div>
</div>

<div class="flex flex-wrap" x-show="checked">
<div class="mb-6 flex items-center w-full sm:w-1/2">
<label for="xoff" class="w-1/3 mb-1 block pr-4 font-bold text-gray-500 text-right">Distances referenced from below array</label>
<div class="w-2/3">
<input id="xoff" class="h-5 w-5 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
name="xoff" type="checkbox" @change="xoffChecked = $event.target.checked"/>
</div>
</div>

<div id="array-depth-container" class="mb-6 flex items-center w-full sm:w-1/2" x-show="xoffChecked">
<div class="w-1/3">
<label class="mb-1 block pr-4 text-3xl font-bold text-violet-500 text-right" for="ad">G</label>
</div>
<div class="w-2/3">
<input class="w-full appearance-none rounded-md border-2 border-violet-500 bg-gray-200 pl-4 py-2 leading-tight text-gray-700 focus:border-blue-500 focus:bg-white focus:outline-none"
id="ad" name="ad" type="number" placeholder="Array depth" min="0.1" step="0.01" x-bind:required="xoffChecked"/>
</div>
</div>
</div>

<div class="mt-6 sm:mt-0 flex items-center w-full sm:w-1/2">
<div class="w-1/3"></div>
<div class="w-2/3">
<input class="w-full appearance-none rounded-md bg-blue-sa-500 hover:bg-blue-600 text-white font-bold py-2 px-4 leading-tight focus:outline-none focus:bg-blue-700"
type="submit" value="Submit"/> <!--should appear with default value "on"-->
</div>
</div>
</form>

<div class="max-w-7xl mx-auto px-4 py-4 sm:px-6 md:px-8">
<div id="container" class="w-full h-full">
<canvas id="canvas" class="absolute z-1"></canvas>
</div>
</div>
</main>
</div>
<script type="module" src="./src/main.js"></script>
</body>
</html>
89 changes: 59 additions & 30 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
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';
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();
Expand All @@ -16,36 +24,24 @@ setupControls();
addAxes();
const labelRenderer = addAxesLabels();

// PAGE ELEMENTS
const subConfigCheckbox = document.getElementById("subConfigCheckbox");
const subDepthInput = document.getElementById("sx");

// 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);

let subLocationX = 1.5;
let mainLocation = new Location(0, 20, 10);
createCube(mainLocation, 0xff0000);

let mainMirrorLocation = new Location(0, -20, 10);
createCube(mainMirrorLocation, 0xff0000);

let subConfigurationLR = subConfigCheckbox.checked;
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);
let subLocation = new Location(-subDimensions.depth / 2, 0, subDimensions.height / 2)
setSubLocationY(subConfigurationLR);
let sub = createCube(subLocation, 0x0000ff);

// FUNCTIONS
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
Expand All @@ -63,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);
Expand Down Expand Up @@ -124,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);
}
}

// 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();
});
42 changes: 42 additions & 0 deletions src/updated-alignment-position-fields.js
Original file line number Diff line number Diff line change
@@ -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();
});
});