Customizing the UI
Relevant source files
The following files were used as context for generating this wiki page:
The user interface of hdrify is a modern, minimalist single-page application built with vanilla HTML, CSS, and JavaScript. It is designed to be responsive and intuitive, featuring a "glass-morphism" aesthetic. Customizing the UI involves modifying the static frontend files located in the static/ directory.
This document outlines the structure, styling, and client-side logic of the UI, providing a guide for developers looking to alter its appearance and behavior. The backend, built with Rust and Warp, serves these static files and provides a single API endpoint for image processing, but all visual aspects are controlled by the frontend code.
Sources: README.md:3-4, README.md:29-30, src/main.rs:188-189
Core UI Architecture
The application follows a simple client-server model where the Rust backend serves the static frontend assets and handles the image processing requests. The frontend is self-contained within the static directory.
This diagram illustrates the high-level architecture.
Sources: src/main.rs:188-197, static/script.js:255-262
HTML Structure
The UI's foundation is static/index.html. It defines the main structural elements, including the header, upload area, image display, controls, and an examples section. Customization of the layout or addition of new static elements should start here.
The diagram below shows the main DOM components and their nesting.
Sources: static/index.html:11-80
Key HTML Elements
The following table lists the primary container elements and their roles, identified by their IDs. These IDs are used by static/script.js to manipulate the DOM.
| ID | Element | Description |
|---|---|---|
uploadArea | div | The initial drag-and-drop area for file uploads. |
imageInput | input[type=file] | The hidden file input, triggered by clicks on uploadArea. |
imageDisplay | div | Container for the processed image and processing overlay. Hidden by default. |
resultImage | img | Displays the original and processed image. |
processingOverlay | div | Shows a spinner while the image is being processed on the backend. |
controls | section | Container for the HDR slider, download, and reset buttons. Hidden by default. |
hdrSlider | input[type=range] | The slider to control the HDR intensity level from 0.5 to 3.0. |
hdrValue | span | Displays the current numerical value of the HDR slider. |
downloadButton | a | The button to download the processed image. |
resetButton | button | The button to reset the UI to its initial state. |
error | div | Container for displaying error messages. |
Sources: static/index.html:26-69, static/script.js:10-21
Styling and Theming (CSS)
All visual styling is defined in static/style.css. The stylesheet uses modern CSS features, a clean color palette, and responsive design principles. The "glass-morphism" effect is achieved using backdrop-filter: blur(10px);.
Sources: static/style.css:291-292, README.md:3
Color Palette
The UI uses a consistent and muted color palette. To change the theme, modify these color values.
| Color | Usage | Description |
|---|---|---|
#ffffff | body background | White |
#1f2937 | h1, body text, button hover | Dark Gray/Blue |
#374151 | Links, labels, download button bg | Medium Gray/Blue |
#6b7280 | Descriptions, paragraphs, link hover | Light Gray |
#e5e7eb | Borders, slider track, disabled bg | Very Light Gray |
#dc2626 | .error text | Red |
Sources: static/style.css:8-10, static/style.css:20-22, static/style.css:32-34, static/style.css:87-89, static/style.css:143-145, static/style.css:223-225
Typography
The font stack prioritizes the system's modern UI font for a native feel.
font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, sans-serif;
Sources: static/style.css:6-8
Component Styling
Key interactive elements have distinct styles that can be customized.
Buttons:
Shared styles are defined in .btn, with specific overrides for .reset-btn and .download-btn. The disabled state for the download button is handled with :not([href]).
/* static/style.css:192-201 */
.btn {
padding: 0.5rem 1rem;
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
line-height: 1.5;
border: 1px solid;
text-decoration: none;
display: inline-block;
font-family: inherit;
}
Sources: static/style.css:192-201
HDR Slider:
The slider is custom-styled for a consistent look across browsers, targeting -webkit-slider-thumb and -moz-range-thumb.
/* static/style.css:154-164 */
#hdrSlider {
width: 200px;
height: 4px;
background: #e5e7eb;
outline: none;
-webkit-appearance: none;
cursor: pointer;
transition: all 0.2s ease;
}
Sources: static/style.css:154-164
Responsive Design
The UI adapts to smaller screens using a media query that triggers at a max-width of 640px. This simplifies the layout by stacking controls vertically and reducing font sizes and padding.
/* static/style.css:334-336 */
@media (max-width: 640px) {
/* ... */
}
Sources: static/style.css:334-379
Client-Side Interactivity (JavaScript)
The file static/script.js controls all frontend logic. It uses a single class, HDRify, to encapsulate state and behavior.
The HDRify Class
On DOMContentLoaded, a new instance of the HDRify class is created. The constructor initializes element references and sets up all necessary event listeners.
This diagram shows the main properties and methods of the HDRify class.
Sources: static/script.js:1-382
UI State Flow
The UI transitions between three main states: Upload, Processing, and Display. The HDRify class manages these transitions with smooth animations.
This flowchart shows the user journey and UI state changes.
API Interaction
When an image is uploaded or the slider is adjusted, the processImage method is called. It sends a POST request to the /upload endpoint with the image data and HDR value.
The following sequence diagram details the API communication flow.
Conclusion
Customizing the hdrify UI is a straightforward process focused on modifying the static assets in the static/ directory. By editing index.html, developers can change the structure; by altering style.css, they can redefine the entire visual theme; and by adjusting script.js, they can modify the application's interactive behavior and state management. The clear separation between the frontend presentation and the backend processing logic allows for flexible and extensive UI customization without needing to touch the Rust codebase.