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 <noreply@anthropic.com>
This commit is contained in:
+30
-9
@@ -42,15 +42,36 @@ var RosaryRing = (function () {
|
|||||||
var COLOR_PRAYED = '#990000';
|
var COLOR_PRAYED = '#990000';
|
||||||
|
|
||||||
var svg = null;
|
var svg = null;
|
||||||
var beadEls = []; // SVG <circle> elements, indexed 0-59
|
var beadEls = []; // SVG elements, one per bead
|
||||||
var polyline = null;
|
var polyline = null;
|
||||||
var beadPositions = []; // [{x, y}] for each bead
|
var beadPositions = []; // [{x, y}] for each bead
|
||||||
var _beadClickHandler = null; // registered by presenter.js
|
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 LARGE_BEADS = new Set([1, 5, 16, 27, 38, 49]);
|
||||||
var CRUCIFIX_BEADS = new Set([0]);
|
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
|
// Calculate bead positions around the viewport edges
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@@ -74,9 +95,9 @@ var RosaryRing = (function () {
|
|||||||
|
|
||||||
var positions = [];
|
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)
|
// 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 dist = frac * perimeter;
|
||||||
|
|
||||||
var pt = pointOnRect(dist, startX, startY, m, W, H, innerW, innerH, perimeter);
|
var pt = pointOnRect(dist, startX, startY, m, W, H, innerW, innerH, perimeter);
|
||||||
@@ -193,7 +214,7 @@ var RosaryRing = (function () {
|
|||||||
|
|
||||||
// Draw beads
|
// Draw beads
|
||||||
beadEls = [];
|
beadEls = [];
|
||||||
for (var i = 0; i < 60; i++) {
|
for (var i = 0; i < TOTAL_BEADS; i++) {
|
||||||
var pos = beadPositions[i];
|
var pos = beadPositions[i];
|
||||||
var isCrucifix = CRUCIFIX_BEADS.has(i);
|
var isCrucifix = CRUCIFIX_BEADS.has(i);
|
||||||
var isLarge = LARGE_BEADS.has(i);
|
var isLarge = LARGE_BEADS.has(i);
|
||||||
@@ -281,10 +302,9 @@ var RosaryRing = (function () {
|
|||||||
var last = (lastPrayedBeadIndex !== null && lastPrayedBeadIndex !== undefined)
|
var last = (lastPrayedBeadIndex !== null && lastPrayedBeadIndex !== undefined)
|
||||||
? lastPrayedBeadIndex : -1;
|
? lastPrayedBeadIndex : -1;
|
||||||
|
|
||||||
// Once the final bead of decade 5 (index 59) has been prayed and there is
|
// Once the final bead has been prayed and there is no active bead,
|
||||||
// no active bead, the cross turns gold and stays gold for the rest of the
|
// the last element turns gold and stays gold for the rest of the presentation.
|
||||||
// presentation (litanies, novena prayer, closing slide).
|
var allDecadesDone = (last >= TOTAL_BEADS - 1) &&
|
||||||
var allDecadesDone = (last >= 59) &&
|
|
||||||
(currentBeadIndex === null || currentBeadIndex === undefined);
|
(currentBeadIndex === null || currentBeadIndex === undefined);
|
||||||
|
|
||||||
beadEls.forEach(function (el, i) {
|
beadEls.forEach(function (el, i) {
|
||||||
@@ -342,6 +362,7 @@ var RosaryRing = (function () {
|
|||||||
// Initialize
|
// Initialize
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
function init() {
|
function init() {
|
||||||
|
configure();
|
||||||
build();
|
build();
|
||||||
window.addEventListener('resize', function () {
|
window.addEventListener('resize', function () {
|
||||||
build();
|
build();
|
||||||
|
|||||||
+14
@@ -78,6 +78,19 @@ if ($session['mystery_set'] === 'all_sorrowful') {
|
|||||||
// Build slide array
|
// Build slide array
|
||||||
$slides = build_slides($session);
|
$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)
|
// Prepare JSON for JavaScript (HTML-safe)
|
||||||
$slides_json = json_encode($slides, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
|
$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 = <?= json_encode($back_url) ?>;
|
var BACK_URL = <?= json_encode($back_url) ?>;
|
||||||
var AUDIO_MANIFEST = <?= json_encode($audio_manifest, JSON_HEX_TAG | JSON_HEX_AMP) ?>;
|
var AUDIO_MANIFEST = <?= json_encode($audio_manifest, JSON_HEX_TAG | JSON_HEX_AMP) ?>;
|
||||||
var AUDIO_BASE_URL = <?= json_encode(UPLOADS_URL . 'audio/') ?>;
|
var AUDIO_BASE_URL = <?= json_encode(UPLOADS_URL . 'audio/') ?>;
|
||||||
|
var CUSTOM_BEADS = <?= json_encode($custom_beads) ?>;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="<?= BASE_URL ?>/assets/js/rosary.js?v=9"></script>
|
<script src="<?= BASE_URL ?>/assets/js/rosary.js?v=9"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user