Refactor demo and template files: removed horizontal logo demo, added responsive sizing and spacing functions for text elements, and improved logo placement logic for vertical layouts.
This commit is contained in:
parent
2d48050378
commit
957dfef98d
2 changed files with 137 additions and 41 deletions
13
demo.typ
13
demo.typ
|
|
@ -41,19 +41,6 @@
|
|||
about: [This is a simple event with just one logo.]
|
||||
)
|
||||
|
||||
// Demo 4: Vier Logos in horizontalem Layout (Gitter)
|
||||
#sharepic(
|
||||
logos: (
|
||||
(path: "tux.svg", height: 3cm),
|
||||
(path: "connection.png", height: 3cm, rotation: -10deg),
|
||||
(path: "kew.jpg", height: 3cm, rotation: 10deg),
|
||||
(path: "tux.svg", height: 3cm, rotation: -5deg)
|
||||
),
|
||||
layout: "horizontal",
|
||||
title: [Four Logo Event],
|
||||
about: [This demonstrates how four logos are arranged in a grid pattern in horizontal layout.]
|
||||
)
|
||||
|
||||
// Demo 5: Vertikales layout mit benutzerdefinierter Positionierung
|
||||
#sharepic(
|
||||
logos: (
|
||||
|
|
|
|||
165
template.typ
165
template.typ
|
|
@ -7,10 +7,21 @@
|
|||
body-font: "DejaVu Sans",
|
||||
border-radius: 0.8cm,
|
||||
border-stroke: 4pt,
|
||||
// Fixed sizes (fallback if responsive is disabled)
|
||||
title-size: 20pt,
|
||||
label-size: 12pt,
|
||||
body-size: 12pt,
|
||||
info-text-size: 12pt,
|
||||
// Responsive sizing configuration
|
||||
title-size-max: 28pt,
|
||||
title-size-min: 14pt,
|
||||
title-base-length: 45, // Character count baseline
|
||||
body-size-max: 14pt,
|
||||
body-size-min: 9pt,
|
||||
body-base-length: 200, // Character count baseline
|
||||
info-size-max: 11pt,
|
||||
info-size-min: 9pt,
|
||||
info-base-length: 60, // Character count baseline
|
||||
)
|
||||
|
||||
// Default logo configuration
|
||||
|
|
@ -18,7 +29,7 @@
|
|||
path: none,
|
||||
height: 4cm,
|
||||
fit: "contain",
|
||||
rotation: 0deg,
|
||||
rotation: 10deg,
|
||||
offset: (x: 0cm, y: 0cm),
|
||||
pin-position: none, // "top-left", "top-center", "top-right", etc.
|
||||
)
|
||||
|
|
@ -68,51 +79,147 @@
|
|||
place-logo(logos.at(0), top + left, dx: 1.5cm, dy: 0.7cm)
|
||||
place-logo(logos.at(1), top + center, dy: 0.7cm)
|
||||
place-logo(logos.at(2), top + right, dx: -1.5cm, dy: 0.7cm)
|
||||
} else {
|
||||
// 4+ logos - anordnen in Gitter
|
||||
let cols = calc.min(2, logos.len())
|
||||
let rows = calc.ceil(logos.len() / cols)
|
||||
for (i, logo) in logos.enumerate() {
|
||||
let row = calc.floor(i / cols)
|
||||
let col = calc.rem(i, cols)
|
||||
let x = -2.5cm + col * 5cm
|
||||
let y = 0.5cm + row * 2.2cm
|
||||
place-logo(logo, top + left, dx: x, dy: y)
|
||||
}
|
||||
}
|
||||
} else if layout == "vertical" {
|
||||
// Logos auf der rechten Seite positioniert, vertikal gestapelt
|
||||
// Logos auf der rechten Seite positioniert, vertikal gestapelt und zentral angeordnet
|
||||
let card-height = 14cm
|
||||
let logo-height = 4cm // Standard logo height
|
||||
|
||||
if logos.len() == 1 {
|
||||
place-logo(logos.first(), top + right, dx: -1cm, dy: 0.7cm)
|
||||
// Single logo: centered vertically
|
||||
let dy = (card-height - logo-height) / 2
|
||||
place-logo(logos.first(), top + right, dx: -1cm, dy: dy)
|
||||
} else if logos.len() == 2 {
|
||||
place-logo(logos.at(0), top + right, dx: -1cm, dy: 0.7cm)
|
||||
place-logo(logos.at(1), top + right, dx: -1cm, dy: 4.2cm)
|
||||
// Two logos: vertically spaced around center
|
||||
let total-height = 2 * logo-height
|
||||
let start-dy = (card-height - total-height) / 2
|
||||
place-logo(logos.at(0), top + right, dx: -1cm, dy: start-dy)
|
||||
place-logo(logos.at(1), top + right, dx: -1cm, dy: start-dy + logo-height)
|
||||
} else {
|
||||
// 3+ logos: vertikal auf der rechten Seite mit leichtem Offset gestapelt
|
||||
// 3+ logos: evenly distributed vertically around center
|
||||
let total-height = logos.len() * logo-height
|
||||
let start-dy = (card-height - total-height) / 2
|
||||
for (i, logo) in logos.enumerate() {
|
||||
let dy = 0.7cm + i * 3.5cm
|
||||
let dy = start-dy + i * logo-height
|
||||
place-logo(logo, top + right, dx: -1cm, dy: dy)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktion um responsive Schriftgröße zu berechnen basierend auf Textlänge
|
||||
#let calculate-responsive-size(text-content, max-size: 28pt, min-size: 14pt, base-length: 50) = {
|
||||
// Zähle Zeichen in Text
|
||||
let text-length = if type(text-content) == str {
|
||||
text-content.len()
|
||||
} else if type(text-content) == content {
|
||||
// Für Content-Blöcke: Schätzung der Länge
|
||||
repr(text-content).len()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
// Berechne Reduktionsfaktor
|
||||
let ratio = if text-length > base-length {
|
||||
(base-length / text-length)
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
|
||||
// Skaliere die Größe, halte sie in Grenzen
|
||||
let range = max-size - min-size
|
||||
let scaled = min-size + range * ratio
|
||||
|
||||
// Stelle sicher, dass die Größe in Grenzen bleibt
|
||||
if scaled > max-size {
|
||||
max-size
|
||||
} else if scaled < min-size {
|
||||
min-size
|
||||
} else {
|
||||
scaled
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktion um responsive Abstände basierend auf Textmenge zu berechnen
|
||||
#let calculate-responsive-spacing(about-content, max-spacing: 1.2em, min-spacing: 0.6em, base-length: 200) = {
|
||||
let text-length = if type(about-content) == str {
|
||||
about-content.len()
|
||||
} else if type(about-content) == content {
|
||||
repr(about-content).len()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
// Reduziere Abstand wenn viel Text vorhanden
|
||||
let ratio = if text-length > base-length {
|
||||
(base-length / text-length)
|
||||
} else {
|
||||
1.0
|
||||
}
|
||||
|
||||
let range = max-spacing - min-spacing
|
||||
let scaled = min-spacing + range * ratio
|
||||
|
||||
if scaled > max-spacing {
|
||||
max-spacing
|
||||
} else if scaled < min-spacing {
|
||||
min-spacing
|
||||
} else {
|
||||
scaled
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktion um den Inhalt zu arrangieren
|
||||
#let arrange-content(title: [], when: [], where: [], about: [], layout: "horizontal", current-theme: theme) = {
|
||||
let left-padding = if layout == "vertical" { 1.5cm } else { 1.5cm }
|
||||
let right-padding = if layout == "vertical" { 5cm } else { 1.5cm }
|
||||
let top-padding = if layout == "vertical" { 0.8cm } else { 5.5cm }
|
||||
|
||||
// Berechne responsive Schriftgrößen
|
||||
let responsive-title-size = calculate-responsive-size(
|
||||
title,
|
||||
max-size: current-theme.title-size-max,
|
||||
min-size: current-theme.title-size-min,
|
||||
base-length: current-theme.title-base-length
|
||||
)
|
||||
|
||||
let responsive-body-size = calculate-responsive-size(
|
||||
about,
|
||||
max-size: current-theme.body-size-max,
|
||||
min-size: current-theme.body-size-min,
|
||||
base-length: current-theme.body-base-length
|
||||
)
|
||||
|
||||
let responsive-info-size = calculate-responsive-size(
|
||||
when + where,
|
||||
max-size: current-theme.info-size-max,
|
||||
min-size: current-theme.info-size-min,
|
||||
base-length: current-theme.info-base-length
|
||||
)
|
||||
|
||||
// Berechne responsive Abstände
|
||||
let responsive-spacing = calculate-responsive-spacing(
|
||||
about,
|
||||
max-spacing: 1.2em,
|
||||
min-spacing: 0.5em,
|
||||
base-length: current-theme.body-base-length
|
||||
)
|
||||
|
||||
// Berechne maximale Höhe für Beschreibungstext basierend auf verfügbarem Platz
|
||||
// Card: 14cm x 14cm, Padding: 1.5cm L+R, 1.5cm B, 5.5cm T (horizontal)
|
||||
// Ungefähre verfügbare Höhe: 14cm - 5.5cm - 1.5cm (Title/Info space) - 1.5cm (padding) = 5.5cm
|
||||
let max-about-height = 5.5cm
|
||||
|
||||
pad(top: top-padding, bottom: 1.5cm, left: left-padding, right: right-padding)[
|
||||
#stack(
|
||||
dir: ttb,
|
||||
spacing: 1em,
|
||||
// Title
|
||||
spacing: responsive-spacing,
|
||||
// Title mit responsiver Größe
|
||||
if title != [] {
|
||||
text(size: current-theme.title-size, weight: "bold", font: current-theme.heading-font, title)
|
||||
text(size: responsive-title-size, weight: "bold", font: current-theme.heading-font, title)
|
||||
},
|
||||
|
||||
// Info-Block für wann/wo
|
||||
// Info-Block für wann/wo mit responsiver Größe
|
||||
if when != [] or where != [] {
|
||||
block(
|
||||
inset: 0.8em,
|
||||
|
|
@ -127,7 +234,7 @@
|
|||
dir: ltr,
|
||||
spacing: 0.5em,
|
||||
align(center + horizon, emoji.calendar),
|
||||
text(size: current-theme.info-text-size, when),
|
||||
text(size: responsive-info-size, when),
|
||||
))
|
||||
},
|
||||
if where != [] {
|
||||
|
|
@ -135,19 +242,21 @@
|
|||
dir: ltr,
|
||||
spacing: 0.5em,
|
||||
align(center + horizon, emoji.pin),
|
||||
text(size: current-theme.info-text-size, where),
|
||||
text(size: responsive-info-size, where),
|
||||
))
|
||||
},
|
||||
),
|
||||
)
|
||||
},
|
||||
|
||||
// Beschreibungstext
|
||||
// Beschreibungstext mit responsiver Größe und maximaler Höhe
|
||||
if about != [] {
|
||||
let about-align = if layout == "vertical" { left } else { center }
|
||||
block(
|
||||
spacing: 0.1em,
|
||||
align(about-align, text(size: current-theme.body-size, about))
|
||||
box(
|
||||
height: max-about-height,
|
||||
width: 100%,
|
||||
clip: true,
|
||||
align(about-align, text(size: responsive-body-size, about))
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue