Commit 694932db authored by vertighel's avatar vertighel
Browse files

Synoptic

parent 9345f255
Loading
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@
<small class="col-md-4 d-flex gap-3 mt-1 small text-muted">
    <div class="form-check form-check-inline m-0">
        <input class="form-check-input force-cb" type="checkbox" id="force-{{ safe_id }}">
        <label class="form-check-label" for="force-{{ safe_id }}">Force</label>
        <label class="form-check-label" for="force-{{ safe_id }}">Ignore deps</label>
    </div>
    <div class="form-check form-check-inline m-0">
        <input class="form-check-input raw-cb" type="checkbox" id="raw-{{ safe_id }}" data-target="{{ safe_id }}">
+7 −7
Original line number Diff line number Diff line
@@ -23,9 +23,9 @@
     inkscape:pageopacity="0.0"
     inkscape:pagecheckerboard="0"
     inkscape:deskcolor="#d1d1d1"
     inkscape:zoom="2.7930718"
     inkscape:cx="129.06936"
     inkscape:cy="133.90275"
     inkscape:zoom="3.95"
     inkscape:cx="200.37975"
     inkscape:cy="213.16456"
     inkscape:window-width="2511"
     inkscape:window-height="1371"
     inkscape:window-x="26"
@@ -659,19 +659,19 @@
     id="beams"
     inkscape:label="beams"><path
       id="beam-photometry"
       style="fill:none;stroke:#ff6600;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       style="fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       d="m 202.22718,216.19623 43.3783,43.92979 m 23.12946,22.95946 7.91835,9.30074 m 37.69479,10.90406 34.60451,-0.0996 m -75.69139,-15.59218 24.38124,-24.04571 57.62634,0.0633"
       sodipodi:nodetypes="ccccccccc" /><path
       id="beam-spectroscopy"
       style="display:inline;fill:none;stroke:#b3b3b3;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       style="display:inline;fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       d="m 200.55953,216.46393 -84.48558,84.72949 h -66.3242 m 103.4728,-37.30999 -45.85232,3e-5 -67.852326,10e-6"
       sodipodi:nodetypes="cccccc" /><path
       id="beam-echelle"
       style="display:inline;fill:none;stroke:#b3b3b3;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       style="display:inline;fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       d="m 203.17512,214.14623 84.48557,-84.72949 66.3242,-2e-5 m -103.4728,37.31002 45.85233,-3e-5 47.85234,-1e-5"
       sodipodi:nodetypes="cccccc" /><path
       id="beam-incoming"
       style="fill:none;stroke:#ff6600;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       style="fill:none;stroke:#37c8ab;stroke-width:1px"
       d="m 200.55953,215.34038 -60.48559,-62.72949 h -34.3242"
       sodipodi:nodetypes="ccc" /></g><path
     id="telemetry:dome:light:indicator"
+108 −14
Original line number Diff line number Diff line
@@ -75,6 +75,57 @@ function initializeGeometry() {
    }
}

/**
 * Update the colors of the optical beams based on the stage's named position.
 * Uses 'stroke' coloring for lines.
 *
 * Parameters
 * ----------
 * namedPosition : string or null
 *     The name of the current stage position (e.g., 'imaging', 'spectro').
 *     If null or empty, all path beams turn grey.
 *
 * Returns
 * -------
 * void
 */

function animateBeams(namedPosition) {
    
    // SVG Elements
    const beamIn  = document.getElementById('structure-beam-incoming');
    const beamImg = document.getElementById('structure-beam-imaging');
    const beamSpc = document.getElementById('structure-beam-spectro');
    const beamEch = document.getElementById('structure-beam-echelle');

    // Define colors for the stroke
    const COLOR_OFF = "rgba(128, 128, 128, 0.3)";  // Grey, off
    const COLOR_ON  = "rgba(255, 165, 0, 0.8)";    // Orange, illuminated

    // Optional: Incoming beam is always ON (as per your request)
    if (beamIn) applyFillForcefully(beamIn, COLOR_ON, 'stroke');

    // 1. Reset all destination beams to OFF (targeting 'stroke')
    if (beamImg) applyFillForcefully(beamImg, COLOR_OFF, 'stroke');
    if (beamSpc) applyFillForcefully(beamSpc, COLOR_OFF, 'stroke');
    if (beamEch) applyFillForcefully(beamEch, COLOR_OFF, 'stroke');

    // 2. Turn ON the active beam if it matches a named position
    let activeBeam = null;

    if (namedPosition === 'imaging') {
        activeBeam = beamImg;
    } else if (namedPosition === 'spectro') {
        activeBeam = beamSpc;
    } else if (namedPosition === 'echelle') {
        activeBeam = beamEch;
    }

    // Apply the ON color to the selected stroke
    if (activeBeam) {
        applyFillForcefully(activeBeam, COLOR_ON, 'stroke');
    }
}

/**
 * Rotate the dome graphic using CSS to preserve Inkscape base transforms.
@@ -240,21 +291,58 @@ function animateStage(posMm) {
    // Translate only on X axis
    mirrorEl.style.transform = `translate(${deltaX}px, 0px)`;
}

/**
 * Forcefully apply fill color to an element and its inline styles.
 * Forcefully apply color to an element and all its children.
 * Erases existing inline styles of the specified type to guarantee the change.
 *
 * Parameters
 * ----------
 * el : SVGElement
 *     The DOM element to colorize.
 * color : string
 *     The CSS color (e.g. 'rgba(0,255,0,1)' or 'red').
 * type : string, optional
 *     'fill' or 'stroke'. Defaults to 'fill'.
 *
 * Returns
 * -------
 * void
 */
function applyFillForcefully(el, color) {
    el.setAttribute('fill', color);
function applyFillForcefully(el, color, type = 'fill') {
    
    if (!el) return;

    // A helper function to apply the forceful styling to a single node
    const forceNode = (node) => {
        // Apply directly as an SVG attribute
        node.setAttribute(type, color);
        
    let style = el.getAttribute('style') || '';
    if (style.match(/fill\s*:/i)) {
        // Replace existing fill with the new color and force !important
        style = style.replace(/fill\s*:[^;]+;?/gi, `fill: ${color} !important;`);
        // Parse the existing inline style string
        let style = node.getAttribute('style') || '';
        
        // Dynamic Regex to match either 'fill' or 'stroke'
        const regex = new RegExp(`${type}\\s*:[^;]+;?`, 'gi');

        if (style.match(regex)) {
            // Replace existing rule with the new color and force !important
            style = style.replace(regex, `${type}: ${color} !important;`);
        } else {
        // Append fill if it doesn't exist
        style += `; fill: ${color} !important;`;
            // Append rule if it doesn't exist
            style += `; ${type}: ${color} !important;`;
        }
    el.setAttribute('style', style);
        
        node.setAttribute('style', style);
    };

    // 1. Apply to the main element itself
    forceNode(el);

    // 2. Apply to all graphic children (Crucial if the ID is on an Inkscape <g> Group)
    const children = el.querySelectorAll('path, rect, circle, ellipse, polygon, line, polyline');
    children.forEach(child => {
        forceNode(child);
    });
}

/**
@@ -359,7 +447,6 @@ document.addEventListener('noctua-telemetry', (e) => {
        }
    });


   // ---- B. Animate Graphics ----
    
    if (subsystem === 'dome') {
@@ -389,10 +476,17 @@ document.addEventListener('noctua-telemetry', (e) => {
    }

    if (subsystem === 'stage') {
        // Translation of the mirror
        if (data.position && data.position.response !== undefined) {
            const stageMm = data.position.response;
            if (typeof stageMm === 'number') animateStage(stageMm);
        }

        // Colorization of the beams
        if (data.named && data.named.response !== undefined) {
            // response could be 'imaging', 'spectro', 'echelle', or null/error
            animateBeams(data.named.response);
        }
    }

});