Skip to content

Commit

Permalink
fixed object selection bug and added fullscreen mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Elixonus committed Jul 22, 2024
1 parent 96bf3ce commit 5ed552e
Showing 1 changed file with 59 additions and 53 deletions.
112 changes: 59 additions & 53 deletions optics/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,23 +514,32 @@ class Scene {
return mirrors;
}

/** get an array of objects that are within a distance of parameter point from a parameter array of objects */
static getCloseObjectsToPoint(p = pointOrigin, radius, objects = [], ) {
let closeObjects = [];

for (let n = 0; n < objects.length; n++) {
let object = objects[n];
let distanceToObject = distance(p, object.position);

if (distanceToObject < radius) {
closeObjects.push(object);
}
}

return closeObjects;
}

/** get the closest object from a parameter array of objects to a parameter point */
static getClosestObjectToPoint(p = pointOrigin, objects = [], distanceModifier = undefined) {
static getClosestObjectToPoint(p = pointOrigin, objects = []) {
let closestObject = undefined;
let distanceToClosestObject = undefined;

for (let n = 0; n < objects.length; n++) {
let object = objects[n];
let distanceToObject = distance(p, object.position);
let comparedDistance;

if (distanceModifier !== undefined) {
comparedDistance = distanceModifier(distanceToObject);
} else {
comparedDistance = distanceToObject;
}

if (closestObject === undefined || comparedDistance < distanceToClosestObject) {
if (closestObject === undefined || distanceToObject < distanceToClosestObject) {
closestObject = object;
distanceToClosestObject = distanceToObject;
}
Expand All @@ -547,8 +556,8 @@ class Scene {
}

/** get the closest mirror to a parameter point in the scene */
getClosestMirrorToPoint(p = pointOrigin, distanceModifier = undefined) {
let closest = Scene.getClosestObjectToPoint(p, this.mirrors, distanceModifier);
getClosestMirrorToPoint(p = pointOrigin) {
let closest = Scene.getClosestObjectToPoint(p, this.mirrors);
return closest;
}

Expand Down Expand Up @@ -1331,7 +1340,7 @@ const switchSound = document.getElementById("sound-switch");
let glow = true;
const pointOrigin = new Point(0, 0);
const cameraPosition = pointOrigin.clone();
const targetPosition = cameraPosition.clone();
const targetCameraPosition = cameraPosition.clone();
const mousePosition = pointOrigin.clone();
let mousePressed = false;
let mouseAction = MouseAction.drag;
Expand All @@ -1340,6 +1349,7 @@ let keysFired = false;
let keysHelp = 0;
let touch = false;
let mobilePanning = true;
let selectionIndex = 0;
const LASER_MAX_COLLISIONS = 50;
const DRAW_RANGE = 10000;
const scene = new Scene();
Expand All @@ -1351,6 +1361,7 @@ let deltaTime = 1000 / framerate;
let timeScale = 1;

// prevent right click registration
canvas.addEventListener("selectstart", (event) => event.preventDefault());
canvas.addEventListener("contextmenu", (event) => event.preventDefault());
clearButton.addEventListener("click", (event) => loadExample(0));
loadButton1.addEventListener("click", (event) => loadExample(1));
Expand Down Expand Up @@ -1419,44 +1430,44 @@ function render() {
// move the camera left, right, up, or down based on the pressed and held key

if (keysPressed.includes("ArrowLeft") || keysPressed.includes("a") || keysPressed.includes("A") || (mousePosition.x < -660 && mousePressed === true && touch === true && mobilePanning === true)) {
targetPosition.x -= 10 * timeScale;
targetCameraPosition.x -= 10 * timeScale;
}

if (keysPressed.includes("ArrowRight") || keysPressed.includes("d") || keysPressed.includes("D") || (mousePosition.x > 660 && mousePressed === true && touch === true && mobilePanning === true)) {
targetPosition.x += 10 * timeScale;
targetCameraPosition.x += 10 * timeScale;
}

if (keysPressed.includes("ArrowUp") || keysPressed.includes("w") || keysPressed.includes("W") || (mousePosition.y < -340 && mousePressed === true && touch === true && mobilePanning === true)) {
targetPosition.y -= 10 * timeScale;
targetCameraPosition.y -= 10 * timeScale;
}

if (keysPressed.includes("ArrowDown") || keysPressed.includes("s") || keysPressed.includes("S") || (mousePosition.y > 340 && mousePressed === true && touch === true && mobilePanning === true)) {
targetPosition.y += 10 * timeScale;
targetCameraPosition.y += 10 * timeScale;
}

targetPosition.x = clamp(targetPosition.x, -0.5 * DRAW_RANGE, 0.5 * DRAW_RANGE);
targetPosition.y = clamp(targetPosition.y, -0.5 * DRAW_RANGE, 0.5 * DRAW_RANGE);
targetCameraPosition.x = clamp(targetCameraPosition.x, -0.5 * DRAW_RANGE, 0.5 * DRAW_RANGE);
targetCameraPosition.y = clamp(targetCameraPosition.y, -0.5 * DRAW_RANGE, 0.5 * DRAW_RANGE);

// linearly interpolate the camera position from the target position
cameraPosition.interpolateToPointLinear(targetPosition, 1 - Math.pow(0.9, timeScale));
cameraPosition.interpolateToPointLinear(targetCameraPosition, 1 - Math.pow(0.9, timeScale));

// find the paths of collisions of the lasers in the scene as an array of arrays of point objects
let lasersCollisions = scene.getLasersCollisions();

// if the user is dragging a protractor, snap the position of the protractor to the position of the closest laser collision with mirror
if (scene.draggedGuide !== false && mouseAction === MouseAction.drag && scene.draggedObject instanceof Guide && Math.round(scene.draggedObject.guidance) === 1) {
let objects = [];
let positionObjects = [];
for (let n = 0; n < lasersCollisions.length; n++) {
objects.push({position: scene.lasers[n].position});
positionObjects.push({position: scene.lasers[n].position});
let laserCollisions = lasersCollisions[n];

for (let m = 0; m < laserCollisions.length; m++) {
let laserCollision = laserCollisions[m];
objects.push({position: laserCollision.position});
positionObjects.push({position: laserCollision.position});
}
}

let closest = Scene.getClosestObjectToPoint(scene.draggedObject.position, objects);
let closest = Scene.getClosestObjectToPoint(scene.draggedObject.position, positionObjects);

// do the position snap if the distance to the object is less than 50 pixels
if (closest !== false && closest.distanceToObject <= 50) {
Expand Down Expand Up @@ -1890,7 +1901,7 @@ function render() {
function loadExample(n) {
scene.reset();
// recenter the camera position
targetPosition.setTo(pointOrigin);
targetCameraPosition.setTo(pointOrigin);

switch (n) {
case 0:
Expand Down Expand Up @@ -2060,7 +2071,7 @@ function updateObjectTable() {
cell5.innerText = "(" + (Math.round(10 * object.position.x) / 10).toString() + ", " + (Math.round(-10 * object.position.y) / 10).toString() + ")";

let cell6 = row.insertCell(-1);
cell6.innerText = (Math.round(100 * modulus(object.rotation * 180 / Math.PI, 360)) / 100).toString() + " deg";
cell6.innerText = (Math.round(100 * modulus((2 * Math.PI - object.rotation) * 180 / Math.PI, 360)) / 100).toString() + " deg";
let cell7 = row.insertCell(-1);

if (object instanceof Mirror) {
Expand Down Expand Up @@ -2221,7 +2232,6 @@ function mousedown(event) {
}

if (touch === false) {
switchSound.currentTime = 0;
switchSound.play();
}

Expand All @@ -2240,7 +2250,6 @@ function mousedown(event) {
}

if (touch === false) {
switchSound.currentTime = 0;
switchSound.play();
}

Expand Down Expand Up @@ -2314,36 +2323,32 @@ function mousedown(event) {
};

let point = mousePosition.clone().addTo(cameraPosition);
let closestLaser = Scene.getClosestObjectToPoint(point, scene.lasers.filter(function (z) {
let lasers = Scene.getCloseObjectsToPoint(point, 200, scene.lasers.filter(function (z) {
return z.interactive;
}), distanceRandomizer);
let laser = undefined;

if (closestLaser !== false && closestLaser.distanceToObject <= 200) {
laser = [closestLaser.object];
} else {
laser = [];
}

let closestGuide = Scene.getClosestObjectToPoint(point, scene.guides.filter(function (z) {
}));
let mirrors = scene.getMirrorsWithPointInside(point).filter(function (z) {
return z.interactive;
});
let guides = Scene.getCloseObjectsToPoint(point, 300, scene.guides.filter(function (z) {
return z.interactive;
}), distanceRandomizer);
let guide = undefined;
}));
let objects = lasers.concat(mirrors, guides);
let object;

if (closestGuide !== false && closestGuide.distanceToObject <= 300) {
guide = [closestGuide.object];
if (objects.length === 0) {
object = false;
} else {
guide = [];
}
if (selectionIndex >= objects.length) {
selectionIndex = 0;
}

let closest = Scene.getClosestObjectToPoint(point, scene.getMirrorsWithPointInside(point).filter(function (z) {
return z.interactive;
}).concat(laser, guide), distanceRandomizer);
object = objects[selectionIndex];
selectionIndex++;
}

if (closest !== false) {
let object = closest.object;
if (object !== false) {
scene.setDraggedObjectTo(object);
object.dragOffset = point.subtractTo(object.position);
object.dragOffset = point.clone().subtractTo(object.position);
object.mousePositionOnDrag = mousePosition.clone();
object.dragPosition = object.position.clone();
object.dragRotation = object.rotation;
Expand All @@ -2357,12 +2362,10 @@ function mousedown(event) {
}

if (touch === false) {
clickSound.currentTime = 0;
clickSound.play();
}
} else {
if (touch === false) {
misclickSound.currentTime = 0;
misclickSound.play();
}
}
Expand All @@ -2376,7 +2379,6 @@ function mouseup(event) {
mousePressed = false;

if (scene.draggedObject !== false && touch === false) {
clickSound.currentTime = 0;
clickSound.play();
}

Expand Down Expand Up @@ -2457,6 +2459,10 @@ function keydown(event) {
loadExample(8);
} else if (eventKey === "9") {
loadExample(9);
} else if (eventKey.toUpperCase() === "F") {
if (canvas.requestFullscreen) {
canvas.requestFullscreen();
}
} else if (eventKey.toUpperCase() === "Z") {
glow = !glow;
}
Expand Down

0 comments on commit 5ed552e

Please sign in to comment.