plus d'espace pour les export typo variable, ui css
This commit is contained in:
@@ -128,7 +128,12 @@ Comportement Drupal (`Drupal.behaviors.leshedSvgExport`) :
|
|||||||
avant de demander le tracé du bon caractère.
|
avant de demander le tracé du bon caractère.
|
||||||
- Assemble le SVG (fond transparent, remplissage noir uniquement — décision
|
- Assemble le SVG (fond transparent, remplissage noir uniquement — décision
|
||||||
volontaire, pas configurable) et déclenche le téléchargement (`Blob` +
|
volontaire, pas configurable) et déclenche le téléchargement (`Blob` +
|
||||||
`<a download>`).
|
`<a download>`). Une marge égale à 30 % de la plus grande taille de police
|
||||||
|
du titre (`ITALIC_OVERFLOW_MARGIN_RATIO`) est ajoutée tout autour du
|
||||||
|
canevas : les lettres italiques débordent de leur boîte d'avance nominale
|
||||||
|
(surtout en haut des hampes), et `getBoundingClientRect()` du titre ne
|
||||||
|
tient pas compte de ce débordement — sans cette marge, un cadrage au plus
|
||||||
|
juste coupe parfois ces lettres.
|
||||||
- Pour le PNG : rasterise le SVG assemblé via un `<canvas>` à ×4 la taille
|
- Pour le PNG : rasterise le SVG assemblé via un `<canvas>` à ×4 la taille
|
||||||
affichée (`PNG_SCALE`), puis `canvas.toBlob('image/png')`.
|
affichée (`PNG_SCALE`), puis `canvas.toBlob('image/png')`.
|
||||||
|
|
||||||
|
|||||||
@@ -72,12 +72,21 @@
|
|||||||
* positioned glyph path. Nothing here recomputes layout — it only reads
|
* positioned glyph path. Nothing here recomputes layout — it only reads
|
||||||
* what the browser already laid out at the moment of the click.
|
* what the browser already laid out at the moment of the click.
|
||||||
*/
|
*/
|
||||||
|
// Fraction of the largest font size on the title, added as padding around
|
||||||
|
// the whole canvas. Italic glyphs slant past their own nominal advance
|
||||||
|
// box (most visibly at the top of ascenders), and the title's own
|
||||||
|
// getBoundingClientRect() doesn't account for that overflow — a tightly
|
||||||
|
// fitted viewBox clips them. This margin is a generous, font-agnostic
|
||||||
|
// safety net rather than measuring each glyph's exact ink bounds.
|
||||||
|
const ITALIC_OVERFLOW_MARGIN_RATIO = 0.3;
|
||||||
|
|
||||||
async function buildSvg(titleEl, glyphFor, hb) {
|
async function buildSvg(titleEl, glyphFor, hb) {
|
||||||
const containerRect = titleEl.getBoundingClientRect();
|
const containerRect = titleEl.getBoundingClientRect();
|
||||||
const chars = Array.from(titleEl.querySelectorAll('.char'));
|
const chars = Array.from(titleEl.querySelectorAll('.char'));
|
||||||
|
|
||||||
const seenWords = new Set();
|
const seenWords = new Set();
|
||||||
const glyphNodes = [];
|
const glyphNodes = [];
|
||||||
|
let maxFontSizePx = 0;
|
||||||
for (const charEl of chars) {
|
for (const charEl of chars) {
|
||||||
const rawText = charEl.textContent;
|
const rawText = charEl.textContent;
|
||||||
if (!rawText || !rawText.trim()) continue;
|
if (!rawText || !rawText.trim()) continue;
|
||||||
@@ -86,6 +95,7 @@
|
|||||||
const computed = getComputedStyle(charEl);
|
const computed = getComputedStyle(charEl);
|
||||||
const fontSizePx = parseFloat(computed.fontSize);
|
const fontSizePx = parseFloat(computed.fontSize);
|
||||||
if (!fontSizePx) continue;
|
if (!fontSizePx) continue;
|
||||||
|
maxFontSizePx = Math.max(maxFontSizePx, fontSizePx);
|
||||||
|
|
||||||
const text = applyTextTransform(rawText, computed.textTransform, charEl, seenWords);
|
const text = applyTextTransform(rawText, computed.textTransform, charEl, seenWords);
|
||||||
|
|
||||||
@@ -101,11 +111,12 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const width = containerRect.width;
|
const margin = maxFontSizePx * ITALIC_OVERFLOW_MARGIN_RATIO;
|
||||||
const height = containerRect.height;
|
const width = containerRect.width + margin * 2;
|
||||||
|
const height = containerRect.height + margin * 2;
|
||||||
const svg = [
|
const svg = [
|
||||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width.toFixed(2)} ${height.toFixed(2)}" width="${width.toFixed(2)}" height="${height.toFixed(2)}">`,
|
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width.toFixed(2)} ${height.toFixed(2)}" width="${width.toFixed(2)}" height="${height.toFixed(2)}">`,
|
||||||
'<g fill="#000000">',
|
`<g fill="#000000" transform="translate(${margin.toFixed(2)}, ${margin.toFixed(2)})">`,
|
||||||
...glyphNodes,
|
...glyphNodes,
|
||||||
'</g>',
|
'</g>',
|
||||||
'</svg>',
|
'</svg>',
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -342,16 +342,19 @@ article.node-type-projet.view-mode-full{
|
|||||||
font-size: 1.8em;
|
font-size: 1.8em;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
.field_invite_accompagne_curate_p{
|
.field_invite_accompagne_curate_p,
|
||||||
|
.field_partenaire_s{
|
||||||
|
margin-top: 1em;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
.field-label{
|
.field-label{
|
||||||
font-weight: $default_fwght;
|
font-weight: $default_fwght;
|
||||||
}
|
}
|
||||||
>div{
|
// >div{
|
||||||
display: inline-block;
|
// display: inline-block;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
.field_dates{
|
.field_dates{
|
||||||
|
margin-top: 1em;
|
||||||
time{
|
time{
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user