From 76a5061fba48857174a730dd549f2466ae63d675 Mon Sep 17 00:00:00 2001 From: Philip Guzman III Date: Wed, 13 May 2026 21:34:24 -0700 Subject: [PATCH] Custom sessions now draw their own bead ring matching the builder sequence present.php extracts the ordered bead types (small/large/crucifix) from custom session slides and passes them as CUSTOM_BEADS to the JS layer. rosary.js reads CUSTOM_BEADS on init: if present, it draws exactly those N beads (with their correct types) instead of the standard 60-bead ring. The three hardcoded 60s and the fixed type Sets are now dynamic so any sequence length works. Standard sessions are unchanged (CUSTOM_BEADS=null). Co-Authored-By: Claude Sonnet 4.6 --- assets/js/rosary.js | 39 ++++++++++++++++++++++++++++++--------- present.php | 14 ++++++++++++++ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/assets/js/rosary.js b/assets/js/rosary.js index 2e6855a..7696c52 100644 --- a/assets/js/rosary.js +++ b/assets/js/rosary.js @@ -42,15 +42,36 @@ var RosaryRing = (function () { var COLOR_PRAYED = '#990000'; var svg = null; - var beadEls = []; // SVG elements, indexed 0-59 + var beadEls = []; // SVG elements, one per bead var polyline = null; var beadPositions = []; // [{x, y}] for each bead var _beadClickHandler = null; // registered by presenter.js - // Which bead indices are "large" (Our Father) beads + // Bead configuration — set by configure(), either from CUSTOM_BEADS or standard rosary + var TOTAL_BEADS = 60; var LARGE_BEADS = new Set([1, 5, 16, 27, 38, 49]); var CRUCIFIX_BEADS = new Set([0]); + // Read window.CUSTOM_BEADS (set by present.php for builder sessions). + // CUSTOM_BEADS is an ordered array of bead types, e.g. ['crucifix','large','small',...]. + // If null/absent, fall back to the standard 60-bead rosary layout. + function configure() { + var cb = window.CUSTOM_BEADS; + if (cb && cb.length) { + TOTAL_BEADS = cb.length; + LARGE_BEADS = new Set(); + CRUCIFIX_BEADS = new Set(); + cb.forEach(function (type, i) { + if (type === 'large') LARGE_BEADS.add(i); + if (type === 'crucifix') CRUCIFIX_BEADS.add(i); + }); + } else { + TOTAL_BEADS = 60; + LARGE_BEADS = new Set([1, 5, 16, 27, 38, 49]); + CRUCIFIX_BEADS = new Set([0]); + } + } + // -------------------------------------------------------------------------- // Calculate bead positions around the viewport edges // -------------------------------------------------------------------------- @@ -74,9 +95,9 @@ var RosaryRing = (function () { var positions = []; - for (var i = 0; i < 60; i++) { + for (var i = 0; i < TOTAL_BEADS; i++) { // Fraction of the perimeter for this bead (clockwise from bottom-center) - var frac = i / 60; + var frac = i / TOTAL_BEADS; var dist = frac * perimeter; var pt = pointOnRect(dist, startX, startY, m, W, H, innerW, innerH, perimeter); @@ -193,7 +214,7 @@ var RosaryRing = (function () { // Draw beads beadEls = []; - for (var i = 0; i < 60; i++) { + for (var i = 0; i < TOTAL_BEADS; i++) { var pos = beadPositions[i]; var isCrucifix = CRUCIFIX_BEADS.has(i); var isLarge = LARGE_BEADS.has(i); @@ -281,10 +302,9 @@ var RosaryRing = (function () { var last = (lastPrayedBeadIndex !== null && lastPrayedBeadIndex !== undefined) ? lastPrayedBeadIndex : -1; - // Once the final bead of decade 5 (index 59) has been prayed and there is - // no active bead, the cross turns gold and stays gold for the rest of the - // presentation (litanies, novena prayer, closing slide). - var allDecadesDone = (last >= 59) && + // Once the final bead has been prayed and there is no active bead, + // the last element turns gold and stays gold for the rest of the presentation. + var allDecadesDone = (last >= TOTAL_BEADS - 1) && (currentBeadIndex === null || currentBeadIndex === undefined); beadEls.forEach(function (el, i) { @@ -342,6 +362,7 @@ var RosaryRing = (function () { // Initialize // -------------------------------------------------------------------------- function init() { + configure(); build(); window.addEventListener('resize', function () { build(); diff --git a/present.php b/present.php index a2cb23c..70e765a 100644 --- a/present.php +++ b/present.php @@ -78,6 +78,19 @@ if ($session['mystery_set'] === 'all_sorrowful') { // Build slide array $slides = build_slides($session); +// For custom sessions, extract the ordered bead sequence so rosary.js +// can draw exactly those beads instead of the standard 60-bead ring. +$custom_beads = null; +if ($session['occasion'] === 'custom') { + $custom_beads = []; + foreach ($slides as $slide) { + if (!empty($slide['bead'])) { + $custom_beads[] = $slide['bead']; + } + } + if (empty($custom_beads)) $custom_beads = null; +} + // Prepare JSON for JavaScript (HTML-safe) $slides_json = json_encode($slides, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT); @@ -223,6 +236,7 @@ $has_audio = !empty($audio_manifest); var BACK_URL = ; var AUDIO_MANIFEST = ; var AUDIO_BASE_URL = ; + var CUSTOM_BEADS = ;