Initial commit
This commit is contained in:
commit
75af9b74cb
3 changed files with 2610 additions and 0 deletions
298
index.html
Normal file
298
index.html
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Pixação</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
#pager {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.screen {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#screen-greeting,
|
||||
#screen-date {
|
||||
font-family: monospace;
|
||||
color: #1a1612;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
|
||||
#screen-greeting {
|
||||
font-size: clamp(1rem, 3vw, 1.6rem);
|
||||
margin: 0 3em 0 3em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#screen-date {
|
||||
font-size: clamp(0.8rem, 2.4vw, 1.3rem);
|
||||
font-face: monospace;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#screen-greeting a {
|
||||
color: inherit;
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 0.2em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#diagram {
|
||||
max-height: 80vh;
|
||||
max-width: 80vw;
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#print-text {
|
||||
font-family: sans-serif;
|
||||
font-size: 0.82rem;
|
||||
color: #999;
|
||||
max-width: 56ch;
|
||||
line-height: 1.65;
|
||||
text-align: justify;
|
||||
margin: 0 3em 0 3em;
|
||||
}
|
||||
|
||||
@media print {
|
||||
/* margin:0 hints to Chromium/Firefox to suppress their date/title/URL headers.
|
||||
Paper size is left to the browser/user so this works on A4, Letter, etc. */
|
||||
@page {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: auto !important;
|
||||
overflow: visible !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* position:fixed;inset:0 pins to the paper box in all browsers.
|
||||
vw/vh would resolve to the screen viewport in Chromium and shrink into a corner. */
|
||||
#pager {
|
||||
transform: none !important;
|
||||
transition: none !important;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
padding: 14mm;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
/* Hide all screens, then re-show the three we want */
|
||||
.screen {
|
||||
display: none !important;
|
||||
height: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
#screen-date,
|
||||
#screen-diagram,
|
||||
#screen-text {
|
||||
display: flex !important;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
break-inside: avoid;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
#screen-date {
|
||||
font-size: 18pt;
|
||||
}
|
||||
|
||||
/* Without this, the SVG hugs the left edge of the block-level container. */
|
||||
#diagram-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#diagram {
|
||||
width: 50% !important;
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
|
||||
/* Browsers (esp. Chromium) darken light text to save ink unless asked
|
||||
not to. print-color-adjust: exact preserves the gray. */
|
||||
#print-text {
|
||||
font-size: 14pt;
|
||||
max-width: 50em;
|
||||
line-height: 1.55;
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="pager">
|
||||
|
||||
<div class="screen" id="screen-date"></div>
|
||||
|
||||
<div class="screen" id="screen-greeting">
|
||||
<span>
|
||||
<a href="#" onclick="event.preventDefault(); window.print();">Print this page</a> to bestow protection from unforeseen circumstances upon your computer.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="screen" id="screen-diagram">
|
||||
<div id="diagram-container"></div>
|
||||
</div>
|
||||
|
||||
<div class="screen" id="screen-text">
|
||||
<p id="print-text">
|
||||
THE BLESSING IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND DHARMA.
|
||||
IN NO EVENT SHALL THE AUTHORS OR CUSTODIANS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
PRAYER, OFFERING OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE BLESSING OR THE USE OR OTHER DEALINGS IN THE BLESSING.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// ── Pager ──────────────────────────────────────────────────────────────────
|
||||
const pager = document.getElementById('pager');
|
||||
const PAGES = pager.querySelectorAll('.screen').length;
|
||||
window.currentPage = Math.min(parseInt(sessionStorage.getItem('page') || '0', 10), PAGES - 1);
|
||||
let locked = false;
|
||||
|
||||
pager.style.transition = 'none';
|
||||
pager.style.transform = `translateY(${-window.currentPage * 100}vh)`;
|
||||
|
||||
function goTo(n) {
|
||||
n = Math.max(0, Math.min(PAGES - 1, n));
|
||||
if (n === window.currentPage || locked) return;
|
||||
locked = true;
|
||||
window.currentPage = n;
|
||||
sessionStorage.setItem('page', n);
|
||||
pager.style.transition = 'transform 0.45s ease-in-out';
|
||||
pager.style.transform = `translateY(${-window.currentPage * 100}vh)`;
|
||||
setTimeout(() => { locked = false; }, 500);
|
||||
}
|
||||
|
||||
window.addEventListener('wheel', e => {
|
||||
e.preventDefault();
|
||||
if (e.deltaY > 0) goTo(window.currentPage + 1);
|
||||
else if (e.deltaY < 0) goTo(window.currentPage - 1);
|
||||
}, { passive: false });
|
||||
|
||||
let touchStartY = null;
|
||||
window.addEventListener('touchstart', e => {
|
||||
touchStartY = e.touches[0].clientY;
|
||||
}, { passive: true });
|
||||
window.addEventListener('touchend', e => {
|
||||
if (touchStartY === null) return;
|
||||
const dy = touchStartY - e.changedTouches[0].clientY;
|
||||
if (Math.abs(dy) > 40) {
|
||||
if (dy > 0) goTo(window.currentPage + 1);
|
||||
else goTo(window.currentPage - 1);
|
||||
}
|
||||
touchStartY = null;
|
||||
}, { passive: true });
|
||||
|
||||
window.addEventListener('keydown', e => {
|
||||
switch (e.key) {
|
||||
case 'ArrowDown': case 'ArrowRight': case 'Enter': case 'PageDown': case ' ':
|
||||
e.preventDefault(); goTo(window.currentPage + 1); break;
|
||||
case 'ArrowUp': case 'ArrowLeft': case 'PageUp':
|
||||
e.preventDefault(); goTo(window.currentPage - 1); break;
|
||||
}
|
||||
});
|
||||
|
||||
// ── SVG substitution ───────────────────────────────────────────────────────
|
||||
async function main() {
|
||||
const [diagramText, pixacaoText] = await Promise.all([
|
||||
fetch('template diagram.svg').then(r => r.text()),
|
||||
fetch('template pixacao onepage.svg').then(r => r.text()),
|
||||
]);
|
||||
|
||||
const parser = new DOMParser();
|
||||
const diagramDoc = parser.parseFromString(diagramText, 'image/svg+xml');
|
||||
const pixacaoDoc = parser.parseFromString(pixacaoText, 'image/svg+xml');
|
||||
|
||||
// Build symbol map: digit → group (already carries its own centering transform)
|
||||
const symbols = {};
|
||||
pixacaoDoc.querySelectorAll('[id^="sym-"]').forEach(g => {
|
||||
symbols[g.id.slice(4)] = g;
|
||||
});
|
||||
|
||||
// Slot reading order: top-to-bottom within each column, left-to-right across columns
|
||||
const slotOrder = [
|
||||
's1', 's2', 's3', 's4', 's5', 's6',
|
||||
's101', 's102', 's103', 's104', 's105', 's106',
|
||||
's201', 's202', 's203', 's204', 's205', 's206',
|
||||
's301', 's302', 's303', 's304', 's305', 's306',
|
||||
's401', 's402', 's403', 's404', 's405', 's406',
|
||||
];
|
||||
|
||||
// Fetch from NIST Randomness Beacon; use first 30 chars of outputValue
|
||||
const { pulse } = await fetch('https://beacon.nist.gov/beacon/2.0/pulse/last')
|
||||
.then(r => r.json());
|
||||
const hexString = pulse.outputValue.slice(0, slotOrder.length).toLowerCase();
|
||||
|
||||
// ISO UTC timestamp, no milliseconds
|
||||
document.getElementById('screen-date').textContent =
|
||||
pulse.timeStamp.replace(/\.\d{3}Z$/, 'Z');
|
||||
|
||||
// Substitute: each slot is a <rect> whose x/y give the cell origin;
|
||||
// sym groups carry their own centering transform, so just stack them.
|
||||
slotOrder.forEach((slotId, i) => {
|
||||
const rect = diagramDoc.getElementById(slotId);
|
||||
if (!rect) return;
|
||||
const sym = symbols[hexString[i]];
|
||||
if (!sym) return;
|
||||
|
||||
const g = diagramDoc.createElementNS('http://www.w3.org/2000/svg', 'g');
|
||||
g.setAttribute('transform', `translate(${rect.getAttribute('x')},${rect.getAttribute('y')})`);
|
||||
|
||||
const clone = diagramDoc.importNode(sym, true);
|
||||
clone.removeAttribute('id');
|
||||
clone.querySelectorAll('[id]').forEach(el => el.removeAttribute('id'));
|
||||
g.appendChild(clone);
|
||||
|
||||
rect.parentNode.replaceChild(g, rect);
|
||||
});
|
||||
|
||||
const svgEl = diagramDoc.documentElement;
|
||||
svgEl.setAttribute('width', '400');
|
||||
svgEl.setAttribute('height', '850');
|
||||
svgEl.setAttribute('id', 'diagram');
|
||||
|
||||
document.getElementById('diagram-container').appendChild(
|
||||
document.importNode(svgEl, true)
|
||||
);
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
document.getElementById('screen-date').textContent = 'Error: ' + err.message;
|
||||
console.error(err);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1085
template diagram.svg
Normal file
1085
template diagram.svg
Normal file
File diff suppressed because it is too large
Load diff
|
After Width: | Height: | Size: 56 KiB |
1227
template pixacao onepage.svg
Normal file
1227
template pixacao onepage.svg
Normal file
File diff suppressed because it is too large
Load diff
|
After Width: | Height: | Size: 72 KiB |
Loading…
Add table
Add a link
Reference in a new issue