Compare commits

...

2 Commits

Author SHA1 Message Date
luxick d0d58fa386 Bump version 2026-07-22 18:50:56 +02:00
luxick 891b0734ca Fix font size 2026-07-22 18:50:45 +02:00
+62 -4
View File
@@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name Game Datacards - Improved // @name Game Datacards - Improved
// @namespace local // @namespace local
// @version 1.1 // @version 1.2
// @description Adds card image export/import (ZIP) to the header, a button to rotate card backs for printing and a toggle for the official 10th edition card font // @description Adds card image export/import (ZIP) to the header, a button to rotate card backs for printing and a toggle for the official 10th edition card font
// @match *://game-datacards.eu/* // @match *://game-datacards.eu/*
// @grant none // @grant none
@@ -196,10 +196,35 @@
const FONT_STYLE_ID = 'gdc-card-font'; const FONT_STYLE_ID = 'gdc-card-font';
const FONT_PREF_KEY = 'gdc-card-font-enabled'; const FONT_PREF_KEY = 'gdc-card-font-enabled';
// Sizes below are the official ones for a full size card. The app draws cards // The official sizes are point sizes on a printed card, and CSS pt units say
// scaled by --card-scaling-factor, so every size is scaled along with it. // nothing about how large the app happens to draw that card. So instead of
// using pt directly, measure each card and derive how many layout pixels one
// point of the printed card is worth; --gdc-pt below carries that value.
// Printed datacard width, 7in. Raising it shrinks all card text and lowering
// it grows it, so it doubles as the tuning knob for the overall type size:
// localStorage.setItem('gdc-card-width-pt', 560)
const CARD_WIDTH_PT = 504;
function cardWidthPt() {
return Number(localStorage.getItem('gdc-card-width-pt')) || CARD_WIDTH_PT;
}
function pt(size) { function pt(size) {
return `calc(${size}pt * var(--card-scaling-factor, 1))`; return `calc(${size} * var(--gdc-pt, 1.333px))`;
}
// offsetWidth is the untransformed layout width, so this stays correct
// whether the app zooms cards by scaling the layout or by a CSS transform.
function updateFontScale() {
const reference = cardWidthPt();
document.querySelectorAll('.unit').forEach((unit) => {
const width = unit.offsetWidth;
if (!width) return;
const value = width / reference + 'px';
if (unit.style.getPropertyValue('--gdc-pt') !== value) {
unit.style.setProperty('--gdc-pt', value);
}
});
} }
function cardFontCss() { function cardFontCss() {
@@ -262,16 +287,49 @@
return localStorage.getItem(FONT_PREF_KEY) === '1'; return localStorage.getItem(FONT_PREF_KEY) === '1';
} }
// Cards get re-rendered on every edit and resized by the zoom control, so the
// scale has to be recomputed rather than set once.
var domObserver = null;
var sizeObserver = null;
var scalePending = false;
function scheduleFontScale() {
if (scalePending) return;
scalePending = true;
requestAnimationFrame(() => {
scalePending = false;
updateFontScale();
document.querySelectorAll('.unit').forEach((unit) => sizeObserver.observe(unit));
});
}
function applyCardFont(enabled) { function applyCardFont(enabled) {
const existing = document.getElementById(FONT_STYLE_ID); const existing = document.getElementById(FONT_STYLE_ID);
if (!enabled) { if (!enabled) {
if (existing) existing.remove(); if (existing) existing.remove();
if (domObserver) {
domObserver.disconnect();
sizeObserver.disconnect();
domObserver = null;
sizeObserver = null;
}
return; return;
} }
const style = existing || document.createElement('style'); const style = existing || document.createElement('style');
style.id = FONT_STYLE_ID; style.id = FONT_STYLE_ID;
style.textContent = cardFontCss(); style.textContent = cardFontCss();
if (!existing) document.head.appendChild(style); if (!existing) document.head.appendChild(style);
if (!domObserver) {
// childList only: the scale is written to the cards as an inline custom
// property, and watching attributes here would retrigger on our own write.
sizeObserver = new ResizeObserver(scheduleFontScale);
domObserver = new MutationObserver(scheduleFontScale);
domObserver.observe(document.body, { childList: true, subtree: true });
}
scheduleFontScale();
} }
function syncCardFontButton() { function syncCardFontButton() {