mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-07-29 08:01:22 +00:00
feat(highway_3d): add a "Hit sparks" on/off toggle (note-hit particles)
The on-hit spark burst (the particle effect that fires the instant note_detect confirms a hit) could previously only be removed by dragging Hit-feedback intensity to 0 — which also kills the strike-line flash and the scale-punch. Add a dedicated "Hit sparks" toggle (default on) under 3D Highway settings, in the hit-feedback group beside the intensity slider, that gates ONLY the spark particles; the strike flash and colour verdict are unaffected. Wired the same way as the sibling juice toggles: a `sparks` boolean in BG_DEFAULTS, in _BG_BOOL_KEYS, a window.h3dBgSetSparks setter, the per-instance _sparks state + settings re-read, and a guard on the _sparkBurst spawn. Reuses existing Tailwind utility classes, so assets/plugin.css is unchanged; plugin.json version bumped to 3.28.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ccbb2c476d
commit
b04d7fa00d
@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "highway_3d",
|
||||
"name": "3D Highway",
|
||||
"version": "3.27.0",
|
||||
"version": "3.28.0",
|
||||
"type": "visualization",
|
||||
"bundled": true,
|
||||
"script": "screen.js",
|
||||
|
||||
@ -1768,7 +1768,7 @@
|
||||
return _bgBandsCache;
|
||||
}
|
||||
|
||||
const BG_DEFAULTS = { style: 'particles', intensity: 0.5, reactive: true, palette: 'default', bgTheme: 'default', hwTheme: 'default', showFretOnNote: true, fretNumberGhostScope: 'chords', cameraSmoothing: 0.5, zoomSmoothing: 0.5, tiltSmoothing: 0.5, cameraLockLow: false, cameraLockZoom: 0.5, cameraMode: 'lookahead', nutHeadstockVisible: true, tuningLabelsVisible: true, nutColor: '#f5f3f0', headstockColor: '#d4b48a', textSize: 0.5, vibrancy: 0.85, glow: 0.25, customImageDataUrl: '', customImageName: '', customVideoName: '', chordDiagramVisible: true, chordDiagramSize: 0.5, chordDiagramPosition: 'tl', fretColumnMarkerCadence: 1, projectionVisible: true, inlayLabelsVisible: false, sectionLabelsOnHighway: false, sectionHudVisible: false, sectionHudPosition: 'tr', sectionHudSize: 0.5, toneHudVisible: false, toneHudPosition: 'tl', toneHudSize: 0.5, fpsVisible: false, fretDividersVisible: true, slideArrowApproachVisible: true, slideArrowNeckVisible: true, slideArrowChainPreviewVisible: true, hitFx: 0.7, cinematic: true, verdictMarks: true, timingFx: true, streakFx: true, bloom: true };
|
||||
const BG_DEFAULTS = { style: 'particles', intensity: 0.5, reactive: true, palette: 'default', bgTheme: 'default', hwTheme: 'default', showFretOnNote: true, fretNumberGhostScope: 'chords', cameraSmoothing: 0.5, zoomSmoothing: 0.5, tiltSmoothing: 0.5, cameraLockLow: false, cameraLockZoom: 0.5, cameraMode: 'lookahead', nutHeadstockVisible: true, tuningLabelsVisible: true, nutColor: '#f5f3f0', headstockColor: '#d4b48a', textSize: 0.5, vibrancy: 0.85, glow: 0.25, customImageDataUrl: '', customImageName: '', customVideoName: '', chordDiagramVisible: true, chordDiagramSize: 0.5, chordDiagramPosition: 'tl', fretColumnMarkerCadence: 1, projectionVisible: true, inlayLabelsVisible: false, sectionLabelsOnHighway: false, sectionHudVisible: false, sectionHudPosition: 'tr', sectionHudSize: 0.5, toneHudVisible: false, toneHudPosition: 'tl', toneHudSize: 0.5, fpsVisible: false, fretDividersVisible: true, slideArrowApproachVisible: true, slideArrowNeckVisible: true, slideArrowChainPreviewVisible: true, hitFx: 0.7, sparks: true, cinematic: true, verdictMarks: true, timingFx: true, streakFx: true, bloom: true };
|
||||
// User-selectable, persistable bg styles — must mirror settings.html's
|
||||
// VALID_STYLES. 'venue' is deliberately NOT here: it is an internal effective
|
||||
// style reached only via _venueSceneOverride (the viz-picker Venue flow), so
|
||||
@ -2115,7 +2115,7 @@
|
||||
// means (fall back to default rather than silently flipping to
|
||||
// false). Add new boolean keys to BG_DEFAULTS and they pick this
|
||||
// up via the dispatch below.
|
||||
const _BG_BOOL_KEYS = new Set(['reactive', 'showFretOnNote', 'cameraLockLow', 'inlayLabelsVisible', 'sectionLabelsOnHighway', 'sectionHudVisible', 'nutHeadstockVisible', 'tuningLabelsVisible', 'projectionVisible', 'chordDiagramVisible', 'fpsVisible', 'toneHudVisible', 'fretDividersVisible', 'slideArrowApproachVisible', 'slideArrowNeckVisible', 'slideArrowChainPreviewVisible', 'cinematic', 'verdictMarks', 'timingFx', 'streakFx', 'bloom']);
|
||||
const _BG_BOOL_KEYS = new Set(['reactive', 'showFretOnNote', 'cameraLockLow', 'inlayLabelsVisible', 'sectionLabelsOnHighway', 'sectionHudVisible', 'nutHeadstockVisible', 'tuningLabelsVisible', 'projectionVisible', 'chordDiagramVisible', 'fpsVisible', 'toneHudVisible', 'fretDividersVisible', 'slideArrowApproachVisible', 'slideArrowNeckVisible', 'slideArrowChainPreviewVisible', 'sparks', 'cinematic', 'verdictMarks', 'timingFx', 'streakFx', 'bloom']);
|
||||
function _bgCoerceBool(val, fallback) {
|
||||
if (val === 'true' || val === '1') return true;
|
||||
if (val === 'false' || val === '0') return false;
|
||||
@ -2260,6 +2260,7 @@
|
||||
window.h3dBgSetVibrancy = (v) => _bgWriteGlobal('vibrancy', v);
|
||||
window.h3dBgSetGlow = (v) => _bgWriteGlobal('glow', v);
|
||||
window.h3dBgSetHitFx = (v) => _bgWriteGlobal('hitFx', v);
|
||||
window.h3dBgSetSparks = (v) => _bgWriteGlobal('sparks', !!v);
|
||||
window.h3dBgSetCinematic = (v) => _bgWriteGlobal('cinematic', !!v);
|
||||
window.h3dBgSetVerdictMarks = (v) => _bgWriteGlobal('verdictMarks', !!v);
|
||||
window.h3dBgSetTimingFx = (v) => _bgWriteGlobal('timingFx', !!v);
|
||||
@ -3559,6 +3560,7 @@
|
||||
let vibrancy = BG_DEFAULTS.vibrancy;
|
||||
let glowMul = BG_DEFAULTS.glow;
|
||||
let _hitFx = BG_DEFAULTS.hitFx;
|
||||
let _sparks = BG_DEFAULTS.sparks;
|
||||
let _cinematic = BG_DEFAULTS.cinematic;
|
||||
let _verdictMarks = BG_DEFAULTS.verdictMarks;
|
||||
let _timingFx = BG_DEFAULTS.timingFx;
|
||||
@ -7382,6 +7384,7 @@
|
||||
vibrancy = _bgReadSetting(panelKey, 'vibrancy');
|
||||
glowMul = _bgReadSetting(panelKey, 'glow');
|
||||
_hitFx = _bgReadSetting(panelKey, 'hitFx');
|
||||
_sparks = _bgReadSetting(panelKey, 'sparks');
|
||||
_cinematic = _bgReadSetting(panelKey, 'cinematic');
|
||||
_verdictMarks = _bgReadSetting(panelKey, 'verdictMarks');
|
||||
_timingFx = _bgReadSetting(panelKey, 'timingFx');
|
||||
@ -12900,7 +12903,7 @@
|
||||
if (_vAlpha > _ndHitFlash) _ndHitFlash = _vAlpha;
|
||||
_hitPunch = 1 + 0.22 * _hitFx * _vAlpha; // #3 scale-punch (biggest at strike, eases)
|
||||
if (_verdictMarks) { const _tc = _timingHex(_ndMatchedMark && _ndMatchedMark.timingState); _ndLabels.push({ x, y: y + NH * 1.7, z: noteZ + 0.02, labels: [{ text: '✓', color: '#' + _tc.toString(16).padStart(6, '0') }] }); } // #6 + #5
|
||||
if (_hitFx > 0 && _vAlpha > 0.5) {
|
||||
if (_sparks && _hitFx > 0 && _vAlpha > 0.5) {
|
||||
const _spk = s + '|' + n.f + '|' + n.t.toFixed(2);
|
||||
if (!(_sparkSeen.get(_spk) > now)) {
|
||||
_sparkSeen.set(_spk, now + 1.0);
|
||||
|
||||
@ -592,6 +592,16 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 flex items-start justify-between gap-3">
|
||||
<label for="h3d-sparks" class="text-xs font-medium text-gray-400">
|
||||
Hit sparks
|
||||
<span class="block text-[10px] text-gray-500 font-normal">The particle burst that pops off a note the instant it's detected as a hit. Turn off for a calmer highway — the strike-line flash and colour verdict stay.</span>
|
||||
</label>
|
||||
<input type="checkbox" id="h3d-sparks" checked
|
||||
onchange="window.h3dBgSetSparks && window.h3dBgSetSparks(this.checked)"
|
||||
class="accent-accent mt-0.5">
|
||||
</div>
|
||||
|
||||
<div class="mt-3 flex items-start justify-between gap-3">
|
||||
<label for="h3d-cinematic" class="text-xs font-medium text-gray-400">
|
||||
Cinematic lighting
|
||||
|
||||
Loading…
Reference in New Issue
Block a user