variables titles are ok
This commit is contained in:
@@ -59,46 +59,119 @@ import Splitting from "splitting";
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
|
||||
function initTitles(){
|
||||
let titles = document.querySelectorAll('#block-leshed-identitedusite>a, article.node-type-projet>h2');
|
||||
// Rendu typographique des titres. Police Epilogue = axe variable `wght`
|
||||
// (100–900) uniquement ; l'italique est un fichier séparé (font-style).
|
||||
const TITLE_STYLE = {
|
||||
// 3 groupes de graisse : thin = majorité (défaut), medium = quelques,
|
||||
// bold = les pics. Les fines ne sont pas comptées (c'est le reste).
|
||||
wghtThin: { min: 100, max: 200 }, // majorité (défaut)
|
||||
wghtMedium: { min: 200, max: 400 }, // quelques
|
||||
wghtBold: { min: 800, max: 900 }, // pics
|
||||
boldRatio: 0.28, // proportion de pics gras par mot
|
||||
mediumRatio: 0.12, // proportion de medium par mot
|
||||
italicOnBold: 0.6, // proba d'italique sur un pic
|
||||
italicOnMedium: 0.4, // proba d'italique sur un medium
|
||||
italicOnThin: 0.30, // proba d'italique sur une fine
|
||||
};
|
||||
|
||||
function initTitles() {
|
||||
const titles = document.querySelectorAll('#block-leshed-identitedusite>a, article.node-type-projet>header>h2');
|
||||
for (const txt of titles) {
|
||||
console.log(txt.innerText, '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -');
|
||||
let splitted = Splitting({ target: txt, by: 'chars'});
|
||||
console.log("splitted", splitted);
|
||||
|
||||
const splitted = Splitting({ target: txt, by: 'chars' });
|
||||
for (const word of splitted[0].words) {
|
||||
let chars = word.getElementsByClassName('char');
|
||||
console.log("chars", chars);
|
||||
styleWordChars(Array.from(word.getElementsByClassName('char')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const char of chars) {
|
||||
console.log(char.innerText);
|
||||
/**
|
||||
* Tire k positions réparties régulièrement dans [0, n[ : le mot est découpé
|
||||
* en k cases contiguës, une position au hasard par case (aléa contrôlé, pas
|
||||
* de paquets). Les positions déjà prises par un autre groupe sont évitées.
|
||||
*/
|
||||
function spreadPositions(n, k, exclude = new Set()) {
|
||||
const set = new Set();
|
||||
for (let i = 0; i < k; i++) {
|
||||
const start = Math.floor((i * n) / k);
|
||||
const end = Math.floor(((i + 1) * n) / k); // borne exclue
|
||||
const span = Math.max(1, end - start);
|
||||
let pos = randomInt(start, start + span);
|
||||
let guard = 0;
|
||||
while ((exclude.has(pos) || set.has(pos)) && guard < span) {
|
||||
pos = start + ((pos - start + 1) % span);
|
||||
guard++;
|
||||
}
|
||||
set.add(pos);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
// Weight
|
||||
let wght = randomInt(150, 600);//200 + Math.random() * 800;
|
||||
/**
|
||||
* Applique graisse + italique caractère par caractère.
|
||||
*
|
||||
* Majorité de fines ; quelques medium et quelques pics gras, chacun réparti
|
||||
* régulièrement dans le mot. L'italique est corrélé à la graisse.
|
||||
*/
|
||||
function styleWordChars(chars) {
|
||||
const n = chars.length;
|
||||
if (!n) return;
|
||||
|
||||
// Ital
|
||||
let ital = Math.random() > 0.7 ? 1 : 0;
|
||||
// char.style.fontVariationSettings = `'wght' ${wght}, 'wdth' ${wdth}, 'ital' ${ital}`;
|
||||
char.style.fontVariationSettings = `'wght' ${wght}`;
|
||||
char.style.fontStyle = ital ? 'italic' : 'normal';
|
||||
// Accents répartis régulièrement : d'abord les pics gras, puis les medium
|
||||
// (en évitant les positions déjà grasses). Le reste sera fin.
|
||||
const bold = spreadPositions(n, Math.round(n * TITLE_STYLE.boldRatio));
|
||||
const medium = spreadPositions(n, Math.round(n * TITLE_STYLE.mediumRatio), bold);
|
||||
|
||||
// // Letter spacing
|
||||
// let wdth_wght_ratio = wdth*wght / 10000;
|
||||
// console.log('wdth_wght_ratio',wdth_wght_ratio);
|
||||
// 1) Décide graisse + italique pour chaque caractère.
|
||||
const decisions = chars.map((char, i) => {
|
||||
let range, pItal;
|
||||
if (bold.has(i)) {
|
||||
range = TITLE_STYLE.wghtBold;
|
||||
pItal = TITLE_STYLE.italicOnBold;
|
||||
}
|
||||
else if (medium.has(i)) {
|
||||
range = TITLE_STYLE.wghtMedium;
|
||||
pItal = TITLE_STYLE.italicOnMedium;
|
||||
}
|
||||
else {
|
||||
range = TITLE_STYLE.wghtThin;
|
||||
pItal = TITLE_STYLE.italicOnThin;
|
||||
}
|
||||
return {
|
||||
char,
|
||||
wght: randomInt(range.min, range.max + 1),
|
||||
ital: Math.random() < pItal,
|
||||
};
|
||||
});
|
||||
|
||||
// char.style.letterSpacing = wdth_wght_ratio < 1 ? "0.5em" : ital ? "0.05em" : 0;
|
||||
// if (ital) {
|
||||
// let prev_char = char.previousSibling;
|
||||
// if (prev_char) {
|
||||
// char.style.letterSpacing = prev_char.style.letterSpacing = "0.03em";
|
||||
// }
|
||||
// }
|
||||
// 2) Au moins une italique par mot : si aucune, on en force une, de
|
||||
// préférence sur un pic gras ou un medium, sinon sur une lettre au hasard.
|
||||
if (!decisions.some((d) => d.ital)) {
|
||||
const accents = [...bold, ...medium];
|
||||
const idx = accents.length ? accents[randomInt(0, accents.length)] : randomInt(0, n);
|
||||
decisions[idx].ital = true;
|
||||
}
|
||||
|
||||
// 3) Pas plus de 2 italiques consécutives : on casse les séries de 3+.
|
||||
let run = 0;
|
||||
for (const d of decisions) {
|
||||
if (d.ital) {
|
||||
run += 1;
|
||||
if (run > 2) {
|
||||
d.ital = false;
|
||||
run = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
run = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 4) Applique.
|
||||
for (const { char, wght, ital } of decisions) {
|
||||
char.style.fontVariationSettings = `'wght' ${wght}`;
|
||||
char.style.fontStyle = ital ? 'italic' : 'normal';
|
||||
char.classList.toggle('italic', ital);
|
||||
char.classList.toggle('normal', !ital);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user