diff --git a/README.md b/README.md index 23e1ddf..7ce02fe 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,10 @@ Three types of interferer objects are displayed differently. ### Extra +```F``` - Toggle browser fullscreen mode (shows canvas). + +```H``` - Toggle in-canvas hints for user actions. + ```Z``` - Toggle between quality and performance (toggles shadow blur effect off or on). ## Limitations 🔒 diff --git a/optics/script.js b/optics/script.js index 85c6e71..d69e4e1 100644 --- a/optics/script.js +++ b/optics/script.js @@ -1339,6 +1339,8 @@ const misclickSound = document.getElementById("sound-misclick"); const switchSound = document.getElementById("sound-switch"); let fullscreen = false; let glow = true; +let hint = true; +let textAnimation = new NumberAnimation([new AnimationKeyframe(0, 0), new AnimationKeyframe(25, 0), new AnimationKeyframe(125, 1), new AnimationKeyframe(150, 1), new AnimationKeyframe(250, 0)], 250, 0, interpolateLinear, true); const pointOrigin = new Point(0, 0); const cameraPosition = pointOrigin.clone(); const targetCameraPosition = cameraPosition.clone(); @@ -1645,7 +1647,7 @@ function render() { ctx.restore(); } - // draw text overlay if user is currently dragging an object + // draw user action text overlay if user is currently dragging an object if (scene.draggedObject !== false) { let text = undefined; let doDrawText = true; @@ -1724,6 +1726,7 @@ function render() { } // find the width of the text in pixels to be used for centering the text + ctx.font = "50px Verdana"; let textWidth = ctx.measureText(text).width; // render the text overlay's background @@ -1733,15 +1736,101 @@ function render() { // render the text overlay's text ctx.fillStyle = "#ffffff"; - ctx.font = "50px Verdana"; ctx.fillText(text, scene.draggedObject.position.x - textWidth / 2, scene.draggedObject.position.y + 25 + extraSpace); } } // go from world space to canvas space ctx.resetTransform(); - ctx.shadowBlur = 0; + + // draw hint text overlay if hint is set to true + if (hint) { + let text = undefined; + + if (mouseAction === MouseAction.drag) { + if (scene.draggedObject === false) { + text = "Click and drag an object to change the position."; + } else { + if (!scene.draggedObject.hasOwnProperty("positionAnimation") || scene.draggedObject.positionAnimation === undefined) { + text = "Drag the object to change the position."; + } else { + text = "The object's position animation is currently in progress."; + } + } + } else if (mouseAction === MouseAction.dragX) { + if (scene.draggedObject === false) { + text = "Click and drag an object horizontally to change the position."; + } else { + if (!scene.draggedObject.hasOwnProperty("positionAnimation") || scene.draggedObject.positionAnimation === undefined) { + text = "Drag the object horizontally to change the position."; + } else { + text = "The object's position animation is currently in progress."; + } + } + } else if (mouseAction === MouseAction.dragY) { + if (scene.draggedObject === false) { + text = "Click and drag an object vertically to change the position."; + } else { + if (!scene.draggedObject.hasOwnProperty("positionAnimation") || scene.draggedObject.positionAnimation === undefined) { + text = "Drag the object vertically to change the position."; + } else { + text = "The object's position animatoin is currently in progress."; + } + } + } else if (mouseAction === MouseAction.rotate) { + if (scene.draggedObject === false) { + text = "Click and mouse-drag an object to change the rotation."; + } else { + if (!scene.draggedObject.hasOwnProperty("rotationAnimation") || scene.draggedObject.rotationAnimation === undefined) { + text = "Drag the mouse to change the rotation."; + } else { + text = "The object's rotation animation is currently in progress."; + } + } + } else if (mouseAction === MouseAction.change) { + if (scene.draggedObject === false) { + text = "Click and mouse-drag an object to change the property."; + } else if (scene.draggedLaser !== false) { + text = "Drag the mouse vertically to switch the power."; + } else if (scene.draggedMirror !== false) { + text = "Drag the mouse vertically to change the type of behavior of light."; + } else if (scene.draggedGuide !== false) { + text = "Drag the mouse vertically to switch the tool."; + } + } else if (mouseAction === MouseAction.laser) { + text = "Click and hold to create a laser of a certain rotation."; + } else if (mouseAction === MouseAction.interferer) { + text = "Click and hold to create an interferer of a certain type."; + } else if (mouseAction === MouseAction.guide) { + text = "Click and hold to create a ruler or protractor of a certain rotation."; + } + + ctx.font = "50px Verdana"; + let textWidth = ctx.measureText(text).width; + + ctx.save(); + ctx.beginPath(); + ctx.rect(960 - 600 - 5, 50 - 25 - 25, 1200 + 10, 50 + 50); + ctx.clip(); + + if (textWidth >= 1200) { + let textNumber = textAnimation.getValues(); + ctx.translate((textWidth / 2 - 600) * (1 - 2 * textNumber), 0); + textAnimation.animate(); + } + + // render the text overlay's background + ctx.shadowBlur = 0; + ctx.fillStyle = "#000000"; + ctx.fillRect(960 - textWidth / 2 - 5, 50 - 25 - 5, textWidth + 10, 50 + 10); + + // render the text overlay's text + ctx.fillStyle = "#ffffff"; + ctx.fillText(text, 960 - textWidth / 2, 50 + 25); + ctx.restore(); + } + // go from canvas space to button space ctx.translate(0, 540); @@ -2482,6 +2571,8 @@ function keydown(event) { } fullscreen = !fullscreen; + } else if (eventKey.toUpperCase() === "H") { + hint = !hint; } else if (eventKey.toUpperCase() === "Z") { glow = !glow; }