Merge pull request #58 from ok2/codex/add-interactive-view-for-eonstrip-events
This commit is contained in:
commit
13dd3ec664
10
index.html
10
index.html
@ -61,11 +61,19 @@
|
|||||||
<button onclick="goToNow()">Now</button>
|
<button onclick="goToNow()">Now</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="calendar-view">
|
<div class="calendar-view" id="calendarView">
|
||||||
<div class="calendar-header" id="calendarHeader">Loading...</div>
|
<div class="calendar-header" id="calendarHeader">Loading...</div>
|
||||||
<div class="eonstrip-grid" id="eonstripGrid"></div>
|
<div class="eonstrip-grid" id="eonstripGrid"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="eonstripDetailView" class="detail-view" style="display:none;">
|
||||||
|
<div class="detail-header">
|
||||||
|
<button id="backToCalendar" class="back-btn">Back</button>
|
||||||
|
<span id="detailTitle"></span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-timeline" id="detailTimeline"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="time-details">
|
<div class="time-details">
|
||||||
<h3 style="text-align: center; margin-bottom: 20px; color: #00ffff;">Time Breakdown</h3>
|
<h3 style="text-align: center; margin-bottom: 20px; color: #00ffff;">Time Breakdown</h3>
|
||||||
|
|
||||||
|
|||||||
81
script.js
81
script.js
@ -651,19 +651,11 @@ function updateCalendar() {
|
|||||||
tooltip.innerHTML = showEonstripDetails(i, cellCob, dateOpts);
|
tooltip.innerHTML = showEonstripDetails(i, cellCob, dateOpts);
|
||||||
card.appendChild(tooltip);
|
card.appendChild(tooltip);
|
||||||
grid.appendChild(card);
|
grid.appendChild(card);
|
||||||
(function(cob) {
|
(function(cob, idx) {
|
||||||
card.addEventListener('click', () => {
|
card.addEventListener('click', () => {
|
||||||
currentOffset = 0;
|
showEonstripDetail(idx, cob);
|
||||||
manualMode = true;
|
|
||||||
manualCobiets = cob;
|
|
||||||
clearInterval(updateInterval);
|
|
||||||
document.querySelector('.current-time').classList.add('manual');
|
|
||||||
updateCurrentTime();
|
|
||||||
if (window.CobieClock) {
|
|
||||||
window.CobieClock.showTime(manualCobiets);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})(cellCob + currentTime);
|
})(cellCob, i);
|
||||||
}
|
}
|
||||||
updateTimeBreakdown(currentCob);
|
updateTimeBreakdown(currentCob);
|
||||||
}
|
}
|
||||||
@ -692,6 +684,68 @@ function showEonstripDetails(index, startCobiets, opts) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showEonstripDetail(index, startCob) {
|
||||||
|
const calendar = document.getElementById('calendarView');
|
||||||
|
const detail = document.getElementById('eonstripDetailView');
|
||||||
|
const timeline = document.getElementById('detailTimeline');
|
||||||
|
const title = document.getElementById('detailTitle');
|
||||||
|
calendar.style.display = 'none';
|
||||||
|
detail.style.display = 'block';
|
||||||
|
timeline.innerHTML = '';
|
||||||
|
|
||||||
|
const bd = breakdownNonNeg(Math.abs(startCob));
|
||||||
|
const sign = startCob < 0 ? '-' : '+';
|
||||||
|
title.textContent = `${sign}${bd.galactic_year.toString(16)}${bd.cosmocycle.toString(16)}${bd.megasequence.toString(16)}${index.toString(16)} – ${EONSTRIP_NAMES[index]}`;
|
||||||
|
|
||||||
|
for (let c = 0; c <= 16; c++) {
|
||||||
|
const block = document.createElement('div');
|
||||||
|
block.className = 'timeline-block';
|
||||||
|
block.style.top = (c / 16 * 100) + '%';
|
||||||
|
if (c < 16) block.textContent = c.toString(16).toUpperCase();
|
||||||
|
timeline.appendChild(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(window.SPECIAL_EVENTS)) {
|
||||||
|
const offsetStart = ((startCob % COBIE_UNITS.cosmocycle) + COBIE_UNITS.cosmocycle) % COBIE_UNITS.cosmocycle;
|
||||||
|
const events = [];
|
||||||
|
window.SPECIAL_EVENTS.forEach(ev => {
|
||||||
|
const evCob = parseCobiets(ev.cobie);
|
||||||
|
if (evCob === null) return;
|
||||||
|
const evOffset = ((evCob % COBIE_UNITS.cosmocycle) + COBIE_UNITS.cosmocycle) % COBIE_UNITS.cosmocycle;
|
||||||
|
if (evOffset >= offsetStart && evOffset < offsetStart + COBIE_UNITS.eonstrip) {
|
||||||
|
const rel = (evOffset - offsetStart) / COBIE_UNITS.eonstrip;
|
||||||
|
const durSec = ev.duration ? ev.duration : 0;
|
||||||
|
const dur = durSec / COBIE_UNITS.eonstrip;
|
||||||
|
events.push({ label: ev.label, start: rel, end: rel + dur });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
events.sort((a,b)=>a.start-b.start);
|
||||||
|
const columns = [];
|
||||||
|
events.forEach(ev=>{
|
||||||
|
let col=0;
|
||||||
|
while(columns[col] && columns[col] > ev.start) col++;
|
||||||
|
columns[col] = ev.end;
|
||||||
|
ev.col = col;
|
||||||
|
});
|
||||||
|
const width = 100 / (columns.length || 1);
|
||||||
|
events.forEach(ev=>{
|
||||||
|
const left = ev.col * width;
|
||||||
|
const elem = document.createElement(ev.end>ev.start ? 'div':'div');
|
||||||
|
if (ev.end>ev.start) {
|
||||||
|
elem.className='event-box';
|
||||||
|
elem.style.height=((ev.end-ev.start)*100)+'%';
|
||||||
|
} else {
|
||||||
|
elem.className='event-line';
|
||||||
|
}
|
||||||
|
elem.style.top=(ev.start*100)+'%';
|
||||||
|
elem.style.left=left+'%';
|
||||||
|
elem.style.width=`calc(${width}% - 2px)`;
|
||||||
|
elem.textContent=ev.label;
|
||||||
|
timeline.appendChild(elem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getStep(mods) {
|
function getStep(mods) {
|
||||||
// base step = 1 megasequence
|
// base step = 1 megasequence
|
||||||
let step = 1;
|
let step = 1;
|
||||||
@ -847,6 +901,11 @@ if (matchingOption) {
|
|||||||
currentTimezone = userTimezone;
|
currentTimezone = userTimezone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById('backToCalendar').addEventListener('click', () => {
|
||||||
|
document.getElementById('eonstripDetailView').style.display = 'none';
|
||||||
|
document.getElementById('calendarView').style.display = 'block';
|
||||||
|
});
|
||||||
|
|
||||||
updateCurrentTime();
|
updateCurrentTime();
|
||||||
updateCalendar();
|
updateCalendar();
|
||||||
updateInterval = setInterval(updateCurrentTime, 1000);
|
updateInterval = setInterval(updateCurrentTime, 1000);
|
||||||
|
|||||||
59
style.css
59
style.css
@ -368,6 +368,65 @@
|
|||||||
will-change: transform;
|
will-change: transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detail-view {
|
||||||
|
margin-top: 20px;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-btn {
|
||||||
|
background: linear-gradient(45deg, #00ffff, #0080ff);
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
color: #fff;
|
||||||
|
padding: 6px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-timeline {
|
||||||
|
position: relative;
|
||||||
|
height: 400px;
|
||||||
|
border-left: 2px solid #00ffff;
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-block {
|
||||||
|
position: absolute;
|
||||||
|
left: -40px;
|
||||||
|
width: calc(100% + 40px);
|
||||||
|
border-top: 1px dashed rgba(255,255,255,0.2);
|
||||||
|
color: #aaa;
|
||||||
|
font-size: 0.8em;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-box, .event-line {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
background: rgba(255,0,255,0.3);
|
||||||
|
border: 1px solid rgba(0,255,255,0.5);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 2px 4px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 0.7em;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-line {
|
||||||
|
height: 2px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Layout combining current time and analog clock */
|
/* Layout combining current time and analog clock */
|
||||||
.time-display {
|
.time-display {
|
||||||
--clock-size: 40vmin;
|
--clock-size: 40vmin;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user