mirror of
git://f0xx.org/android_cast
synced 2026-07-29 07:39:15 +03:00
font struggling
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-theme="dark">
|
||||
<html lang="en" data-theme="dark" data-clock-font="dseg14-classic">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
@@ -11,12 +11,13 @@
|
||||
})();
|
||||
</script>
|
||||
<link rel="stylesheet" href="/app/androidcast_project/crashes/assets/css/app.css">
|
||||
<link rel="stylesheet" href="hub.css?v=20260530i">
|
||||
<link rel="stylesheet" href="hub.css?v=20260530k">
|
||||
<link rel="stylesheet" href="hub-logo-layers.css">
|
||||
<script src="assets/analytics.config.js"></script>
|
||||
<script src="/app/androidcast_project/crashes/assets/js/analytics.js" defer></script>
|
||||
</head>
|
||||
<body class="hub-page">
|
||||
<div id="lcd-alphabet-host" hidden aria-hidden="true"></div>
|
||||
<div id="overtime-alphabet-host" hidden aria-hidden="true"></div>
|
||||
<div id="quartz-alphabet-host" hidden aria-hidden="true"></div>
|
||||
<div id="hub-logo-stage" class="hub-logo-stage" hidden aria-hidden="true"></div>
|
||||
@@ -151,14 +152,52 @@
|
||||
}
|
||||
|
||||
var stage = document.getElementById('hub-logo-stage');
|
||||
if (!stage) return;
|
||||
|
||||
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
var supportsSvg = !!(svg && svg.createSVGRect);
|
||||
var supportsLayout = !!(window.CSS && CSS.supports && CSS.supports('object-fit', 'cover'));
|
||||
if (!supportsSvg || !supportsLayout) return;
|
||||
var logoEnabled = !!(stage && supportsSvg && supportsLayout);
|
||||
|
||||
var logoBuild = '20260530i';
|
||||
var logoBuild = '20260530k';
|
||||
|
||||
function hubAsset(rel) {
|
||||
var link = document.querySelector('link[href*="hub.css"]');
|
||||
if (link) {
|
||||
var href = link.getAttribute('href') || '';
|
||||
return href.replace(/[^/]*$/, '') + rel;
|
||||
}
|
||||
return rel;
|
||||
}
|
||||
|
||||
var LCD_FONT_CATALOG = {
|
||||
'dseg14-classic': {
|
||||
url: 'assets/dseg14-classic-alphabet.svg',
|
||||
prefix: 'd14c',
|
||||
css: '"DSEG14 Classic", "Consolas", monospace'
|
||||
},
|
||||
'dseg14-modern': {
|
||||
url: 'assets/dseg14-modern-alphabet.svg',
|
||||
prefix: 'd14m',
|
||||
css: '"DSEG14 Modern", "Consolas", monospace'
|
||||
},
|
||||
'ds-digital': {
|
||||
url: 'assets/ds-digital-alphabet.svg',
|
||||
prefix: 'dsd',
|
||||
css: '"DS-Digital", "Consolas", monospace'
|
||||
},
|
||||
'digital-7-mono-italic': {
|
||||
url: 'assets/digital-7-mono-italic-alphabet.svg',
|
||||
prefix: 'd7mi',
|
||||
css: '"Digital-7 Mono Italic", "Consolas", monospace'
|
||||
}
|
||||
};
|
||||
|
||||
var clockFontParams = new URLSearchParams(window.location.search);
|
||||
var clockFontKey = (clockFontParams.get('clockFont') || 'dseg14-classic').toLowerCase();
|
||||
if (!LCD_FONT_CATALOG[clockFontKey]) clockFontKey = 'dseg14-classic';
|
||||
var lcdFontReady = false;
|
||||
var lcdSymbolIds = {};
|
||||
var lcdFontPrefix = LCD_FONT_CATALOG[clockFontKey].prefix;
|
||||
var fragments = {
|
||||
space: 'assets/hub-logo-fragment-space.svg',
|
||||
globe: 'assets/hub-logo-fragment-globe.svg',
|
||||
@@ -185,6 +224,7 @@
|
||||
return base + '?v=' + logoBuild;
|
||||
}
|
||||
|
||||
if (logoEnabled) {
|
||||
list.forEach(function (name) {
|
||||
var img = document.createElement('img');
|
||||
img.className = 'hub-logo-layer hub-logo-layer--' + name;
|
||||
@@ -208,6 +248,7 @@
|
||||
|
||||
stage.hidden = false;
|
||||
stage.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
|
||||
/* Nav dock overlaps globe left hemisphere; stack top → bottom. */
|
||||
var GLOBE_VIEW = { imgW: 1920, imgH: 1080, cx: 720, cy: 560, r: 330 };
|
||||
@@ -443,7 +484,7 @@
|
||||
}
|
||||
|
||||
function bindCompassOpen() {
|
||||
if (!compassLayer) return;
|
||||
if (!logoEnabled || !compassLayer) return;
|
||||
var open = function () { openDeploymentModel(); };
|
||||
compassLayer.addEventListener('click', open);
|
||||
compassLayer.addEventListener('keydown', function (ev) {
|
||||
@@ -586,6 +627,113 @@
|
||||
return null;
|
||||
}
|
||||
|
||||
function lcdSymbolId(ch) {
|
||||
var p = lcdFontPrefix;
|
||||
if (ch >= '0' && ch <= '9') return p + '-' + ch;
|
||||
if (ch === ':') return p + '-colon';
|
||||
if (ch === '+') return p + '-plus';
|
||||
if (ch === '-') return p + '-minus';
|
||||
if (ch === '/') return p + '-slash';
|
||||
if (ch === '.') return p + '-dot';
|
||||
if (ch === ' ') return p + '-space';
|
||||
if (ch >= 'A' && ch <= 'Z') return p + '-' + ch;
|
||||
if (ch >= 'a' && ch <= 'z') return p + '-' + ch.toUpperCase();
|
||||
return null;
|
||||
}
|
||||
|
||||
function loadLcdAlphabet(done) {
|
||||
var host = document.getElementById('lcd-alphabet-host');
|
||||
var spec = LCD_FONT_CATALOG[clockFontKey];
|
||||
if (!host || !spec) { done(false); return; }
|
||||
fetch(hubAsset(spec.url) + '?v=' + logoBuild)
|
||||
.then(function (res) {
|
||||
if (!res.ok) throw new Error('alphabet fetch failed');
|
||||
return res.text();
|
||||
})
|
||||
.then(function (svgText) {
|
||||
host.replaceChildren();
|
||||
var parser = new DOMParser();
|
||||
var doc = parser.parseFromString(svgText, 'image/svg+xml');
|
||||
var sprite = doc.documentElement;
|
||||
if (sprite.querySelector('parsererror')) throw new Error('alphabet parse failed');
|
||||
sprite.setAttribute('aria-hidden', 'true');
|
||||
sprite.style.cssText = 'position:absolute;width:0;height:0;overflow:hidden;pointer-events:none';
|
||||
host.appendChild(sprite);
|
||||
lcdSymbolIds = {};
|
||||
sprite.querySelectorAll('symbol').forEach(function (sym) {
|
||||
if (sym.id) lcdSymbolIds[sym.id] = sym;
|
||||
});
|
||||
lcdFontReady = Object.keys(lcdSymbolIds).length > 0;
|
||||
document.documentElement.setAttribute('data-clock-font', clockFontKey);
|
||||
var widget = document.getElementById('hub-clock-widget');
|
||||
if (widget) widget.setAttribute('data-lcd-mode', lcdFontReady ? 'svg' : 'text');
|
||||
done(lcdFontReady);
|
||||
})
|
||||
.catch(function () {
|
||||
lcdFontReady = false;
|
||||
var widget = document.getElementById('hub-clock-widget');
|
||||
if (widget) widget.setAttribute('data-lcd-mode', 'text');
|
||||
done(false);
|
||||
});
|
||||
}
|
||||
|
||||
function cloneLcdSymbolContent(svg, sym) {
|
||||
sym.childNodes.forEach(function (node) {
|
||||
if (node.nodeType !== 1) return;
|
||||
svg.appendChild(node.cloneNode(true));
|
||||
});
|
||||
}
|
||||
|
||||
function renderLcdText(el, text, opts) {
|
||||
opts = opts || {};
|
||||
if (!el) return;
|
||||
el.innerHTML = '';
|
||||
el.classList.add('cw-lcd-text');
|
||||
var fontCss = LCD_FONT_CATALOG[clockFontKey].css;
|
||||
if (!lcdFontReady) {
|
||||
el.textContent = text;
|
||||
el.style.fontFamily = fontCss;
|
||||
return;
|
||||
}
|
||||
var renderedSvg = false;
|
||||
String(text).split('').forEach(function (ch) {
|
||||
var up = ch.toUpperCase();
|
||||
var sid = lcdSymbolId(up === ch ? ch : up);
|
||||
if (!sid || !lcdSymbolIds[sid]) {
|
||||
var fb = document.createElement('span');
|
||||
fb.className = 'ot-fallback-char' + (opts.bold ? ' ot-fallback-char--bold' : '');
|
||||
fb.style.fontFamily = fontCss;
|
||||
fb.textContent = ch === ' ' ? '\u00A0' : ch;
|
||||
el.appendChild(fb);
|
||||
return;
|
||||
}
|
||||
var sym = lcdSymbolIds[sid];
|
||||
if (!sym.childNodes.length) {
|
||||
var emptyFb = document.createElement('span');
|
||||
emptyFb.className = 'ot-fallback-char';
|
||||
emptyFb.style.fontFamily = fontCss;
|
||||
emptyFb.textContent = ch === ' ' ? '\u00A0' : ch;
|
||||
el.appendChild(emptyFb);
|
||||
return;
|
||||
}
|
||||
renderedSvg = true;
|
||||
var wrap = document.createElement('span');
|
||||
wrap.className = 'ot-glyph-wrap' + (opts.bold ? ' ot-glyph-wrap--bold' : '');
|
||||
if (opts.blinkColon && ch === ':') wrap.className += ' ot-colon-blink';
|
||||
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.setAttribute('viewBox', sym.getAttribute('viewBox') || '0 0 20 32');
|
||||
svg.setAttribute('class', 'ot-glyph');
|
||||
svg.setAttribute('aria-hidden', 'true');
|
||||
cloneLcdSymbolContent(svg, sym);
|
||||
wrap.appendChild(svg);
|
||||
el.appendChild(wrap);
|
||||
});
|
||||
if (!renderedSvg) {
|
||||
el.textContent = text;
|
||||
el.style.fontFamily = fontCss;
|
||||
}
|
||||
}
|
||||
|
||||
function loadQuartzAlphabet(done) {
|
||||
var host = document.getElementById('quartz-alphabet-host');
|
||||
if (!host) { done(false); return; }
|
||||
@@ -817,19 +965,18 @@
|
||||
});
|
||||
|
||||
function setClockopiaText(el, text) {
|
||||
if (!el) return;
|
||||
el.textContent = text;
|
||||
renderLcdText(el, text, {});
|
||||
}
|
||||
|
||||
function updateClockWidget() {
|
||||
var now = new Date();
|
||||
var p = timeParts(now, primaryTz);
|
||||
setClockopiaText(document.getElementById('cw-hm-lcd'), p.hh + ':' + p.mm);
|
||||
setClockopiaText(document.getElementById('cw-colon-lcd'), ':');
|
||||
setClockopiaText(document.getElementById('cw-ss-lcd'), p.ss);
|
||||
setClockopiaText(document.getElementById('cw-tz-text'), gmtOffsetLabel(now, primaryTz));
|
||||
setClockopiaText(document.getElementById('cw-region'), regionLabel(primaryTz));
|
||||
setClockopiaText(document.getElementById('cw-date-line'), formatDateLine(now, primaryTz));
|
||||
renderLcdText(document.getElementById('cw-hm-lcd'), p.hh + ':' + p.mm, { bold: true });
|
||||
renderLcdText(document.getElementById('cw-colon-lcd'), ':', { blinkColon: true });
|
||||
renderLcdText(document.getElementById('cw-ss-lcd'), p.ss, {});
|
||||
renderLcdText(document.getElementById('cw-tz-text'), gmtOffsetLabel(now, primaryTz), {});
|
||||
renderLcdText(document.getElementById('cw-region'), regionLabel(primaryTz), {});
|
||||
renderLcdText(document.getElementById('cw-date-line'), formatDateLine(now, primaryTz), {});
|
||||
|
||||
secondary.forEach(function (clock) {
|
||||
var t = timeParts(now, clock.tz);
|
||||
@@ -920,8 +1067,10 @@
|
||||
widget.releasePointerCapture(ev.pointerId);
|
||||
});
|
||||
})();
|
||||
updateClockWidget();
|
||||
setInterval(updateClockWidget, 1000);
|
||||
loadLcdAlphabet(function () {
|
||||
updateClockWidget();
|
||||
setInterval(updateClockWidget, 1000);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user