Compare commits

...

136 Commits

Author SHA1 Message Date
Oleksandr Kozachuk 38e16687cb Make hands movement smooth on analag clock. 2025-07-10 14:37:56 +02:00
Kiyomichi Kosaka 2ade28e9cd Merge pull request #81 from ok2/codex/refactor-code-into-separate-files
Refactor JS into modules
2025-06-20 16:25:41 +02:00
Kiyomichi Kosaka a9b90729ff Refactor scripts into modules 2025-06-20 16:25:21 +02:00
Kiyomichi Kosaka ce17d2d5bf Merge pull request #80 from ok2/codex/refactor-code-to-reduce-size
Refactor JS helpers
2025-06-20 16:06:08 +02:00
Kiyomichi Kosaka 8f570ca4d3 refactor: reduce duplication via helpers 2025-06-20 16:05:51 +02:00
Kiyomichi Kosaka da56bfce7a Merge pull request #79 from ok2/codex/implement-swipe-mechanism-for-eonstrips
Enable swipe navigation in detail view
2025-06-20 14:04:19 +02:00
Kiyomichi Kosaka f38f4af4ca Add swipe navigation for detail view 2025-06-20 14:03:59 +02:00
Kiyomichi Kosaka ff5d2a7816 Merge pull request #78 from ok2/codex/improve-border-visibility-in-detail-view
Improve event border visibility
2025-06-20 13:59:21 +02:00
Kiyomichi Kosaka 3961bc3345 Improve visibility of event borders 2025-06-20 13:59:03 +02:00
Kiyomichi Kosaka 3974237f42 Merge pull request #77 from ok2/codex/ensure-visible-borders-for-event-boxes
Improve event box borders
2025-06-20 13:49:46 +02:00
Kiyomichi Kosaka 3822b0cdf7 Enhance detail event box visibility 2025-06-20 13:49:32 +02:00
Kiyomichi Kosaka 8451fa9f54 Merge pull request #76 from ok2/codex/fix-event-width-and-color-handling
Improve event overlap display
2025-06-20 13:42:02 +02:00
Kiyomichi Kosaka 26cfa8b868 Improve detail event display 2025-06-20 13:41:48 +02:00
Oleksandr Kozachuk 3f7a343b17 Improve tooltip. 2025-06-20 13:32:58 +02:00
Oleksandr Kozachuk 217c0b0028 Add Sleep. 2025-06-20 13:22:33 +02:00
Oleksandr Kozachuk a63ed16871 Move night 2 hours later. 2025-06-20 13:22:33 +02:00
Kiyomichi Kosaka 6e45dca49a Merge pull request #75 from ok2/codex/improve-tooltip-for-event-details
Improve event tooltip info
2025-06-20 13:21:47 +02:00
Kiyomichi Kosaka 1ec09e1b76 Improve event tooltip with series info 2025-06-20 13:21:32 +02:00
Kiyomichi Kosaka cf30e830a0 Merge pull request #74 from ok2/codex/update-eonstrips-detail-view-on-timezone-change 2025-06-20 10:31:21 +02:00
Kiyomichi Kosaka 65b85f1575 Update detail view on timezone change 2025-06-20 10:31:06 +02:00
Kiyomichi Kosaka 49b30a69e9 Merge pull request #73 from ok2/codex/rename-sleep-to-night-and-add-timezone-shift-attribute 2025-06-20 10:23:26 +02:00
Kiyomichi Kosaka 6c75140533 Rename Sleep event and add timezone shifting 2025-06-20 10:10:11 +02:00
Kiyomichi Kosaka 1002456a0c Merge pull request #72 from ok2/codex/update-event-boxes-and-current-time-line-layout 2025-06-20 08:42:08 +02:00
Kiyomichi Kosaka f6f1502f1a Adjust detail view timeline layout and auto-update 2025-06-20 08:41:44 +02:00
Kiyomichi Kosaka 615a14b5a8 Merge pull request #71 from ok2/codex/fix-layout-issues-in-detail-view 2025-06-20 08:35:03 +02:00
Kiyomichi Kosaka 08a4ef346a fix detail timeline visuals 2025-06-20 08:34:44 +02:00
Kiyomichi Kosaka 1fab01ffb9 Merge pull request #70 from ok2/codex/fix-event-box-label-positioning-and-toolbox-visibility 2025-06-20 08:27:43 +02:00
Kiyomichi Kosaka 441eec4e0c Adjust detail timeline layout and event label positions 2025-06-20 08:27:23 +02:00
Kiyomichi Kosaka d671e64c85 Merge pull request #69 from ok2/codex/refactor-event-box-labels-and-cronon-scale 2025-06-20 08:20:30 +02:00
Kiyomichi Kosaka 6c868f3768 Improve event labels and tooltips 2025-06-20 08:20:13 +02:00
Kiyomichi Kosaka 7a8a463169 Merge pull request #68 from ok2/codex/fix-analog-clock-background-visibility-in-eonstrip-view 2025-06-20 08:11:46 +02:00
Kiyomichi Kosaka 0f7f83c618 Fix fullscreen clock not hiding detail view 2025-06-20 08:11:28 +02:00
Kiyomichi Kosaka bf04c9569a Merge pull request #67 from ok2/codex/improve-timeline-and-event-label-visibility 2025-06-20 08:10:07 +02:00
Kiyomichi Kosaka 483b20e13d Improve detail timeline visibility 2025-06-20 08:09:50 +02:00
Kiyomichi Kosaka 757aa60ec4 Merge pull request #66 from ok2/codex/fix-chronon-numbers-visibility-and-add-timestamp-line 2025-06-20 08:03:04 +02:00
Kiyomichi Kosaka ead5d58d21 Fix detail view timeline 2025-06-20 08:02:40 +02:00
Kiyomichi Kosaka 3a591be7dc Merge pull request #65 from ok2/codex/fix-stuck-animation-issue-in-eonstript-detail-view 2025-06-20 08:00:28 +02:00
Kiyomichi Kosaka 7f706f12cd fix grid animation when navigating from detail 2025-06-20 08:00:10 +02:00
Kiyomichi Kosaka b2d8754c7e Merge pull request #64 from ok2/codex/fix-visibility-of-labels-in-detail-view 2025-06-20 07:55:49 +02:00
Kiyomichi Kosaka 1a61d7b3cc Allow detail labels to overflow 2025-06-20 07:55:34 +02:00
Oleksandr Kozachuk 93fe6bcdd2 Simplify events.js 2025-06-20 07:51:19 +02:00
Kiyomichi Kosaka 456f0744c4 Merge pull request #63 from ok2/codex/add-properties-to-control-event-visibility 2025-06-20 07:49:53 +02:00
Kiyomichi Kosaka 7bfee30e71 feat(events): configurable visibility 2025-06-20 07:49:34 +02:00
Kiyomichi Kosaka 2e6d870c0f Merge pull request #62 from ok2/codex/fix-visibility-of-event-labels-and-line-thickness 2025-06-20 07:47:54 +02:00
Kiyomichi Kosaka 88c37b566a Fix detail view labels for small events 2025-06-20 07:47:31 +02:00
Kiyomichi Kosaka 47d4a66b0f Merge pull request #61 from ok2/codex/fix-event-overflow-in-detail-view 2025-06-20 07:42:01 +02:00
Kiyomichi Kosaka 38a7de5ef8 fix(detail): clamp long events 2025-06-20 07:41:46 +02:00
Kiyomichi Kosaka 5e2ec31e4f Merge pull request #60 from ok2/codex/fix-bugs-in-analog-clock-and-megasequence 2025-06-20 07:35:29 +02:00
Kiyomichi Kosaka ec8f238a05 Fix detail view navigation and full screen 2025-06-20 07:35:04 +02:00
Kiyomichi Kosaka 01f06b84b2 Merge pull request #59 from ok2/codex/fix-missing-event-and-prev/next-buttons 2025-06-20 00:55:06 +02:00
Kiyomichi Kosaka c991a58296 Add daily Sleep event and restore detail navigation 2025-06-20 00:54:28 +02:00
Kiyomichi Kosaka 13dd3ec664 Merge pull request #58 from ok2/codex/add-interactive-view-for-eonstrip-events 2025-06-20 00:34:07 +02:00
Kiyomichi Kosaka 7e060760e7 Add vertical eonstrip detail view 2025-06-20 00:33:33 +02:00
Kiyomichi Kosaka d32b672289 Merge pull request #57 from ok2/codex/enhance-event-periodicity-support 2025-06-20 00:26:59 +02:00
Kiyomichi Kosaka 5e703813d7 Add flexible recurring events 2025-06-20 00:26:11 +02:00
Oleksandr Kozachuk d11b8cf19f Remove unneeded code. 2025-06-20 00:15:15 +02:00
Oleksandr Kozachuk 51aaa52112 Bigger marker. 2025-06-20 00:14:49 +02:00
Kiyomichi Kosaka 3a2df03eb3 Merge pull request #56 from ok2/codex/fix-analog-clock-markers-positioning 2025-06-20 00:06:04 +02:00
Kiyomichi Kosaka 3ea7f1e69f Set marker font size relative to radius 2025-06-20 00:05:48 +02:00
Oleksandr Kozachuk bc39eb3169 Simplify label. 2025-06-19 23:57:18 +02:00
Kiyomichi Kosaka ebbfc215b1 Merge pull request #55 from ok2/codex/find-issue-with-analog-clock-widget
Fix macOS widget resource bundling
2025-06-16 15:18:56 +02:00
Kiyomichi Kosaka 65e8457359 Add widget resource files 2025-06-16 15:18:43 +02:00
Kiyomichi Kosaka f4d4f518c6 Merge pull request #54 from ok2/codex/fix-widget-display-issue-on-macos
Fix macOS widget docs
2025-06-16 14:45:43 +02:00
Kiyomichi Kosaka 1d887cf2ca Update macOS widget instructions 2025-06-16 14:45:32 +02:00
Oleksandr Kozachuk 80e58578fc Fix widget. 2025-06-16 14:42:03 +02:00
Kiyomichi Kosaka 9256d5ecb7 Merge pull request #53 from ok2/codex/fix-bugs-in-cobie-analog-clock-widget
Fix WKWebView setup in widget
2025-06-16 14:39:09 +02:00
Kiyomichi Kosaka 4b8b29a657 Fix web view compilation issues 2025-06-16 14:38:54 +02:00
Kiyomichi Kosaka b749cfe5f4 Merge pull request #52 from ok2/codex/implement-cobie-analog-clock-widget
Implement CoBiE analog clock widget
2025-06-16 14:32:02 +02:00
Kiyomichi Kosaka 342e5c9c72 Add HTML-based analog clock widget 2025-06-16 14:31:47 +02:00
Oleksandr Kozachuk a486b97a2a Add empty Xcode project (remove old unsupported widget) 2025-06-16 14:25:00 +02:00
Kiyomichi Kosaka 81c93710ed Merge pull request #51 from ok2/codex/fix-widget-install-issue-on-mac-os-x
Fix macOS widget packaging
2025-06-16 13:00:58 +02:00
Kiyomichi Kosaka db3b93fc1b Fix macOS widget packaging 2025-06-16 12:58:21 +02:00
Kiyomichi Kosaka 9031736f7a Merge pull request #50 from ok2/codex/prevent-clock-size-change-on-font-scaling
Fix analog clock scaling
2025-06-15 15:23:19 +02:00
Kiyomichi Kosaka a6375d4148 Fix analog clock marker scaling 2025-06-15 15:23:09 +02:00
Kiyomichi Kosaka 7e4e4af00e Merge pull request #49 from ok2/codex/create-shell-script-for-macos-widget
Create script to build macOS widget
2025-06-15 15:03:17 +02:00
Kiyomichi Kosaka 1e1a961dc2 Add build script and remove widget duplicates 2025-06-15 15:02:12 +02:00
Kiyomichi Kosaka 356e904abc Merge pull request #48 from ok2/codex/implement-analog-clock-widget-for-macos
Add macOS dashboard widget
2025-06-15 14:57:07 +02:00
Kiyomichi Kosaka a1f987ff59 Add macOS dashboard widget 2025-06-15 14:56:16 +02:00
Oleksandr Kozachuk 8789b96ada Fix central point. 2025-06-15 14:50:26 +02:00
Kiyomichi Kosaka d8874f1164 Merge pull request #47 from ok2/codex/remove-white-border-from-clock-center
Remove border from analog clock center
2025-06-15 14:45:05 +02:00
Kiyomichi Kosaka fb5cec7837 Remove central clock border 2025-06-15 14:44:53 +02:00
Kiyomichi Kosaka 979acd4483 Merge pull request #46 from ok2/codex/reduce-central-point-size-on-big-screens
Fix clock center size and jitter
2025-06-15 14:43:23 +02:00
Kiyomichi Kosaka d7ba0479f4 Reduce center size and fix jitter 2025-06-15 14:43:13 +02:00
Kiyomichi Kosaka 794631dcba Merge pull request #45 from ok2/codex/fix-central-point-movement-and-size-adaptation
Fix analog clock center dot
2025-06-15 14:38:11 +02:00
Kiyomichi Kosaka fe8fa11f91 Fix center dot jitter and adjust size 2025-06-15 14:37:53 +02:00
Kiyomichi Kosaka 85e5979414 Merge pull request #44 from ok2/codex/fix-hand-jitter-in-analog-clock-animation
Fix analog clock hand center alignment
2025-06-15 14:31:58 +02:00
Kiyomichi Kosaka c7c1823594 fix clock hand centering 2025-06-15 14:31:46 +02:00
Kiyomichi Kosaka f40f3b8425 Merge pull request #43 from ok2/codex/match-time-block-height-to-clock-in-landscape-mode
Align landscape time block with analog clock
2025-06-15 14:27:39 +02:00
Kiyomichi Kosaka 69e426d9ce sync current time block height with analog clock 2025-06-15 14:27:24 +02:00
Kiyomichi Kosaka 4f7f47dc1c Merge pull request #42 from ok2/codex/fix-pixel-jump-in-0-f-markers
Fix marker jitter in analog clock
2025-06-15 14:25:50 +02:00
Kiyomichi Kosaka 40a7d87832 Fix jittering of clock markers 2025-06-15 14:25:30 +02:00
Kiyomichi Kosaka 433c4e6a75 Merge pull request #41 from ok2/codex/fix-analog-clock-size-in-landscape-mode
Fix analog clock scaling in iPhone landscape
2025-06-15 14:22:08 +02:00
Kiyomichi Kosaka eb3e206006 Fix analog clock scaling in landscape 2025-06-15 14:21:47 +02:00
Oleksandr Kozachuk 3005465d1d Bigger hands on analog clock. 2025-06-15 14:18:39 +02:00
Kiyomichi Kosaka 0a55bba1c9 Merge pull request #40 from ok2/codex/increase-analog-clock-size-in-landscape-mode
Fix analog clock size on iPhone landscape
2025-06-15 14:06:43 +02:00
Kiyomichi Kosaka b4c0799676 Increase clock size in iPhone landscape 2025-06-15 14:06:30 +02:00
Kiyomichi Kosaka a39c7216b3 Merge pull request #39 from ok2/codex/fix-alignment-of-hands-and-markers
Improve analog clock alignment
2025-06-15 13:32:15 +02:00
Oleksandr Kozachuk 59ba29e5a0 Small improvements 2025-06-15 13:31:18 +02:00
Kiyomichi Kosaka 31b326b090 refactor clock layout using unified radius 2025-06-15 11:28:02 +02:00
Oleksandr Kozachuk 3a765e01a8 Fix analog positioning 2025-06-15 11:03:01 +02:00
Kiyomichi Kosaka 2c90b77885 Merge pull request #38 from ok2/codex/adjust-tick-markers-alignment-on-analog-clock 2025-06-15 10:52:34 +02:00
Kiyomichi Kosaka dbbb21b3d8 fix analog clock alignment 2025-06-15 10:52:21 +02:00
Kiyomichi Kosaka b7a074a75d Merge pull request #37 from ok2/codex/fix-analog-clock-tick-marker-spacing-and-layout 2025-06-15 10:45:42 +02:00
Kiyomichi Kosaka d1514ee828 fix analog clock marker spacing 2025-06-15 10:45:27 +02:00
Kiyomichi Kosaka efbb9513da Merge pull request #36 from ok2/codex/move-tick-markers-to-outer-border 2025-06-15 10:27:36 +02:00
Kiyomichi Kosaka 8ac0d4943d Position ticks at outer clock edge 2025-06-15 10:27:22 +02:00
Kiyomichi Kosaka bde1f36642 Merge pull request #35 from ok2/codex/adjust-clock-hands-and-markers-size 2025-06-15 10:22:13 +02:00
Kiyomichi Kosaka 2838d9373c Add tick marks and longer hands for analog clock 2025-06-15 10:21:56 +02:00
Kiyomichi Kosaka aa2cca60b1 Merge pull request #34 from ok2/codex/synchronize-analog-clock-with-current-cobie-time 2025-06-15 10:07:09 +02:00
Kiyomichi Kosaka 3a63ced4e6 Sync analog clock with manual mode 2025-06-15 10:06:53 +02:00
Oleksandr Kozachuk f0ce3b29d6 fix label position on the clock 2025-06-15 09:38:32 +02:00
Kiyomichi Kosaka db68c2e328 Merge pull request #33 from ok2/codex/fix-text-position-on-analog-clock 2025-06-15 09:37:35 +02:00
Kiyomichi Kosaka 3db31682b9 fix clock label responsiveness 2025-06-15 09:37:11 +02:00
Kiyomichi Kosaka f97e99db1f Merge pull request #32 from ok2/codex/adjust-and-scale-cobie-time-display
Adjust analog clock label position
2025-06-15 01:19:30 +02:00
Kiyomichi Kosaka ccb018b3b2 Adjust analog clock label positioning and scaling 2025-06-15 01:19:14 +02:00
Kiyomichi Kosaka 0b79476e30 Merge pull request #31 from ok2/codex/add-time-system-label-to-analog-clock
Add label inside analog clock face
2025-06-15 01:14:48 +02:00
Kiyomichi Kosaka b96f402fc5 Add brand label to analog clock 2025-06-15 01:14:37 +02:00
Kiyomichi Kosaka d953bba4e3 Merge pull request #30 from ok2/codex/update-analog-hand-colors-for-clarity
Improve analog hand colors
2025-06-15 01:12:49 +02:00
Kiyomichi Kosaka 7a27ba933e Adjust analog clock hand colors 2025-06-15 01:12:36 +02:00
Kiyomichi Kosaka 1398c52e44 Merge pull request #29 from ok2/codex/use-futuristic-font-for-clock-markers
Update clock markers with Orbitron font
2025-06-15 01:06:58 +02:00
Kiyomichi Kosaka 81d0dd25a8 Use Orbitron font for analog clock markers 2025-06-15 01:06:32 +02:00
Kiyomichi Kosaka 6368eeb542 Merge pull request #28 from ok2/codex/fix-clock-hand-animation-at-last-second
Fix analog clock hand wraparound animation
2025-06-15 01:05:16 +02:00
Kiyomichi Kosaka fc0eba7cc7 smooth clock wraparound 2025-06-15 01:05:05 +02:00
Kiyomichi Kosaka b2f21c7cb5 Merge pull request #27 from ok2/codex/remove-box-around-markers-on-clock
Remove boxes from analog clock markers
2025-06-15 01:03:07 +02:00
Kiyomichi Kosaka 7887296f7a Remove boxes from analog clock markers 2025-06-15 01:02:49 +02:00
Kiyomichi Kosaka acbf7562ee Merge pull request #26 from ok2/codex/redesign-analog-clock-numbers
Style futuristic clock numbers
2025-06-15 00:57:35 +02:00
Kiyomichi Kosaka 4b425f39c1 Enhance analog clock numbers 2025-06-15 00:57:12 +02:00
Kiyomichi Kosaka d94cd3dd65 Merge pull request #25 from ok2/codex/replace-center-spot-with-cobie-time-logo
Refine clock logo
2025-06-15 00:55:38 +02:00
Kiyomichi Kosaka 7615c6457f Improve clock logo 2025-06-15 00:55:21 +02:00
Oleksandr Kozachuk adc6716344 Make hands bigger. 2025-06-15 00:51:24 +02:00
Kiyomichi Kosaka 3a3bfc8ebb Merge pull request #24 from ok2/codex/disable-animation-during-state-reset
Fix analog clock wrap-around animation
2025-06-15 00:51:04 +02:00
Kiyomichi Kosaka 7efe528168 fix analog clock wrap-around animation 2025-06-15 00:50:07 +02:00
Kiyomichi Kosaka 6371a195ea Merge pull request #23 from ok2/codex/fix-system-issue-after-update
Fix initialization timing for CoBiE UI
2025-06-15 00:41:05 +02:00
Kiyomichi Kosaka 552fdcc798 Delay initialization until DOM ready 2025-06-15 00:40:50 +02:00
Kiyomichi Kosaka 400e4144ec Merge pull request #22 from ok2/codex/check-cobie.js-usage-and-deduplicate-code
Deduplicate cobie utilities
2025-06-15 00:30:00 +02:00
Kiyomichi Kosaka 76e9bab8e6 expose cobie utilities for browser 2025-06-15 00:29:36 +02:00
12 changed files with 1040 additions and 554 deletions
Vendored
BIN
View File
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
# Build artifacts
CoBiEClock.wdgt
build-widget/
+20 -6
View File
@@ -54,15 +54,29 @@ An interactive web app that visualizes the **CosmoChron Binary Epoch (CoBiE)** t
```
├── index.html # Main HTML markup
├── analog.html # Analog clock interface
├── clock.js # Clock logic
├── style.css # Separated styles
├── script.js # JavaScript logic
├── README.md # This documentation
── assets/ # (Optional) images or external CSS/JS
├── cobie.js # CoBiE time system utilities
├── utils.js # Generic helper functions
├── animate.js # Shared animations
├── events.js # Sample calendar events
── style.css # Separated styles
├── script.js # Page interactions
├── README.md # This documentation
└── test/ # Unit tests
```
## macOS Widget
The repository provides a SwiftUI widget inside the Xcode project
located at `CoBiE/CoBiE.xcodeproj`.
1. Open the project in Xcode.
2. Select the `CoBiE Analog Clock` scheme.
3. Build and run to install the widget on macOS 13 or later.
The widget displays the analog CoBiE clock directly on your desktop or
in Notification Center.
## Contributing
1. Fork the repository.
+83
View File
@@ -0,0 +1,83 @@
(function(){
const lastAngles = {
handXeno: 0,
handQuantic: 0,
handChronon: 0,
handEonstrip: 0,
handMegasequence: 0
};
function rotateHand(id, angle) {
const el = document.getElementById(id);
if (!el) return;
const prev = lastAngles[id];
if (angle < prev) {
const target = angle + 360;
const handle = () => {
el.removeEventListener('transitionend', handle);
el.style.transition = 'none';
el.style.transform = `translateX(-50%) translateZ(0) rotate(${angle}deg)`;
void el.offsetWidth;
el.style.transition = '';
};
el.addEventListener('transitionend', handle, { once: true });
el.style.transform = `translateX(-50%) translateZ(0) rotate(${target}deg)`;
} else {
el.style.transform = `translateX(-50%) translateZ(0) rotate(${angle}deg)`;
}
lastAngles[id] = angle;
}
function animateSwipe(direction, onDone) {
const grid = document.getElementById('eonstripGrid');
if (!grid) { onDone(); return; }
grid.style.transition = 'none';
grid.style.transform = 'translateX(0)';
void grid.offsetWidth;
grid.style.transition = 'transform 0.3s ease';
grid.style.transform = `translateX(${direction > 0 ? '-100%' : '100%'})`;
function afterOut() {
grid.removeEventListener('transitionend', afterOut);
grid.style.transition = 'none';
grid.style.transform = `translateX(${direction > 0 ? '100%' : '-100%'})`;
onDone();
void grid.offsetWidth;
grid.style.transition = 'transform 0.3s ease';
grid.style.transform = 'translateX(0)';
}
grid.addEventListener('transitionend', afterOut);
}
function animateDetailSwipe(direction, onDone) {
const tl = document.getElementById('detailTimeline');
if (!tl) { onDone(); return; }
tl.style.transition = 'none';
tl.style.transform = 'translateX(0)';
void tl.offsetWidth;
tl.style.transition = 'transform 0.3s ease';
tl.style.transform = `translateX(${direction > 0 ? '-100%' : '100%'})`;
function afterOut() {
tl.removeEventListener('transitionend', afterOut);
tl.style.transition = 'none';
tl.style.transform = `translateX(${direction > 0 ? '100%' : '-100%'})`;
onDone();
void tl.offsetWidth;
tl.style.transition = 'transform 0.3s ease';
tl.style.transform = 'translateX(0)';
}
tl.addEventListener('transitionend', afterOut);
}
window.Animate = {
rotateHand,
animateSwipe,
animateDetailSwipe
};
})();
+117 -72
View File
@@ -1,70 +1,53 @@
// Minimal CoBiE analog clock logic wrapped in its own scope to
// avoid clashes with variables from other scripts on the page.
(function () {
const COBIE_EPOCH = 0;
const COBIE_UNITS = {
second: 1,
xenocycle: 0x10,
quantic: 0x100,
chronon: 0x1000,
eonstrip: 0x10000,
megasequence: 0x100000,
cosmocycle: 0x1000000,
};
const {
COBIE_EPOCH,
COBIE_UNITS,
floorDiv,
getTAIOffsetAt,
toCobiets
} = window.Cobie;
function floorDiv(a, b) {
return Math.trunc(a / b);
}
function getTAIOffsetAt(date) {
const taiEpoch = new Date('1958-01-01T00:00:00Z');
if (date < taiEpoch) return 0;
const leapSeconds = [
{ date: '1972-01-01T00:00:00Z', offset: 10 },
{ date: '1972-07-01T00:00:00Z', offset: 11 },
{ date: '1973-01-01T00:00:00Z', offset: 12 },
{ date: '1974-01-01T00:00:00Z', offset: 13 },
{ date: '1975-01-01T00:00:00Z', offset: 14 },
{ date: '1976-01-01T00:00:00Z', offset: 15 },
{ date: '1977-01-01T00:00:00Z', offset: 16 },
{ date: '1978-01-01T00:00:00Z', offset: 17 },
{ date: '1979-01-01T00:00:00Z', offset: 18 },
{ date: '1980-01-01T00:00:00Z', offset: 19 },
{ date: '1981-07-01T00:00:00Z', offset: 20 },
{ date: '1982-07-01T00:00:00Z', offset: 21 },
{ date: '1983-07-01T00:00:00Z', offset: 22 },
{ date: '1985-07-01T00:00:00Z', offset: 23 },
{ date: '1988-01-01T00:00:00Z', offset: 24 },
{ date: '1990-01-01T00:00:00Z', offset: 25 },
{ date: '1991-01-01T00:00:00Z', offset: 26 },
{ date: '1992-07-01T00:00:00Z', offset: 27 },
{ date: '1993-07-01T00:00:00Z', offset: 28 },
{ date: '1994-07-01T00:00:00Z', offset: 29 },
{ date: '1996-01-01T00:00:00Z', offset: 30 },
{ date: '1997-07-01T00:00:00Z', offset: 31 },
{ date: '1999-01-01T00:00:00Z', offset: 32 },
{ date: '2006-01-01T00:00:00Z', offset: 33 },
{ date: '2009-01-01T00:00:00Z', offset: 34 },
{ date: '2012-07-01T00:00:00Z', offset: 35 },
{ date: '2015-07-01T00:00:00Z', offset: 36 },
{ date: '2017-01-01T00:00:00Z', offset: 37 },
function getMarkerOffset(width) {
const points = [
{ width: 1024, value: 2 },
{ width: 450, value: 1.3 },
{ width: 200, value: 0.8 }
];
for (let i = 0; i < leapSeconds.length; i++) {
const d = new Date(leapSeconds[i].date);
if (date < d) return i === 0 ? 10 : leapSeconds[i - 1].offset;
// Sort points by width descending for easier handling
points.sort((a, b) => b.width - a.width);
for (let i = 0; i < points.length - 1; i++) {
const p1 = points[i];
const p2 = points[i + 1];
if (width <= p1.width && width >= p2.width) {
// Linear interpolation
const t = (width - p2.width) / (p1.width - p2.width);
return p2.value + t * (p1.value - p2.value);
}
}
return 37;
}
function toCobiets(date) {
const utcSec = floorDiv(date.getTime(), 1000);
const taiSec = utcSec + getTAIOffsetAt(date);
return taiSec - COBIE_EPOCH;
// Extrapolation for width > max known
if (width > points[0].width) {
const p1 = points[0];
const p2 = points[1];
const slope = (p1.value - p2.value) / (p1.width - p2.width);
return p1.value + slope * (width - p1.width);
}
// Extrapolation for width < min known
const p1 = points[points.length - 2];
const p2 = points[points.length - 1];
const slope = (p2.value - p1.value) / (p2.width - p1.width);
return p2.value + slope * (width - p2.width);
}
function placeMarkers() {
const clock = document.getElementById('clock');
let markers = clock.querySelectorAll('.marker');
let ticks = clock.querySelectorAll('.tick');
// Create markers if they don't exist yet
if (markers.length === 0) {
@@ -77,37 +60,95 @@
markers = clock.querySelectorAll('.marker');
}
// Position markers based on the current clock size
const radius = clock.offsetWidth / 2 - 20;
// Create tick marks once
if (ticks.length === 0) {
for (let i = 0; i < 256; i++) {
const t = document.createElement('div');
t.classList.add('tick');
if (i % 16 === 0) t.classList.add('big');
else if (i % 8 === 0) t.classList.add('mid');
// insert before markers so digits sit on top
clock.insertBefore(t, clock.firstChild);
}
ticks = clock.querySelectorAll('.tick');
}
// Unified radius based on the actual clock size
const baseRadius = clock.offsetWidth / 2;
// Tick lengths relative to the clock radius
const lenBig = baseRadius * 0.12;
const lenMid = baseRadius * 0.08;
const lenSmall = baseRadius * 0.05;
const outerR = baseRadius - 2; // just inside the border
// Distance from center so marker's outer edge sits just inside the big tick
const markerSize = markers[0] ? markers[0].offsetWidth : 0;
const inset = baseRadius * 0.001; // 0.1% of the radius
const markerRadius = outerR - lenBig - inset + markerSize / 2;
markers.forEach((m, i) => {
const angle = (i / 16) * 2 * Math.PI;
const x = radius * Math.sin(angle);
const y = -radius * Math.cos(angle);
m.style.left = `${clock.offsetWidth / 2 + x}px`;
m.style.top = `${clock.offsetHeight / 2 + y}px`;
m.style.left = '50%';
m.style.top = '50%';
m.style.transform =
`translate(-50%, -50%) rotate(${angle}rad) translate(0, -${markerRadius}px) rotate(${-angle}rad)`;
});
ticks.forEach((t, i) => {
let len = lenSmall;
if (t.classList.contains('big')) len = lenBig;
else if (t.classList.contains('mid')) len = lenMid;
const innerR = outerR - len;
const angle = ((i + 1) / 256) * 2 * Math.PI;
t.style.height = `${len}px`;
t.style.left = '50%';
t.style.top = '50%';
t.style.transform = `translate(-50%, 0) rotate(${angle}rad) translate(0, -${innerR}px)`;
if (clock.offsetWidth < 200 && !t.classList.contains('big') && !t.classList.contains('mid')) {
t.style.display = 'none';
} else {
t.style.display = '';
}
});
}
function updateClock() {
const now = new Date();
const cob = toCobiets(now);
function renderClock(cob) {
// Use fractional progress within each unit so angles stay small
const xf = (cob % COBIE_UNITS.quantic) / COBIE_UNITS.quantic;
const qf = (cob % COBIE_UNITS.chronon) / COBIE_UNITS.chronon;
const cf = (cob % COBIE_UNITS.eonstrip) / COBIE_UNITS.eonstrip;
const ef = (cob % COBIE_UNITS.megasequence) / COBIE_UNITS.megasequence;
const mf = (cob % COBIE_UNITS.cosmocycle) / COBIE_UNITS.cosmocycle;
document.getElementById('handXeno').style.transform = `rotate(${xf * 360}deg)`;
document.getElementById('handQuantic').style.transform = `rotate(${qf * 360}deg)`;
document.getElementById('handChronon').style.transform = `rotate(${cf * 360}deg)`;
document.getElementById('handEonstrip').style.transform = `rotate(${ef * 360}deg)`;
document.getElementById('handMegasequence').style.transform = `rotate(${mf * 360}deg)`;
Animate.rotateHand('handXeno', xf * 360);
Animate.rotateHand('handQuantic', qf * 360);
Animate.rotateHand('handChronon', cf * 360);
Animate.rotateHand('handEonstrip', ef * 360);
Animate.rotateHand('handMegasequence', mf * 360);
}
function updateClock() {
renderClock(toCobiets(new Date()));
}
let intervalId = null;
function startClock() {
clearInterval(intervalId);
updateClock();
intervalId = setInterval(updateClock, 1000);
}
function showTime(cob) {
clearInterval(intervalId);
renderClock(cob);
}
function initClock() {
placeMarkers();
updateClock();
setInterval(updateClock, 1000);
startClock();
const clk = document.getElementById('clock');
if (clk) {
clk.addEventListener('click', () => {
@@ -117,6 +158,10 @@
});
}
window.addEventListener('resize', placeMarkers);
window.CobieClock = {
start: startClock,
showTime
};
}
if (document.readyState === 'loading') {
+28 -2
View File
@@ -19,6 +19,20 @@ const COBIE_UNITS = {
astralmillennia: 0x1000000000000000
};
const EONSTRIP_NAMES = [
'Solprime', 'Lunex', 'Terros', 'Aquarion',
'Ventaso', 'Ignisar', 'Crystalos', 'Floraen',
'Faunor', 'Nebulus', 'Astraeus', 'Umbranox',
'Electros', 'Chronar', 'Radiantae', 'Etherion'
];
const MEGASEQUENCE_NAMES = [
'Azurean Tide', 'Sable Gleam', 'Verdanth Starfall', 'Crimson Dusk',
'Cobalt Frost', 'Amber Blaze', 'Viridian Bloom', 'Argent Veil',
'Helian Rise', 'Nocturne Shade', 'Celestine Aura', 'Pyralis Light',
'Zephyrine Whisper', 'Lustran Bounty', 'Umbral Echo', 'Mythran Epoch'
];
function floorDiv(a, b) {
return Math.trunc(a / b);
}
@@ -163,7 +177,7 @@ function formatCobieTimestamp(cobiets) {
return sign + rawDateHex + '.' + paddedTimeHex;
}
module.exports = {
const Cobie = {
COBIE_EPOCH,
COBIE_UNITS,
floorDiv,
@@ -171,5 +185,17 @@ module.exports = {
getTAIOffsetAt,
toCobiets,
fromCobiets,
formatCobieTimestamp
formatCobieTimestamp,
breakdownNonNeg,
EONSTRIP_NAMES,
MEGASEQUENCE_NAMES
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = Cobie;
}
// Expose globally when loaded in a browser environment
if (typeof window !== 'undefined') {
window.Cobie = Cobie;
}
+23 -10
View File
@@ -1,14 +1,27 @@
// Configuration of periodic events in CoBiE time
// Each event repeats every cosmocycle.
// "cobie" is the timestamp within the cosmocycle when the event occurs.
// "tag" is a short label that will be displayed on the calendar.
// Each object describes when the event occurs and how often it repeats.
//
// Fields:
// start - CoBiE timestamp when the first occurrence happens.
// end - optional CoBiE timestamp after which the event stops.
// unit - the unit of the recurrence ("second", "xenocycle", "quantic",
// "chronon", "eonstrip", "megasequence", "cosmocycle", ...).
// interval - how many units between occurrences (1 = every unit,
// 2 = every second unit, ...).
// label - short description displayed on the calendar.
// duration - optional length of the event in seconds.
// showMega - optional boolean, show label on the megasequence view (default true).
// showDetail - optional boolean, show event in the detail view (default true).
// color - optional hex color for the event (used in detail view)
window.SPECIAL_EVENTS = [
{ cobie: '49f4.9332', label: 'Afina', megasequence: 'Mythran Epoch', eonstrip: 'Ventaso' },
{ cobie: '11e5.f552', label: 'Oleks', megasequence: 'Umbral Echo', eonstrip: 'Ignisar' },
{ cobie: '4d07.a2b2', label: 'Vincent', megasequence: 'Azurean Tide', eonstrip: 'Floraen' },
{ cobie: '3edc.d430', label: 'Hochzeitstag', megasequence: 'Lustran Bounty', eonstrip: 'Electros' },
{ cobie: '330d.d4ae', label: 'Zusammentag', megasequence: 'Azurean Tide', eonstrip: 'Chronar' },
{ cobie: '11de.0c52', label: 'Anna', megasequence: 'Lustran Bounty', eonstrip: 'Radiantae' },
{ cobie: '467f.ae61', label: 'Iris', megasequence: 'Argent Veil', eonstrip: 'Etherion' }
{ cobie: '49f4.9332', label: 'Afina', color: '#e57373', unit: 'cosmocycle', interval: 1 },
{ cobie: '11e5.f552', label: 'Oleks', color: '#64b5f6', unit: 'cosmocycle', interval: 1 },
{ cobie: '4d07.a2b2', label: 'Vincent', color: '#81c784', unit: 'cosmocycle', interval: 1 },
{ cobie: '3edc.d430', label: 'Hochzeitstag', color: '#ffb74d', unit: 'cosmocycle', interval: 1 },
{ cobie: '330d.d4ae', label: 'Zusammentag', color: '#ba68c8', unit: 'cosmocycle', interval: 1 },
{ cobie: '11de.0c52', label: 'Anna', color: '#4db6ac', unit: 'cosmocycle', interval: 1 },
{ cobie: '467f.ae61', label: 'Iris', color: '#7986cb', unit: 'cosmocycle', interval: 1 },
{ cobie: '6854.7a75', label: 'Sleep', color: '#546e7a', unit: 'second', interval: 86400, duration: 28800, showMega: false },
{ cobie: '6854.9695', label: 'Night', color: '#212121', unit: 'second', interval: 86400, duration: 28800, showMega: false, shiftWithTimezone: true }
];
+21 -1
View File
@@ -5,6 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="format-detection" content="telephone=no">
<title>CoBiE Time System Calendar</title>
<!-- Orbitron provides a high-tech, futuristic look for the analog clock markers -->
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;600&family=Great+Vibes&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body>
@@ -29,6 +31,8 @@
<div class="hand chronon" id="handChronon"></div>
<div class="hand quantic" id="handQuantic"></div>
<div class="hand xeno" id="handXeno"></div>
<div class="clock-center"></div>
<div class="clock-label">CoBiE</div>
</div>
</div>
</div>
@@ -57,11 +61,24 @@
<button onclick="goToNow()">Now</button>
</div>
<div class="calendar-view">
<div class="calendar-view" id="calendarView">
<div class="calendar-header" id="calendarHeader">Loading...</div>
<div class="eonstrip-grid" id="eonstripGrid"></div>
</div>
<div id="eonstripDetailView" class="detail-view" style="display:none;">
<div class="detail-header">
<button id="backToCalendar" class="back-btn">Back</button>
<div class="detail-nav">
<button id="detailPrev" class="back-btn"></button>
<button id="detailNow" class="back-btn">Now</button>
<button id="detailNext" class="back-btn"></button>
</div>
<span id="detailTitle"></span>
</div>
<div class="detail-timeline" id="detailTimeline"></div>
</div>
<div class="time-details">
<h3 style="text-align: center; margin-bottom: 20px; color: #00ffff;">Time Breakdown</h3>
@@ -149,6 +166,9 @@
</div>
</div>
<script src="cobie.js"></script>
<script src="utils.js"></script>
<script src="animate.js"></script>
<script src="events.js"></script>
<script src="script.js"></script>
<script src="clock.js"></script>
+22
View File
@@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<defs>
<radialGradient id="bg" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#101018"/>
<stop offset="100%" stop-color="#050508"/>
</radialGradient>
<linearGradient id="ring" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#00ffff"/>
<stop offset="100%" stop-color="#ff00ff"/>
</linearGradient>
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<circle cx="50" cy="50" r="45" fill="url(#bg)" stroke="url(#ring)" stroke-width="4"/>
<path d="M55 30 H45 A20 20 0 0 0 45 70 H55" fill="none" stroke="#00ffff" stroke-width="6" stroke-linecap="round" filter="url(#glow)"/>
<path d="M65 30 H75 M70 30 V70" fill="none" stroke="#ff00ff" stroke-width="6" stroke-linecap="round" filter="url(#glow)"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+390 -423
View File
File diff suppressed because it is too large Load Diff
+241 -40
View File
@@ -72,7 +72,7 @@
display: flex;
flex-direction: column;
justify-content: center;
height: 40vmin;
height: var(--clock-size);
}
.current-time.manual::before {
@@ -360,6 +360,7 @@
}
}
.eonstrip-grid {
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
transform: translateX(0);
@@ -367,8 +368,145 @@
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;
}
.detail-nav {
display: flex;
gap: 10px;
align-items: center;
}
.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;
--scale-width: 24px;
height: 400px;
border-left: 3px solid #00ffff;
margin-right: 40px;
margin-left: 0;
overflow: visible;
}
.timeline-block {
position: absolute;
left: 0;
width: calc(100% + 40px);
text-align: left;
padding-left: 4px;
border-top: 1px dashed rgba(0,255,255,0.5);
color: #00ffff;
font-size: 0.9em;
font-weight: 600;
padding-top: 2px;
text-shadow: 0 0 4px #00ffff;
pointer-events: none;
z-index: 5;
}
.current-time-line {
position: absolute;
left: var(--scale-width);
width: calc(100% + 40px - var(--scale-width));
border-top: 2px solid #ff00ff;
color: #ff00ff;
font-size: 0.9em;
font-weight: 600;
padding-top: 2px;
text-shadow: 0 0 4px #ff00ff;
pointer-events: none;
z-index: 2;
}
.event-box, .event-line {
position: absolute;
left: var(--scale-width);
background: var(--bg-color, rgba(255,0,255,0.4));
border: 1px solid var(--border-color, rgba(0,255,255,0.7));
border-radius: 4px;
padding: 2px 4px;
color: var(--text-color, #fff);
font-size: 0.75em;
overflow: visible;
white-space: nowrap;
z-index: 3;
box-shadow: 0 0 4px var(--border-color, rgba(0,255,255,0.9));
}
.event-box {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.event-line {
height: 4px;
padding: 0;
overflow: visible;
}
.event-box.small-event {
overflow: visible;
padding: 0;
}
.event-line .event-label,
.event-box.small-event .event-label {
position: absolute;
bottom: 100%;
left: 50%;
transform: translate(-50%, -2px);
margin-bottom: 2px;
background: var(--bg-color, rgba(255,0,255,0.5));
border: 1px solid var(--border-color, rgba(0,255,255,0.8));
border-radius: 4px;
padding: 2px 6px;
white-space: nowrap;
color: var(--text-color, #fff);
font-size: 0.75em;
font-weight: 600;
text-shadow: 0 0 4px var(--border-color, #ff00ff);
z-index: 4;
box-shadow: 0 0 4px var(--border-color, rgba(0,255,255,0.9));
}
.event-line .event-label.below,
.event-box.small-event .event-label.below {
bottom: auto;
top: 100%;
transform: translate(-50%, 2px);
margin-bottom: 0;
margin-top: 2px;
}
.event-box:hover .tooltip,
.event-line:hover .tooltip {
opacity: 1;
}
/* Layout combining current time and analog clock */
.time-display {
--clock-size: 40vmin;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
@@ -376,9 +514,10 @@
gap: 20px;
}
.analog-clock-container {
flex: 0 0 auto;
width: 40vmin;
width: var(--clock-size);
margin-left: auto;
display: flex;
justify-content: center;
@@ -387,48 +526,101 @@
#clock {
position: relative;
width: 40vmin;
height: 40vmin;
width: var(--clock-size);
height: var(--clock-size);
border: 2px solid rgba(255, 255, 255, 0.2);
border-radius: 50%;
background: radial-gradient(circle at center, #0a0e27 0%, #1a1f3a 100%);
box-shadow: 0 0 25px rgba(0, 255, 255, 0.2), inset 0 0 40px rgba(255, 0, 255, 0.2);
}
#clock::after {
content: '';
.clock-center {
position: absolute;
top: 50%;
left: 50%;
width: 1.2em;
height: 1.2em;
transform: translate(-50%, -50%);
background: #ffffff;
width: calc(var(--clock-size) * 0.13);
height: calc(var(--clock-size) * 0.13);
transform: translate(-50%, -50%) translateZ(0);
background: url('logo.svg') center/contain no-repeat;
background-color: transparent;
border-radius: 50%;
box-shadow: 0 0 8px rgba(0, 255, 255, 0.8);
/* box-shadow: 0 0 8px rgba(0, 255, 255, 0.8); */
z-index: 2;
pointer-events: none;
}
@media screen and (min-width: 1200px) {
.clock-center {
width: calc(var(--clock-size) * 0.085);
height: calc(var(--clock-size) * 0.085);
}
}
.clock-label {
position: absolute;
bottom: 30%;
left: 50%;
transform: translateX(-50%);
font-family: 'Great Vibes', cursive;
font-size: calc(var(--clock-size) * 0.06);
color: #ffaaff;
text-shadow: 0 0 6px rgba(255, 0, 255, 0.6);
pointer-events: none;
z-index: 0;
}
body.fullscreen-clock .clock-label {
font-size: calc(var(--clock-size) * 0.08);
}
.marker {
position: absolute;
width: 2em;
height: 2em;
width: calc(var(--clock-size) * 0.13);
height: calc(var(--clock-size) * 0.13);
text-align: center;
line-height: 2em;
font-family: 'Courier New', monospace;
font-size: 1.1em;
color: #ffffff;
text-shadow: 0 0 8px rgba(0, 255, 255, 0.8);
transform: translate(-50%, -50%);
line-height: calc(var(--clock-size) * 0.13);
/* Use a futuristic font for the clock markers */
font-family: 'Orbitron', 'Trebuchet MS', 'Lucida Sans', Arial, sans-serif;
/* 1% of the clock radius */
font-size: calc(var(--clock-size) * 0.05);
font-weight: 600;
color: #00ffff;
background: none;
border: none;
border-radius: 0;
text-shadow: 0 0 6px rgba(0, 255, 255, 0.9), 0 0 12px rgba(0, 255, 255, 0.7);
box-shadow: none;
transform-origin: center;
font-variant-numeric: tabular-nums;
user-select: none;
pointer-events: none;
will-change: transform;
z-index: 1;
}
.tick {
position: absolute;
width: 2px;
background: #00ffff;
transform-origin: center top;
z-index: 0;
}
.tick.mid {
background: #66ffff;
}
.tick.big {
background: #ffffff;
}
.hand {
position: absolute;
bottom: 50%;
left: 50%;
transform-origin: bottom;
transition: transform 0.5s ease-in-out;
transform-origin: bottom center;
transform: translateX(-50%);
transition: transform 1s linear;
border-radius: 2px;
z-index: 1;
}
@@ -436,37 +628,44 @@
.hand.xeno {
width: 2px;
height: 50%;
background: linear-gradient(to top, #00ffff, #0066ff);
box-shadow: 0 0 8px #00ffff;
height: 44%;
background: linear-gradient(to top, #66ccff, #0044ff);
box-shadow: 0 0 8px #66ccff;
}
.hand.quantic {
width: 3px;
height: 45%;
background: linear-gradient(to top, #ff00ff, #6600ff);
box-shadow: 0 0 8px #ff00ff;
height: 40%;
background: linear-gradient(to top, #ff66ff, #9900ff);
box-shadow: 0 0 8px #ff66ff;
}
.hand.chronon {
width: 4px;
height: 40%;
background: linear-gradient(to top, #ffff00, #ff6600);
box-shadow: 0 0 8px #ffff99;
height: 34%;
background: linear-gradient(to top, #ff4444, #880000);
box-shadow: 0 0 8px #ff4444;
}
.hand.eonstrip {
width: 5px;
height: 35%;
background: linear-gradient(to top, #00ff88, #005544);
box-shadow: 0 0 8px #00ff88;
height: 30%;
background: linear-gradient(to top, #33ff99, #006633);
box-shadow: 0 0 8px #33ff99;
}
.hand.megasequence {
width: 6px;
height: 30%;
background: linear-gradient(to top, #ffa500, #552200);
box-shadow: 0 0 8px #ffa500;
height: 26%;
background: linear-gradient(to top, #ffbb33, #aa5500);
box-shadow: 0 0 8px #ffbb33;
}
@media only screen and (max-height: 430px) and (orientation: landscape) {
.time-display {
--clock-size: 70vmin;
}
}
body.fullscreen-clock .header,
@@ -474,9 +673,10 @@ body.fullscreen-clock .current-time,
body.fullscreen-clock .timezone-selector,
body.fullscreen-clock .calendar-controls,
body.fullscreen-clock .calendar-view,
body.fullscreen-clock .detail-view,
body.fullscreen-clock .time-details,
body.fullscreen-clock .explanations {
display: none;
display: none !important;
}
body.fullscreen-clock .time-display {
@@ -488,11 +688,12 @@ body.fullscreen-clock .time-display {
}
body.fullscreen-clock .analog-clock-container {
width: 80vmin;
--clock-size: 80vmin;
width: var(--clock-size);
margin-left: 0;
}
body.fullscreen-clock #clock {
width: 80vmin;
height: 80vmin;
width: var(--clock-size);
height: var(--clock-size);
}
+92
View File
@@ -0,0 +1,92 @@
(function(){
function parseColor(hex) {
if (!hex) return [255, 255, 255];
let c = hex.replace('#', '');
if (c.length === 3) c = c.split('').map(x => x + x).join('');
const num = parseInt(c, 16);
return [(num >> 16) & 255, (num >> 8) & 255, num & 255];
}
const toHex = v => v.toString(16).padStart(2, '0');
function hexToRgba(hex, a = 1) {
const [r, g, b] = parseColor(hex);
return `rgba(${r},${g},${b},${a})`;
}
function getContrastColor(hex) {
const [r, g, b] = parseColor(hex);
const yiq = (r * 299 + g * 587 + b * 114) / 1000;
return yiq >= 128 ? '#000' : '#fff';
}
function lightenColor(hex, p) {
const [r, g, b] = parseColor(hex).map(v =>
Math.min(255, Math.round(v + (255 - v) * p))
);
return '#' + [r, g, b].map(toHex).join('');
}
function getHumanDiff(d1, d2) {
let start = d1 < d2 ? d1 : d2;
let end = d1 < d2 ? d2 : d1;
let years = end.getUTCFullYear() - start.getUTCFullYear();
let months = end.getUTCMonth() - start.getUTCMonth();
let days = end.getUTCDate() - start.getUTCDate();
if (days < 0) {
months--;
let prevMonthDays = new Date(Date.UTC(
end.getUTCFullYear(),
end.getUTCMonth(), 0
)).getUTCDate();
days += prevMonthDays;
}
if (months < 0) {
years--;
months += 12;
}
let aligned = new Date(Date.UTC(
start.getUTCFullYear() + years,
start.getUTCMonth() + months,
start.getUTCDate() + days,
start.getUTCHours(),
start.getUTCMinutes(),
start.getUTCSeconds()
));
let diffMs = end.getTime() - aligned.getTime();
if (diffMs < 0) {
diffMs += 24 * 3600e3;
if (days > 0) {
days--;
} else {
months--;
if (months < 0) {
years--;
months += 12;
}
days = new Date(Date.UTC(
end.getUTCFullYear(),
end.getUTCMonth(), 0
)).getUTCDate();
}
}
let hours = Math.floor(diffMs / 3600e3); diffMs -= hours * 3600e3;
let minutes = Math.floor(diffMs / 60e3); diffMs -= minutes * 60e3;
let seconds = Math.floor(diffMs / 1e3);
return { years, months, days, hours, minutes, seconds };
}
window.Utils = {
parseColor,
hexToRgba,
getContrastColor,
lightenColor,
getHumanDiff
};
})();