Frontend Architecture
Relevant source files
The following files were used as context for generating this wiki page:The frontend of hdrify is a modern, minimalist single-page application built with vanilla HTML, CSS, and JavaScript. It provides an intuitive interface for users to upload an SDR image, adjust its HDR intensity in real-time, and download the processed result. The architecture prioritizes simplicity, performance, and a smooth user experience through responsive design, state-driven UI updates, and client-side optimizations.
The entire client-side logic is encapsulated within a single JavaScript class, HDRify, which manages the application's state, user interactions, and communication with the backend API. The styling employs contemporary CSS features like backdrop-filter to achieve a glass-morphism effect, complemented by smooth transitions for a polished feel.
Sources: README.md:3-5, static/script.js, static/index.html
Core Components
The user interface is structured with semantic HTML elements, each serving a distinct purpose in the application's workflow.
Sources: static/index.html:11-78
| Element ID | Tag | Description |
|---|---|---|
uploadArea | <div> | The initial view for image uploads. Supports both click-to-select and drag-and-drop. |
imageInput | <input type="file"> | A hidden file input triggered by the uploadArea. Accepts JPEG, PNG, and WebP formats. |
imageDisplay | <div> | A container that appears after an image is uploaded, holding the resultImage and processingOverlay. |
resultImage | <img> | Displays the processed HDR image. Also used to show a blurred version of the original during processing. |
processingOverlay | <div> | An overlay with a spinner, shown on top of the imageDisplay while the backend is processing the image. |
controls | <section> | A container for user controls that appears with the imageDisplay. |
hdrSlider | <input type="range"> | A slider allowing the user to adjust the HDR intensity from 0.5 to 3.0. |
hdrValue | <span> | Displays the current numerical value of the hdrSlider. |
downloadButton | <a> | A button to download the processed image. It is disabled until a successful process is complete. |
resetButton | <button> | A button to reset the application to its initial state. |
error | <div> | A container to display error messages to the user. |
Client-Side Logic (HDRify Class)
All frontend interactivity is managed by the HDRify class defined in static/script.js. This class-based approach encapsulates state, DOM element references, and event handling logic into a single, organized unit.
Sources: static/script.js:1-395
Class Structure
The HDRify class diagram below illustrates its properties and methods.
This diagram shows the properties and methods of the HDRify class, which controls all frontend functionality.
Sources: static/script.js:1-395
State Management
The application's state is managed through several key properties within the HDRify instance.
| Property | Type | Description |
|---|---|---|
currentImageData | string | The base64-encoded string of the original uploaded image, without the prefix. |
originalImageUrl | string | A data URL for the original uploaded image, used for previews. |
originalFileName | string | The name of the original file, used for generating the download filename. |
imageCache | Map | Caches processed image data with the HDR value as the key to avoid re-fetching. |
processingTimeout | number | A timeout ID used for debouncing slider input events. |
Sources: static/script.js:3-7
User Interaction and State Flow
The application follows a clear, linear flow from image upload to download. The UI transitions smoothly between states to provide a responsive user experience.
This flowchart illustrates the primary user workflow.
Key Interactions
- Image Upload: Users can click the upload area or use drag-and-drop. Keyboard users can trigger the file input with
EnterorSpace.
Sources: static/script.js:34-80 - File Validation: Before processing,
handleFilevalidates the file's MIME type (image/jpeg,image/png,image/webp) and size (max 10MB).
Sources: static/script.js:150-174 - HDR Adjustment: The
hdrSliderinput is debounced using asetTimeoutof 250ms. This prevents excessive API calls while the user is dragging the slider. A new processing request is only sent after the user pauses.
Sources: static/script.js:108-116 - Reset: The
reset()method can be triggered by the "Reset" button or by pressing theEscapekey, returning the UI to its initial state.
Sources: static/script.js:119-128, static/script.js:348-386
API Interaction
The frontend communicates with the Rust backend via a single API endpoint to process the image.
Endpoint: POST /upload
This endpoint accepts the image data and HDR value, processes the image using ImageMagick on the server, and returns the base64-encoded result.
Sources: src/main.rs:189-193, README.md:65-71
Request
The processImage function in script.js constructs a POST request to /upload with a Content-Type of application/x-www-form-urlencoded. The body is built using URLSearchParams.
| Parameter | Type | Description |
|---|---|---|
image | string | The base64-encoded image data (without prefix). |
hdr_value | string | The desired HDR intensity value (e.g., "1.5"). |
Sources: static/script.js:275-283, src/main.rs:19-24
Response
The server responds with a JSON object containing the status of the operation and, on success, the processed image data.
{
"success": true,
"message": "Image processed successfully",
"image_data": "base64_encoded_hdr_image"
}
Sources: src/main.rs:10-15, src/main.rs:125-129
Client-Server Sequence
The following diagram shows the sequence of events when a user adjusts the HDR slider.
This diagram illustrates the API call flow, including the client-side caching mechanism.
Sources: static/script.js:231-314, src/main.rs:17-152
Performance and User Experience
The frontend incorporates several features to enhance performance and usability.
- Client-Side Caching: Processed images are stored in the
imageCacheMap. If a user adjusts the slider to a value that has already been processed, the image is retrieved directly from the cache, providing an instant preview and avoiding a redundant API call.
Sources: static/script.js:7, 235-252 - Smooth Transitions: CSS transitions on
opacityandfilter: blur()are used to create a seamless flow between the upload view and the image processing view. During processing, a heavily blurred version of the original image is shown behind a spinner, which then sharpens into the final result.
Sources: static/script.js:188-201, 255-260, static/style.css:84-88, 303-308 - Responsive Design: The application uses CSS media queries to adapt the layout for smaller screens, ensuring usability on mobile devices.
Sources: static/style.css:258-297 - Accessibility: The UI includes ARIA attributes (
role,aria-label,aria-live) and keyboard navigation support to improve accessibility.
Sources: static/index.html:25, 33, 44, 50, static/script.js:37-43, 124-128