forked from lovis/socials-template
		
	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
				
			
		
							
								
								
									
										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
	
	 AljGe
						AljGe