File size: 19,523 Bytes
e44f5f1
99a6e86
 
 
 
 
 
 
e44f5f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99a6e86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e44f5f1
99a6e86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e44f5f1
99a6e86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e44f5f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99a6e86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e44f5f1
 
 
 
 
99a6e86
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic Sliders with Editable Values and Array Upscaler</title>
    <style>
        /* Add styling for the suggestions */
        .suggestions {
            margin-bottom: 10px;
        }
        .suggestion {
            display: inline-block;
            margin-right: 10px;
            padding: 5px 10px;
            background-color: #e0e0e0;
            border-radius: 4px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        .suggestion:hover {
            background-color: #d0d0d0;
        }
        /* Add the rest of your existing styles */
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f4f4f4;
            margin: 0;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
        }
        .container {
            background-color: #fff;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            width: 100%;
            max-width: 800px;
        }
        .input-section {
        margin-bottom: 20px;
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
        gap: 10px;
        justify-content: center;
        }
        .input-section label {
            font-weight: bold;
            margin-bottom: 5px;
            display: block;
        }
        .input-section input[type="number"] {
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
            width: 100%;
            box-sizing: border-box;
        }
        /* Add media query to adjust grid template columns on smaller screens */
        @media (max-width: 768px) {
            .input-section {
                grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
            }
        }
        @media (max-width: 480px) {
            .input-section {
                grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
            }
        }
        }
        #sliders {
            display: flex;
            flex-direction: column;
        }
        .slider-container {
            display: flex;
            align-items: center;
            width: 100%;
        }
        .slider-index {
            width: 30px;
            text-align: right;
            font-weight: bold;
            color: #333;
            flex-shrink: 0;
        }
        .slider-wrapper {
            flex-grow: 1;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .slider-wrapper input[type="range"] {
            width: 100%;
            box-sizing: border-box;
        }
        .slider-number {
            width: 70px;
            text-align: left;
            font-weight: bold;
            color: #333;
            flex-shrink: 0;
            cursor: pointer;
        }
        .slider-number input {
            width: 100%;
            box-sizing: border-box;
        }
        .middle-slider .slider-index,
        .middle-slider .slider-wrapper input[type="range"] {
            background-color: #ffcccb;
        }
        .output {
            margin-top: 20px;
            font-weight: bold;
            color: #333;
        }
        .output span {
            color: #007bff;
        }
        .error-message {
            color: red;
            font-weight: bold;
            margin-top: 10px;
        }
        .close-button {
            cursor: pointer;
            color: red;
            font-weight: bold;
            margin-left: 5px;
        }
        .array-upscaler {
            margin-top: 40px;
        }
        .array-upscaler h2 {
            margin-bottom: 10px;
        }
        .array-upscaler p {
            margin: 10px 0;
        }
        .array-upscaler button {
            padding: 10px 20px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .array-upscaler button:hover {
            background-color: #0056b3;
        }
        .array-upscaler #result {
            margin-top: 20px;
            font-weight: bold;
            color: #333;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="input-section">
            <div>
                <label for="numSliders">Number of Sliders:</label>
                <input type="number" id="numSliders" min="1" value="1" oninput="updateSliders()">
            </div>
            <div>
                <label for="minValue">Minimum Value:</label>
                <input type="number" id="minValue" step="0.01" value="0.00" oninput="updateSliders()">
            </div>
            <div>
                <label for="maxValue">Maximum Value:</label>
                <input type="number" id="maxValue" step="0.01" value="100.00" oninput="updateSliders()">
            </div>
            <div>
                <label for="sliderWidth">Slider Width (%):</label>
                <input type="number" id="sliderWidth" min="10" max="100" value="100" oninput="updateSliderStyles()">
            </div>
            <div>
                <label for="sliderMargin">Slider Margin (px):</label>
                <input type="number" id="sliderMargin" min="0" value="10" oninput="updateSliderStyles()">
            </div>
            <div>
                <label for="sliderStep">Slider Step:</label>
                <input type="number" id="sliderStep" min="0.01" step="0.01" value="0.01" oninput="updateSliderStep()">
            </div>
        </div>
        <div id="sliders"></div>
        <div class="output">
            <label>Slider Values:</label>
            <span id="sliderValues">[]</span>
        </div>
        <div id="errorMessage" class="error-message"></div>

        <!-- Array Upscaler Section -->
        <div class="array-upscaler">
            <h2>Array Upscaler</h2>
            <div class="suggestions" id="suggestions"></div>
            <p>
                Upscaled Length:
                <input type="number" id="newLength" min="1" value="5">
            </p>
            <button onclick="upscaleArray()">Upscale Array</button>
            <h3>Upscaled Array:</h3>
            <div id="result"></div>
        </div>
    </div>

    <script>
        function updateSliderStyles() {
            const sliderWidth = document.getElementById('sliderWidth').value;
            const sliderMargin = document.getElementById('sliderMargin').value;
            const sliders = document.querySelectorAll('.slider-wrapper input[type="range"]');
            sliders.forEach(slider => {
                slider.style.width = `${sliderWidth}%`;
            });
            const sliderContainers = document.querySelectorAll('.slider-container');
            sliderContainers.forEach(sliderContainer => {
                sliderContainer.style.margin = `${sliderMargin}px 0`;
            });
        }
        function updateSliderStep() {
            const step = document.getElementById('sliderStep').value;
            const sliders = document.querySelectorAll('#sliders input[type="range"]');
            
            sliders.forEach(slider => {
                slider.step = step;
            });
        }
        function createSliders() {
            const numSliders = parseInt(document.getElementById('numSliders').value);
            const minValue = parseFloat(document.getElementById('minValue').value);
            const maxValue = parseFloat(document.getElementById('maxValue').value);
            const sliderStep = parseFloat(document.getElementById('sliderStep').value);
            const slidersContainer = document.getElementById('sliders');
            slidersContainer.innerHTML = ''; // Clear previous sliders
            for (let i = 0; i < numSliders; i++) {
                const sliderContainer = document.createElement('div');
                sliderContainer.className = 'slider-container';
                const sliderIndex = document.createElement('span');
                sliderIndex.className = 'slider-index';
                sliderIndex.textContent = i + 1;
                const sliderWrapper = document.createElement('div');
                sliderWrapper.className = 'slider-wrapper';
                const slider = document.createElement('input');
                slider.type = 'range';
                slider.min = minValue;
                slider.max = maxValue;
                slider.value = minValue;
                slider.step = sliderStep;
                slider.oninput = updateValues;
                const sliderNumber = document.createElement('span');
                sliderNumber.className = 'slider-number';
                sliderNumber.textContent = minValue.toFixed(2);
                sliderNumber.onclick = function() {
                    makeEditable(sliderNumber, slider);
                };
                sliderWrapper.appendChild(slider);
                sliderWrapper.appendChild(sliderNumber);
                sliderContainer.appendChild(sliderIndex);
                sliderContainer.appendChild(sliderWrapper);
                slidersContainer.appendChild(sliderContainer);
                // Highlight the middle slider if the total number of sliders is odd
                if (numSliders % 2 !== 0 && i === Math.floor(numSliders / 2)) {
                    sliderContainer.classList.add('middle-slider');
                }
            }
            updateValues(); // Initial update
            updateSliderStyles(); // Apply initial styles
        }
        function updateSliders() {
            const numSlidersInput = document.getElementById('numSliders').value;
            const minValue = parseFloat(document.getElementById('minValue').value);
            const maxValue = parseFloat(document.getElementById('maxValue').value);
            const sliderStep = parseFloat(document.getElementById('sliderStep').value);
            const slidersContainer = document.getElementById('sliders');
            const errorMessage = document.getElementById('errorMessage');
            // Validate the number of sliders input
            if (!numSlidersInput || isNaN(numSlidersInput) || parseInt(numSlidersInput) < 1) {
                errorMessage.textContent = 'Please enter a valid number of sliders (greater than 0).';
                slidersContainer.innerHTML = ''; // Clear sliders if input is invalid
                return;
            } else {
                errorMessage.textContent = ''; // Clear error message if input is valid
            }
            const numSliders = parseInt(numSlidersInput);
            const currentSliders = document.querySelectorAll('#sliders input[type="range"]');
            // Preserve existing slider values when reducing number of sliders
            const existingValues = Array.from(currentSliders).map(slider => parseFloat(slider.value));
            slidersContainer.innerHTML = ''; // Clear existing sliders
            for (let i = 0; i < numSliders; i++) {
                const sliderContainer = document.createElement('div');
                sliderContainer.className = 'slider-container';
                const sliderIndex = document.createElement('span');
                sliderIndex.className = 'slider-index';
                sliderIndex.textContent = i + 1;
                const sliderWrapper = document.createElement('div');
                sliderWrapper.className = 'slider-wrapper';
                const slider = document.createElement('input');
                slider.type = 'range';
                slider.min = minValue;
                slider.max = maxValue;
                slider.step = sliderStep;
                slider.oninput = updateValues;
                const sliderNumber = document.createElement('span');
                sliderNumber.className = 'slider-number';
                sliderNumber.onclick = function() {
                    makeEditable(sliderNumber, slider);
                };
                // Use preserved value or default to minValue
                const preservedValue = existingValues[i] !== undefined 
                    ? Math.max(minValue, Math.min(maxValue, existingValues[i]))
                    : minValue;
                
                slider.value = preservedValue;
                sliderNumber.textContent = preservedValue.toFixed(2);
                sliderWrapper.appendChild(slider);
                sliderWrapper.appendChild(sliderNumber);
                sliderContainer.appendChild(sliderIndex);
                sliderContainer.appendChild(sliderWrapper);
                slidersContainer.appendChild(sliderContainer);
                // Highlight the middle slider if the total number of sliders is odd
                if (numSliders % 2 !== 0 && i === Math.floor(numSliders / 2)) {
                    sliderContainer.classList.add('middle-slider');
                }
            }
            updateValues(); // Update the displayed values
            updateSliderStyles(); // Apply styles
            updateSuggestions(); // Update upscaling suggestions
        }
        function updateValues() {
            const sliders = document.querySelectorAll('#sliders input[type="range"]');
            const values = Array.from(sliders).map(slider => {
                const value = parseFloat(slider.value);
                slider.nextElementSibling.textContent = value.toFixed(2); // Update the number next to the slider
                return value;
            });
            document.getElementById('sliderValues').textContent = JSON.stringify(values);
        }
        function makeEditable(sliderNumber, slider) {
            const currentValue = sliderNumber.textContent;
            const container = document.createElement('div'); // Create a container to hold input and button
            const input = document.createElement('input');
            input.type = 'number';
            input.value = currentValue;
            input.min = slider.min;
            input.max = slider.max;
            input.step = slider.step;
            input.style.width = '100%';
            input.style.boxSizing = 'border-box';
            const closeButton = document.createElement('span');
            closeButton.className = 'close-button';
            closeButton.textContent = 'X';
            closeButton.onclick = function() {
                input.blur(); // Trigger blur event to revert to text
            };
            container.appendChild(input); // Append input and button to container
            container.appendChild(closeButton);
            const originalSliderNumber = sliderNumber.cloneNode(true); // Clone original sliderNumber for later use
            originalSliderNumber.onclick = function() { makeEditable(originalSliderNumber, slider); }; // Reattach onclick event
            sliderNumber.replaceWith(container); // Replace sliderNumber with the container
            input.onblur = function() {
                const newValue = parseFloat(input.value);
                if (!isNaN(newValue) && newValue >= parseFloat(slider.min) && newValue <= parseFloat(slider.max)) {
                    slider.value = newValue;
                    originalSliderNumber.textContent = newValue.toFixed(2); // Update sliderNumber text
                } else {
                    originalSliderNumber.textContent = currentValue; // Revert to original value if invalid
                }
                container.replaceWith(originalSliderNumber); // Replace container with original sliderNumber
                updateValues(); // Update displayed values
            };
            input.onkeydown = function(event) {
                if (event.key === 'Enter') {
                    input.blur(); // Trigger blur event on Enter key press
                }
            };
            input.focus(); // Focus on the input field
        }

        function updateSuggestions() {
            const numSliders = parseInt(document.getElementById('numSliders').value);
            const suggestionsDiv = document.getElementById('suggestions');
            suggestionsDiv.innerHTML = ''; // Clear previous suggestions

            if (numSliders % 2 !== 0) {
                const n = numSliders;
                const firstSuggestion = 2 * n - 1;
                const secondSuggestion = 2 * firstSuggestion - 1;
                
                const createSuggestionElement = (value) => {
                    const suggestion = document.createElement('span');
                    suggestion.className = 'suggestion';
                    suggestion.textContent = value;
                    suggestion.onclick = function() {
                        document.getElementById('newLength').value = value;
                        upscaleArray();
                    };
                    return suggestion;
                };

                if (firstSuggestion > numSliders) {
                    suggestionsDiv.appendChild(createSuggestionElement(firstSuggestion));
                }
                if (secondSuggestion > firstSuggestion) {
                    suggestionsDiv.appendChild(createSuggestionElement(secondSuggestion));
                }
            }
        }

        function upscaleArray() {
            // Get slider values
            const sliders = document.querySelectorAll('#sliders input[type="range"]');
            const originalArray = Array.from(sliders).map(slider => parseFloat(slider.value));
            const newLengthInput = document.getElementById('newLength').value;
            const newLength = parseInt(newLengthInput, 10);
            // Validate inputs
            if (originalArray.length === 0 || isNaN(newLength) || newLength < 1) {
                document.getElementById('result').innerHTML = 'Invalid input.';
                return;
            }
            // If new length is less than or equal to original, return original array
            if (newLength <= originalArray.length) {
                document.getElementById('result').innerHTML = originalArray.join(', ');
                return;
            }
            // Calculate the step size
            const step = (originalArray.length - 1) / (newLength - 1);
            // Create the upscaled array
            const upscaledArray = [];
            for (let j = 0; j < newLength; j++) {
                const i = j * step;
                const lower = Math.floor(i);
                const upper = Math.ceil(i);
                const fraction = i - lower;
                // Handle edge cases where upper is out of bounds
                if (upper >= originalArray.length) {
                    upper = originalArray.length - 1;
                    fraction = 0;
                }
                // Linear interpolation
                const value = originalArray[lower] + fraction * (originalArray[upper] - originalArray[lower]);
                upscaledArray.push(value.toFixed(3)); // Display one decimal place
            }
            // Display the result
            document.getElementById('result').innerHTML = upscaledArray.join(', ');
        }

        // Initial call to create sliders
        createSliders();
        // Initial call to update suggestions
        updateSuggestions();
    </script>
</body>
</html>