Skip to content

Instantly share code, notes, and snippets.

@fgouin2014
Created July 6, 2024 03:13
Show Gist options
  • Save fgouin2014/811abce415bb40ed0047b8a8c764eacf to your computer and use it in GitHub Desktop.
Save fgouin2014/811abce415bb40ed0047b8a8c764eacf to your computer and use it in GitHub Desktop.
Lights v13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Multi-Bulb Smart Light Control</title>
<link rel="stylesheet" href="styles.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jscolor/2.4.5/jscolor.min.js"></script>
</head>
<body>
<h1>Multi-Bulb Smart Light Control</h1>
<div id="masterControlSection">
<h2>Master Control</h2>
<div class="control-item">
<label class="switch">
<input type="checkbox" id="masterToggle">
<span class="slider"></span>
</label>
</div>
<div class="control-item">
<label for="masterBrightness">Master Brightness:</label>
<input type="range" id="masterBrightness" min="0" max="100" value="50">
<span id="masterBrightnessValue">50%</span>
</div>
<div class="control-item">
<label for="masterColor">Master Color:</label>
<input type="text" id="masterColor" data-jscolor="" value="FFFFFF">
</div>
<div class="color-presets" id="masterColorPresets"></div>
</div>
<div id="bulbControls"></div>
<script src="script.js"></script>
</body>
</html>
// script.js
document.addEventListener('DOMContentLoaded', function() {
const bulbCount = 5;
const bulbControls = document.getElementById('bulbControls');
const masterToggle = document.getElementById('masterToggle');
const masterBrightness = document.getElementById('masterBrightness');
const masterBrightnessValue = document.getElementById('masterBrightnessValue');
const masterColor = document.getElementById('masterColor');
const masterColorPresets = document.getElementById('masterColorPresets');
const colorPresets = {
'White Tones': [
{ name: 'Cool White', color: 'F0F8FF' },
{ name: 'Daylight', color: 'F5F5F5' },
{ name: 'Neutral White', color: 'F5DEB3' },
{ name: 'Warm White', color: 'FFD700' },
{ name: 'Candlelight', color: 'FFA07A' }
],
'Basic Colors': [
{ name: 'Red', color: 'FF0000' },
{ name: 'Green', color: '00FF00' },
{ name: 'Blue', color: '0000FF' },
{ name: 'Yellow', color: 'FFFF00' },
{ name: 'Magenta', color: 'FF00FF' }
],
'Pastel Colors': [
{ name: 'Pastel Pink', color: 'FFB6C1' },
{ name: 'Pastel Blue', color: 'ADD8E6' },
{ name: 'Pastel Green', color: '98FB98' },
{ name: 'Pastel Yellow', color: 'FFFACD' },
{ name: 'Pastel Lavender', color: 'E6E6FA' }
]
};
function createColorPresets(container, colorPickerId) {
Object.entries(colorPresets).forEach(([category, presets]) => {
const categoryDiv = document.createElement('div');
categoryDiv.className = 'preset-category';
const labelDiv = document.createElement('div');
labelDiv.className = 'preset-label';
labelDiv.textContent = category;
categoryDiv.appendChild(labelDiv);
const presetRow = document.createElement('div');
presetRow.className = 'preset-row';
presets.forEach(preset => createPresetButton(preset, presetRow, colorPickerId));
categoryDiv.appendChild(presetRow);
container.appendChild(categoryDiv);
});
}
function createPresetButton(preset, container, colorPickerId) {
const presetElement = document.createElement('div');
presetElement.className = 'color-preset';
presetElement.style.backgroundColor = `#${preset.color}`;
presetElement.title = preset.name;
presetElement.addEventListener('click', () => {
const colorPicker = document.getElementById(colorPickerId);
if (colorPicker.jscolor) {
colorPicker.jscolor.fromString(preset.color);
updateBulbColor(colorPickerId, preset.color);
}
});
container.appendChild(presetElement);
}
function updateBulbColor(colorPickerId, color) {
const bulbId = colorPickerId.replace('color', '');
console.log(`Set bulb ${bulbId} color to #${color}`);
if (colorPickerId === 'masterColor') {
syncMasterColor(color);
}
saveSettings();
}
function createBulbControl(id) {
const bulbDiv = document.createElement('div');
bulbDiv.className = 'bulb-control';
bulbDiv.innerHTML = `
<h2>Bulb ${id}</h2>
<div class="control-item">
<label class="switch">
<input type="checkbox" class="toggleBtn" data-id="${id}">
<span class="slider"></span>
</label>
<svg class="bulb-icon" width="24" height="24" viewBox="0 0 24 24">
<path d="M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6C7.8 12.16 7 10.63 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z"/>
</svg>
</div>
<div class="control-item">
<label for="brightness${id}">Brightness:</label>
<input type="range" id="brightness${id}" class="brightnessSlider" data-id="${id}" min="0" max="100" value="50">
<span class="brightnessValue" data-id="${id}">50%</span>
</div>
<div class="control-item">
<label for="color${id}">Color:</label>
<input type="text" id="color${id}" class="colorPicker" data-jscolor="" data-id="${id}" value="FFFFFF">
</div>
<div class="color-presets" id="colorPresets${id}"></div>
`;
bulbControls.appendChild(bulbDiv);
createColorPresets(bulbDiv.querySelector(`#colorPresets${id}`), `color${id}`);
}
// Create controls for each bulb
for (let i = 1; i <= bulbCount; i++) {
createBulbControl(i);
}
// Initialize jscolor for all color pickers
jscolor.install();
// Create color presets for master control
createColorPresets(masterColorPresets, 'masterColor');
// Add event listeners for individual bulb controls
document.querySelectorAll('.toggleBtn').forEach(btn => {
btn.addEventListener('change', (e) => {
const id = e.target.dataset.id;
const bulbIcon = e.target.closest('.control-item').querySelector('.bulb-icon');
bulbIcon.classList.toggle('on', e.target.checked);
bulbIcon.classList.toggle('off', !e.target.checked);
console.log(`Toggle bulb ${id} ${e.target.checked ? 'on' : 'off'}`);
saveSettings();
});
});
document.querySelectorAll('.brightnessSlider').forEach(slider => {
slider.addEventListener('input', (e) => {
const id = e.target.dataset.id;
const brightness = e.target.value;
document.querySelector(`.brightnessValue[data-id="${id}"]`).textContent = `${brightness}%`;
console.log(`Set bulb ${id} brightness to ${brightness}%`);
saveSettings();
});
});
document.querySelectorAll('.colorPicker').forEach(picker => {
picker.addEventListener('change', (e) => {
const id = e.target.dataset.id;
const color = e.target.jscolor.toString();
console.log(`Set bulb ${id} color to #${color}`);
saveSettings();
});
});
// Add event listeners for master controls
masterToggle.addEventListener('change', (e) => {
console.log(`Toggle all bulbs ${e.target.checked ? 'on' : 'off'}`);
document.querySelectorAll('.toggleBtn').forEach(btn => {
btn.checked = e.target.checked;
btn.dispatchEvent(new Event('change'));
});
});
masterBrightness.addEventListener('input', (e) => {
const brightness = e.target.value;
masterBrightnessValue.textContent = `${brightness}%`;
console.log(`Set all bulbs brightness to ${brightness}%`);
syncMasterBrightness(brightness);
saveSettings();
});
masterColor.addEventListener('change', (e) => {
const color = e.target.jscolor.toString();
console.log(`Set all bulbs color to #${color}`);
syncMasterColor(color);
saveSettings();
});
function syncMasterBrightness(brightness) {
document.querySelectorAll('.brightnessSlider').forEach(slider => {
slider.value = brightness;
const id = slider.dataset.id;
document.querySelector(`.brightnessValue[data-id="${id}"]`).textContent = `${brightness}%`;
});
}
function syncMasterColor(color) {
document.querySelectorAll('.colorPicker').forEach(picker => {
if (picker.jscolor) {
picker.jscolor.fromString(color);
}
});
}
// Save settings to localStorage
function saveSettings() {
const settings = {
masterToggle: masterToggle.checked,
masterBrightness: masterBrightness.value,
masterColor: masterColor.value,
bulbs: {}
};
document.querySelectorAll('.bulb-control').forEach((bulb, index) => {
const id = index + 1;
settings.bulbs[id] = {
isOn: bulb.querySelector('.toggleBtn').checked,
brightness: bulb.querySelector('.brightnessSlider').value,
color: bulb.querySelector('.colorPicker').value
};
});
localStorage.setItem('bulbSettings', JSON.stringify(settings));
}
// Load settings from localStorage
function loadSettings() {
const settings = JSON.parse(localStorage.getItem('bulbSettings'));
if (settings) {
masterToggle.checked = settings.masterToggle;
masterBrightness.value = settings.masterBrightness;
masterBrightnessValue.textContent = `${settings.masterBrightness}%`;
masterColor.jscolor.fromString(settings.masterColor);
Object.entries(settings.bulbs).forEach(([id, bulbSettings]) => {
const bulbControl = document.querySelector(`.bulb-control:nth-child(${id})`);
if (bulbControl) {
const toggleBtn = bulbControl.querySelector('.toggleBtn');
toggleBtn.checked = bulbSettings.isOn;
toggleBtn.dispatchEvent(new Event('change'));
const brightnessSlider = bulbControl.querySelector('.brightnessSlider');
brightnessSlider.value = bulbSettings.brightness;
bulbControl.querySelector('.brightnessValue').textContent = `${bulbSettings.brightness}%`;
const colorPicker = bulbControl.querySelector('.colorPicker');
colorPicker.jscolor.fromString(bulbSettings.color);
}
});
}
}
// Load settings when the page loads
loadSettings();
});
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
h1 {
text-align: center;
}
.bulb-control {
border: 1px solid #ddd;
padding: 15px;
margin-bottom: 20px;
border-radius: 5px;
}
.control-item {
margin-bottom: 10px;
display: flex;
align-items: center;
}
.color-presets {
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 10px;
}
.preset-category {
margin-bottom: 10px;
}
.preset-label {
font-weight: bold;
margin-bottom: 5px;
}
.preset-row {
display: flex;
gap: 5px;
}
.color-preset {
width: 20px;
height: 20px;
border-radius: 50%;
cursor: pointer;
}
#masterControlSection {
border: 1px solid #ddd;
padding: 15px;
margin-bottom: 20px;
border-radius: 5px;
}
.bulb-icon {
margin-left: 10px;
}
.bulb-icon.on {
fill: #ffd700;
}
.bulb-icon.off {
fill: #d3d3d3;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment