Add effect palette preview bar in CSS editor
Show a gradient color bar below the effect type description, giving users a visual preview of palette colors before applying. Updates live when switching effect type, palette, or meteor head color. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -507,6 +507,14 @@
|
|||||||
|
|
||||||
/* ── Gradient editor ────────────────────────────────────────────── */
|
/* ── Gradient editor ────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.effect-palette-preview {
|
||||||
|
width: 100%;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-top: 6px;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
.gradient-editor {
|
.gradient-editor {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ import {
|
|||||||
// Layer 5: color-strip sources
|
// Layer 5: color-strip sources
|
||||||
import {
|
import {
|
||||||
showCSSEditor, closeCSSEditorModal, forceCSSEditorClose, saveCSSEditor, deleteColorStrip,
|
showCSSEditor, closeCSSEditorModal, forceCSSEditorClose, saveCSSEditor, deleteColorStrip,
|
||||||
onCSSTypeChange, onEffectTypeChange, onAnimationTypeChange, colorCycleAddColor, colorCycleRemoveColor,
|
onCSSTypeChange, onEffectTypeChange, onAnimationTypeChange, updateEffectPreview,
|
||||||
|
colorCycleAddColor, colorCycleRemoveColor,
|
||||||
applyGradientPreset,
|
applyGradientPreset,
|
||||||
} from './features/color-strips.js';
|
} from './features/color-strips.js';
|
||||||
|
|
||||||
@@ -277,6 +278,7 @@ Object.assign(window, {
|
|||||||
onCSSTypeChange,
|
onCSSTypeChange,
|
||||||
onEffectTypeChange,
|
onEffectTypeChange,
|
||||||
onAnimationTypeChange,
|
onAnimationTypeChange,
|
||||||
|
updateEffectPreview,
|
||||||
colorCycleAddColor,
|
colorCycleAddColor,
|
||||||
colorCycleRemoveColor,
|
colorCycleRemoveColor,
|
||||||
applyGradientPreset,
|
applyGradientPreset,
|
||||||
|
|||||||
@@ -131,6 +131,38 @@ function _syncAnimationSpeedState() {
|
|||||||
|
|
||||||
/* ── Effect type helpers ──────────────────────────────────────── */
|
/* ── Effect type helpers ──────────────────────────────────────── */
|
||||||
|
|
||||||
|
// Palette color control points — mirrors _PALETTE_DEFS in effect_stream.py
|
||||||
|
const _PALETTE_COLORS = {
|
||||||
|
fire: [[0,'0,0,0'],[0.33,'200,24,0'],[0.66,'255,160,0'],[1,'255,255,200']],
|
||||||
|
ocean: [[0,'0,0,32'],[0.33,'0,16,128'],[0.66,'0,128,255'],[1,'128,224,255']],
|
||||||
|
lava: [[0,'0,0,0'],[0.25,'128,0,0'],[0.5,'255,32,0'],[0.75,'255,160,0'],[1,'255,255,128']],
|
||||||
|
forest: [[0,'0,16,0'],[0.33,'0,80,0'],[0.66,'32,160,0'],[1,'128,255,64']],
|
||||||
|
rainbow: [[0,'255,0,0'],[0.17,'255,255,0'],[0.33,'0,255,0'],[0.5,'0,255,255'],[0.67,'0,0,255'],[0.83,'255,0,255'],[1,'255,0,0']],
|
||||||
|
aurora: [[0,'0,16,32'],[0.2,'0,80,64'],[0.4,'0,200,100'],[0.6,'64,128,255'],[0.8,'128,0,200'],[1,'0,16,32']],
|
||||||
|
sunset: [[0,'32,0,64'],[0.25,'128,0,128'],[0.5,'255,64,0'],[0.75,'255,192,64'],[1,'255,255,192']],
|
||||||
|
ice: [[0,'0,0,64'],[0.33,'0,64,192'],[0.66,'128,192,255'],[1,'240,248,255']],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Default palette per effect type
|
||||||
|
const _EFFECT_DEFAULT_PALETTE = {
|
||||||
|
fire: 'fire', meteor: 'fire', plasma: 'rainbow', noise: 'rainbow', aurora: 'aurora',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function updateEffectPreview() {
|
||||||
|
const el = document.getElementById('css-editor-effect-preview');
|
||||||
|
if (!el) return;
|
||||||
|
const et = document.getElementById('css-editor-effect-type').value;
|
||||||
|
if (et === 'meteor') {
|
||||||
|
const color = document.getElementById('css-editor-effect-color').value;
|
||||||
|
el.style.background = color;
|
||||||
|
} else {
|
||||||
|
const palette = document.getElementById('css-editor-effect-palette').value || _EFFECT_DEFAULT_PALETTE[et] || 'fire';
|
||||||
|
const pts = _PALETTE_COLORS[palette] || _PALETTE_COLORS.fire;
|
||||||
|
const stops = pts.map(([pos, rgb]) => `rgb(${rgb}) ${(pos * 100).toFixed(0)}%`).join(', ');
|
||||||
|
el.style.background = `linear-gradient(to right, ${stops})`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function onEffectTypeChange() {
|
export function onEffectTypeChange() {
|
||||||
const et = document.getElementById('css-editor-effect-type').value;
|
const et = document.getElementById('css-editor-effect-type').value;
|
||||||
// palette: all except meteor
|
// palette: all except meteor
|
||||||
@@ -152,6 +184,8 @@ export function onEffectTypeChange() {
|
|||||||
descEl.textContent = desc;
|
descEl.textContent = desc;
|
||||||
descEl.style.display = desc ? '' : 'none';
|
descEl.style.display = desc ? '' : 'none';
|
||||||
}
|
}
|
||||||
|
// palette preview
|
||||||
|
updateEffectPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Color Cycle helpers ──────────────────────────────────────── */
|
/* ── Color Cycle helpers ──────────────────────────────────────── */
|
||||||
|
|||||||
@@ -228,6 +228,7 @@
|
|||||||
<option value="aurora" data-i18n="color_strip.effect.aurora">Aurora</option>
|
<option value="aurora" data-i18n="color_strip.effect.aurora">Aurora</option>
|
||||||
</select>
|
</select>
|
||||||
<small id="css-editor-effect-type-desc" class="field-desc"></small>
|
<small id="css-editor-effect-type-desc" class="field-desc"></small>
|
||||||
|
<div id="css-editor-effect-preview" class="effect-palette-preview"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -249,7 +250,7 @@
|
|||||||
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
||||||
</div>
|
</div>
|
||||||
<small class="input-hint" style="display:none" data-i18n="color_strip.effect.palette.hint">Color palette used by the effect.</small>
|
<small class="input-hint" style="display:none" data-i18n="color_strip.effect.palette.hint">Color palette used by the effect.</small>
|
||||||
<select id="css-editor-effect-palette">
|
<select id="css-editor-effect-palette" onchange="updateEffectPreview()">
|
||||||
<option value="fire" data-i18n="color_strip.palette.fire">Fire</option>
|
<option value="fire" data-i18n="color_strip.palette.fire">Fire</option>
|
||||||
<option value="ocean" data-i18n="color_strip.palette.ocean">Ocean</option>
|
<option value="ocean" data-i18n="color_strip.palette.ocean">Ocean</option>
|
||||||
<option value="lava" data-i18n="color_strip.palette.lava">Lava</option>
|
<option value="lava" data-i18n="color_strip.palette.lava">Lava</option>
|
||||||
@@ -267,7 +268,7 @@
|
|||||||
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
<button type="button" class="hint-toggle" onclick="toggleHint(this)" title="?" data-i18n-aria-label="aria.hint">?</button>
|
||||||
</div>
|
</div>
|
||||||
<small class="input-hint" style="display:none" data-i18n="color_strip.effect.color.hint">Head color for the meteor effect.</small>
|
<small class="input-hint" style="display:none" data-i18n="color_strip.effect.color.hint">Head color for the meteor effect.</small>
|
||||||
<input type="color" id="css-editor-effect-color" value="#ff5000">
|
<input type="color" id="css-editor-effect-color" value="#ff5000" oninput="updateEffectPreview()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="css-editor-effect-intensity-group" class="form-group">
|
<div id="css-editor-effect-intensity-group" class="form-group">
|
||||||
|
|||||||
Reference in New Issue
Block a user