about summary refs log tree commit diff stats
path: root/js/leibovitz/balance.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/leibovitz/balance.js')
-rw-r--r--js/leibovitz/balance.js103
1 files changed, 103 insertions, 0 deletions
diff --git a/js/leibovitz/balance.js b/js/leibovitz/balance.js
new file mode 100644
index 0000000..aeff62e
--- /dev/null
+++ b/js/leibovitz/balance.js
@@ -0,0 +1,103 @@
+/**
+ * White balance management module implementing temperature-based color adjustment.
+ * 
+ * Implements white balance adjustment using temperature-based RGB channel scaling.
+ * Provides non-linear temperature adjustment for natural color correction.
+ * 
+ * Implements the following design patterns:
+ * - Observer Pattern: state management and effect application
+ * - Factory Pattern: UI initialization
+ * - Strategy Pattern: temperature adjustment algorithm
+ * - Command Pattern: state reset operations
+ * 
+ * White balance adjustment process:
+ * 1. Convert temperature to ratio relative to neutral (6500K)
+ * 2. Apply non-linear scaling (0.2 factor) to red and blue channels
+ * 3. Warmer temps (<6500K) increase red, decrease blue
+ * 4. Cooler temps (>6500K) increase blue, decrease red
+ * 
+ * Features:
+ * - Temperature-based color adjustment
+ * - Non-linear response curve
+ * - Preserves green channel
+ * - Real-time updates
+ */
+
+const BalanceManager = {
+    // Private state
+    _observers: new Set(),
+    _slider: null,
+    _value: null,
+
+    /**
+     * Initializes the balance manager and sets up UI controls
+     */
+    init() {
+        this._slider = document.getElementById('balance-slider');
+        this._value = document.getElementById('balance-value');
+        this._setupEventListeners();
+    },
+
+    _setupEventListeners() {
+        this._slider.addEventListener('input', () => {
+            const value = this._slider.value;
+            this._value.textContent = `${value}K`;
+            this._notifyObservers();
+        });
+    },
+
+    _notifyObservers() {
+        this._observers.forEach(observer => observer(this.getCurrentBalance()));
+    },
+
+    /**
+     * Subscribes to balance state changes
+     * @param {Function} observer - Callback function for state changes
+     * @returns {Function} Unsubscribe function
+     */
+    subscribe(observer) {
+        this._observers.add(observer);
+        return () => this._observers.delete(observer);
+    },
+
+    /**
+     * Gets the current white balance temperature
+     * @returns {number} Current temperature in Kelvin (2000K-10000K)
+     */
+    getCurrentBalance() {
+        return parseInt(this._slider.value);
+    },
+
+    /**
+     * Applies white balance adjustment to an image
+     * And implements temperature-based RGB channel scaling with non-linear response
+     * @param {ImageData} imageData - Source image data
+     * @returns {ImageData} White balanced image data
+     */
+    applyBalance(imageData) {
+        const balance = this.getCurrentBalance();
+        if (!balance || balance === 6500) return imageData; // 6500K is neutral
+
+        const data = imageData.data;
+        const temperature = balance / 6500; // Convert to temperature ratio
+
+        for (let i = 0; i < data.length; i += 4) {
+            // Adjust red and blue channels based on temperature
+            // Warmer (lower K) increases red, decreases blue
+            // Cooler (higher K) increases blue, decreases red
+            data[i] = Math.min(255, data[i] * (1 + (temperature - 1) * 0.2));     // Red
+            data[i + 2] = Math.min(255, data[i + 2] * (1 + (1 - temperature) * 0.2)); // Blue
+        }
+
+        return imageData;
+    },
+
+    /**
+     * Resets balance effect to default state
+     */
+    reset() {
+        this._slider.value = 6500;
+        this._value.textContent = '6500K';
+        this._notifyObservers();
+    }
+}; 
\ No newline at end of file