mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-24 07:53:09 +00:00
75d0593198
- A text can be cased (capitals, lower case, small caps), placed at the top, middle or foot of its frame, outlined, given a hard shadow or a marker band, bent on an arc or round a circle, filled with a gallery photo or left hollow, and shrunk to fit its frame. Every effect prints as vector: copies and strokes for HTML type, textPath and a clip over an <image> for SVG. - Fitting is solved when the text is edited, in the Studio and in the edit engine, and stored; the chosen size is kept as the ceiling. - Text sizes reach 400 pt and tracking 1.5 em. - The Elements panel opens on a Text tab: the plain styles and 24 lockups (titles, badges and stamps, chapter marks, quotes, captions, places), each drawn with the book's own title and placed as one group. - The assistant sets every effect through style and add, places a lockup with add_lockup, reads the effects in describe_book_page and gets two new findings (curve_overflow, effect_heavy) beside photo-fill and band checks. - Book format revision 6.
590 lines
15 KiB
TypeScript
590 lines
15 KiB
TypeScript
import type {
|
|
BookLockup,
|
|
BookLockupRole,
|
|
BookLockupShapePart,
|
|
BookLockupTextPart,
|
|
BookLockupTone,
|
|
} from './book-lockups';
|
|
|
|
/**
|
|
* The 24 lockups, in the units of a box 100 wide (book-lockups.ts).
|
|
*
|
|
* Type sizes are chosen against the share of the page a lockup takes, so the
|
|
* printed sizes land where the type scale wants them on a 210 mm page: a cover
|
|
* title between 70 and 180 pt, spaced capitals at 8 to 11 pt with a quarter to
|
|
* half an em of tracking, a title at least three times its subtitle. Every
|
|
* frame is a little taller than its line, and the parts never touch unless
|
|
* they are meant to layer, so a lockup placed as it comes has no severe finding.
|
|
*
|
|
* The faces are the book's own (book-fonts.data.ts): condensed and heavy
|
|
* poster faces for titles, Montserrat for spaced capitals, a thin serif and its
|
|
* italic for quiet titles and quotes, a script for the word laid over a title,
|
|
* DM Mono for coordinates.
|
|
*/
|
|
|
|
/** A line of spaced capitals: a date line, a kicker, a year. */
|
|
function spaced(
|
|
role: BookLockupRole,
|
|
y: number,
|
|
size: number,
|
|
tone: BookLockupTone = 'muted',
|
|
more: Partial<BookLockupTextPart> = {},
|
|
): BookLockupTextPart {
|
|
return {
|
|
kind: 'text',
|
|
role,
|
|
x: 0,
|
|
y,
|
|
w: 100,
|
|
h: size * 2,
|
|
font: 'montserrat',
|
|
size,
|
|
weight: 600,
|
|
tracking: 0.4,
|
|
transform: 'upper',
|
|
tone,
|
|
...more,
|
|
};
|
|
}
|
|
|
|
/** A filled bar: a rule when it is thin, a band when it is not. */
|
|
function bar(x: number, y: number, w: number, h: number, fill: BookLockupTone = 'ink'): BookLockupShapePart {
|
|
return { kind: 'shape', shape: 'rect', x, y, w, h, fill };
|
|
}
|
|
|
|
/** A circle drawn as a line only. */
|
|
function ring(inset: number, stroke: BookLockupTone, strokeWidth: number, size = 100): BookLockupShapePart {
|
|
const side = size - inset * 2;
|
|
return { kind: 'shape', shape: 'ellipse', x: inset, y: inset, w: side, h: side, fill: null, stroke, strokeWidth };
|
|
}
|
|
|
|
/** A condensed poster face, Bebas unless the part says another: capitals, tight lines. */
|
|
function poster(
|
|
role: BookLockupRole,
|
|
y: number,
|
|
size: number,
|
|
more: Partial<BookLockupTextPart> = {},
|
|
): BookLockupTextPart {
|
|
return {
|
|
kind: 'text',
|
|
role,
|
|
x: 0,
|
|
y,
|
|
w: 100,
|
|
h: size * 1.05,
|
|
font: 'bebas',
|
|
size,
|
|
leading: 0.9,
|
|
tracking: 0.02,
|
|
transform: 'upper',
|
|
tone: 'ink',
|
|
...more,
|
|
};
|
|
}
|
|
|
|
export const BOOK_LOCKUPS: readonly BookLockup[] = [
|
|
{
|
|
id: 'poster-stack',
|
|
descr: 'Heavy poster title with a hard accent shadow, a subtitle on an accent band, the year under it',
|
|
height: 62,
|
|
share: 0.8,
|
|
parts: [
|
|
poster('title', 0, 34, { font: 'anton', shadow: { dx: 0.9, dy: 0.9, tone: 'accent' } }),
|
|
poster('subtitle', 38, 7.5, {
|
|
h: 11,
|
|
tracking: 0.3,
|
|
tone: 'paper',
|
|
highlight: { tone: 'accent', padX: 2.4, padY: 0.5 },
|
|
}),
|
|
spaced('year', 54, 2.4, 'ink', { h: 6 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'spaced-date',
|
|
descr: 'A spaced date line over a condensed title, a short accent rule and the place',
|
|
height: 50,
|
|
share: 0.75,
|
|
parts: [
|
|
spaced('dates', 0, 2.4, 'muted', { h: 6 }),
|
|
poster('title', 7, 30, { font: 'league', tracking: 0.04 }),
|
|
bar(42, 40.5, 16, 0.5, 'accent'),
|
|
spaced('place', 43.5, 2.4, 'ink', { h: 6, tracking: 0.3 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'serif-sun',
|
|
descr: 'A large thin serif title, an italic subtitle, a sun between two hairlines and the year',
|
|
height: 64,
|
|
share: 0.8,
|
|
parts: [
|
|
{
|
|
kind: 'text',
|
|
role: 'title',
|
|
x: 0,
|
|
y: 0,
|
|
w: 100,
|
|
h: 28,
|
|
font: 'cormorant',
|
|
size: 26,
|
|
weight: 300,
|
|
leading: 1,
|
|
tracking: -0.01,
|
|
tone: 'ink',
|
|
},
|
|
{
|
|
kind: 'text',
|
|
role: 'subtitle',
|
|
x: 0,
|
|
y: 29,
|
|
w: 100,
|
|
h: 10,
|
|
font: 'cormorant',
|
|
size: 7.5,
|
|
italic: true,
|
|
tone: 'ink',
|
|
},
|
|
bar(18, 46.8, 26, 0.3),
|
|
{ kind: 'shape', shape: 'sun', x: 46, y: 43, w: 8, h: 8, fill: 'accent' },
|
|
bar(56, 46.8, 26, 0.3),
|
|
spaced('year', 55, 2.2, 'muted', { h: 6, tracking: 0.5 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'title-script-year',
|
|
descr: 'A bold serif title, an accent script subtitle turned across its foot, the year in spaced capitals',
|
|
height: 50,
|
|
share: 0.75,
|
|
parts: [
|
|
{
|
|
kind: 'text',
|
|
role: 'title',
|
|
x: 0,
|
|
y: 0,
|
|
w: 100,
|
|
h: 25,
|
|
font: 'playfair',
|
|
size: 22,
|
|
weight: 700,
|
|
leading: 0.95,
|
|
tone: 'ink',
|
|
},
|
|
{
|
|
kind: 'text',
|
|
role: 'subtitle',
|
|
x: 12,
|
|
y: 24,
|
|
w: 76,
|
|
h: 13,
|
|
rotation: -4,
|
|
font: 'vibes',
|
|
size: 12,
|
|
italic: false,
|
|
tone: 'accent',
|
|
},
|
|
spaced('year', 42, 2.4, 'muted', { h: 6, tracking: 0.45 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'circle-badge',
|
|
descr: 'A round accent badge: a kicker run round its rim inside a paper ring, the title and the year in the middle',
|
|
height: 100,
|
|
share: 0.45,
|
|
parts: [
|
|
{ kind: 'shape', shape: 'ellipse', x: 0, y: 0, w: 100, h: 100, fill: 'accent' },
|
|
ring(5, 'paper', 0.7),
|
|
spaced('kicker', 0, 6, 'paper', {
|
|
x: 7,
|
|
y: 7,
|
|
w: 86,
|
|
h: 86,
|
|
tracking: 0.25,
|
|
curve: { type: 'circle', bend: 0, start: 0 },
|
|
}),
|
|
poster('title', 36, 22, { x: 16, w: 68, h: 24, tone: 'paper', tracking: 0.04 }),
|
|
spaced('year', 62, 4.4, 'paper', { x: 25, w: 50, h: 8, tracking: 0.3 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'postmark',
|
|
descr: 'A round postmark: the place round its rim between two rings, the date in the middle over a cancel wave',
|
|
height: 100,
|
|
share: 0.42,
|
|
parts: [
|
|
ring(0.5, 'ink', 1),
|
|
ring(14, 'ink', 0.5),
|
|
poster('place', 0, 12, {
|
|
x: 1,
|
|
y: 1,
|
|
w: 98,
|
|
h: 98,
|
|
tracking: 0.16,
|
|
curve: { type: 'circle', bend: 0, start: 0 },
|
|
}),
|
|
poster('dates', 38, 10, { x: 20, w: 60, h: 11, tracking: 0.08 }),
|
|
{ kind: 'shape', shape: 'wave', x: 22, y: 53, w: 56, h: 8, fill: 'ink' },
|
|
spaced('year', 63, 4.4, 'ink', { x: 25, w: 50, h: 8, tracking: 0.3 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'script-overlay',
|
|
descr: 'A spaced poster title with a large accent script word turned over it, outlined in paper',
|
|
height: 58,
|
|
share: 0.8,
|
|
parts: [
|
|
poster('title', 22, 32, { tracking: 0.1 }),
|
|
{
|
|
kind: 'text',
|
|
role: 'overlay',
|
|
x: 8,
|
|
y: 0,
|
|
w: 84,
|
|
h: 30,
|
|
rotation: -6,
|
|
font: 'yellowtail',
|
|
size: 24,
|
|
weight: 400,
|
|
italic: false,
|
|
tone: 'accent',
|
|
outline: { tone: 'paper', width: 0.6 },
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'photo-word',
|
|
descr: 'A huge poster word filled with a photo, a spaced kicker over it',
|
|
height: 50,
|
|
share: 0.85,
|
|
parts: [
|
|
spaced('kicker', 0, 2.4, 'ink', { h: 6, tracking: 0.45 }),
|
|
poster('title', 7, 40, { h: 42, font: 'anton', fill: 'photo' }),
|
|
],
|
|
},
|
|
{
|
|
id: 'fabric-band',
|
|
descr: 'A poster title in paper on a full accent band, a script subtitle under it',
|
|
height: 44,
|
|
share: 0.8,
|
|
parts: [
|
|
bar(0, 0, 100, 26, 'accent'),
|
|
poster('title', 4, 18, { h: 18, tracking: 0.14, tone: 'paper' }),
|
|
{
|
|
kind: 'text',
|
|
role: 'subtitle',
|
|
x: 0,
|
|
y: 29,
|
|
w: 100,
|
|
h: 13,
|
|
font: 'satisfy',
|
|
size: 7,
|
|
italic: false,
|
|
tone: 'ink',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'quote-classic',
|
|
descr:
|
|
'A large accent quotation mark, the quote in a serif italic, an accent rule and the source in spaced capitals',
|
|
height: 56,
|
|
share: 0.6,
|
|
parts: [
|
|
{
|
|
kind: 'text',
|
|
role: 'quote',
|
|
literal: '“',
|
|
x: 0,
|
|
y: 0,
|
|
w: 22,
|
|
h: 22,
|
|
font: 'playfair',
|
|
size: 26,
|
|
weight: 700,
|
|
leading: 0.8,
|
|
align: 'left',
|
|
tone: 'accent',
|
|
},
|
|
{
|
|
kind: 'text',
|
|
role: 'quote',
|
|
x: 0,
|
|
y: 23,
|
|
w: 100,
|
|
h: 24,
|
|
font: 'cormorant',
|
|
size: 6.5,
|
|
italic: true,
|
|
leading: 1.3,
|
|
align: 'left',
|
|
tone: 'ink',
|
|
},
|
|
bar(0, 50.8, 9, 0.4, 'accent'),
|
|
spaced('caption', 48, 2.8, 'muted', { x: 12, w: 88, h: 6, align: 'left', tracking: 0.3 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'quote-band',
|
|
descr: 'A quote set in paper on ink bands behind each line, the source under it',
|
|
height: 42,
|
|
share: 0.7,
|
|
parts: [
|
|
{
|
|
kind: 'text',
|
|
role: 'quote',
|
|
x: 0,
|
|
y: 0,
|
|
w: 100,
|
|
h: 32,
|
|
font: 'sans',
|
|
size: 5,
|
|
weight: 600,
|
|
leading: 1.6,
|
|
align: 'left',
|
|
tone: 'paper',
|
|
highlight: { tone: 'ink', padX: 1.4, padY: 0.4 },
|
|
},
|
|
spaced('caption', 35, 2.6, 'muted', { h: 6, align: 'left', tracking: 0.3 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'caption-rule',
|
|
descr: 'A caption in spaced capitals after a short rule',
|
|
height: 8,
|
|
share: 0.5,
|
|
parts: [
|
|
bar(0, 3.85, 8, 0.3),
|
|
spaced('caption', 0, 3.1, 'ink', { x: 11, w: 89, h: 8, align: 'left', tracking: 0.3 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'caption-number',
|
|
descr: 'An accent figure beside a caption in a serif italic',
|
|
height: 16,
|
|
share: 0.5,
|
|
parts: [
|
|
poster('number', 0, 14, { w: 16, h: 16, align: 'left', tone: 'accent' }),
|
|
{
|
|
kind: 'text',
|
|
role: 'caption',
|
|
x: 18,
|
|
y: 1,
|
|
w: 82,
|
|
h: 14,
|
|
font: 'cormorant',
|
|
size: 4.8,
|
|
italic: true,
|
|
leading: 1.3,
|
|
align: 'left',
|
|
tone: 'ink',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'ticket',
|
|
descr: 'A ticket outline holding a kicker, the place in poster capitals and the dates',
|
|
height: 40,
|
|
share: 0.55,
|
|
parts: [
|
|
{ kind: 'shape', shape: 'ticket', x: 0, y: 0, w: 100, h: 40, fill: null, stroke: 'ink', strokeWidth: 0.5 },
|
|
spaced('kicker', 7, 2.8, 'muted', { x: 12, w: 76, h: 5 }),
|
|
poster('place', 12, 15, { x: 12, w: 76, h: 16, tracking: 0.08 }),
|
|
spaced('dates', 28.5, 2.8, 'ink', { x: 12, w: 76, h: 5, font: 'mono', weight: 500, tracking: 0.12 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'coords-pin',
|
|
descr: 'Coordinates in spaced figures after an accent map pin',
|
|
height: 10,
|
|
share: 0.5,
|
|
parts: [
|
|
{ kind: 'shape', shape: 'pin', x: 0, y: 1, w: 6, h: 8, fill: 'accent' },
|
|
spaced('coords', 0, 3.2, 'ink', {
|
|
x: 9,
|
|
w: 91,
|
|
h: 10,
|
|
align: 'left',
|
|
font: 'mono',
|
|
weight: 400,
|
|
tracking: 0.12,
|
|
transform: 'none',
|
|
}),
|
|
],
|
|
},
|
|
{
|
|
id: 'coords-stack',
|
|
descr: 'The place in poster capitals, an accent rule and the coordinates under it',
|
|
height: 30,
|
|
share: 0.5,
|
|
parts: [
|
|
poster('place', 0, 15, { h: 16, tracking: 0.1 }),
|
|
bar(42, 17.5, 16, 0.4, 'accent'),
|
|
spaced('coords', 21, 3, 'muted', { h: 7, font: 'mono', weight: 400, tracking: 0.08, transform: 'none' }),
|
|
],
|
|
},
|
|
{
|
|
id: 'chapter-outline',
|
|
descr: 'A huge hollow outlined figure, a spaced accent label under it and the title in a serif italic',
|
|
height: 62,
|
|
share: 0.45,
|
|
parts: [
|
|
poster('number', 0, 42, { h: 42, fill: { tone: 'ink', alpha: 0 }, outline: { tone: 'accent', width: 0.5 } }),
|
|
spaced('label', 43, 3.6, 'accent', { h: 7, tracking: 0.5 }),
|
|
{
|
|
kind: 'text',
|
|
role: 'title',
|
|
x: 0,
|
|
y: 51,
|
|
w: 100,
|
|
h: 11,
|
|
font: 'cormorant',
|
|
size: 8,
|
|
italic: true,
|
|
tone: 'ink',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'chapter-rules',
|
|
descr: 'A serif figure between two hairlines, the title in spaced capitals under it',
|
|
height: 34,
|
|
share: 0.5,
|
|
parts: [
|
|
bar(0, 12.8, 32, 0.35),
|
|
{ kind: 'text', role: 'number', x: 34, y: 2, w: 32, h: 22, font: 'bodoni', size: 17, leading: 1, tone: 'ink' },
|
|
bar(68, 12.8, 32, 0.35),
|
|
spaced('title', 26, 3.4, 'ink', { h: 7 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'day-opener',
|
|
descr: 'A spaced label, a huge accent serif figure and the place in poster capitals, set flush left',
|
|
height: 58,
|
|
share: 0.5,
|
|
parts: [
|
|
spaced('label', 0, 3.4, 'muted', { h: 7, align: 'left', tracking: 0.5 }),
|
|
{
|
|
kind: 'text',
|
|
role: 'number',
|
|
x: 0,
|
|
y: 7,
|
|
w: 100,
|
|
h: 37,
|
|
font: 'fraunces',
|
|
size: 40,
|
|
weight: 800,
|
|
leading: 0.85,
|
|
align: 'left',
|
|
tone: 'accent',
|
|
},
|
|
poster('place', 46, 10, { h: 11, align: 'left', tracking: 0.14 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'stamp',
|
|
descr: 'A rubber stamp set at an angle: a double accent frame round the place and the dates',
|
|
height: 44,
|
|
share: 0.45,
|
|
rotation: -7,
|
|
parts: [
|
|
{
|
|
kind: 'shape',
|
|
shape: 'rect',
|
|
x: 0,
|
|
y: 0,
|
|
w: 100,
|
|
h: 44,
|
|
fill: null,
|
|
stroke: 'accent',
|
|
strokeWidth: 1,
|
|
radius: 2,
|
|
},
|
|
{
|
|
kind: 'shape',
|
|
shape: 'rect',
|
|
x: 3.5,
|
|
y: 3.5,
|
|
w: 93,
|
|
h: 37,
|
|
fill: null,
|
|
stroke: 'accent',
|
|
strokeWidth: 0.35,
|
|
radius: 1,
|
|
},
|
|
poster('place', 8, 17, { x: 7, w: 86, h: 18, tracking: 0.12, tone: 'accent' }),
|
|
spaced('dates', 28, 3.4, 'accent', { x: 7, w: 86, h: 7, tracking: 0.35 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'arched-title',
|
|
descr: 'A poster title arched over a script subtitle, a sparkle at each side',
|
|
height: 58,
|
|
share: 0.75,
|
|
parts: [
|
|
poster('title', 0, 20, { h: 42, tracking: 0.08, curve: { type: 'arc', bend: 42, start: 0 } }),
|
|
{ kind: 'shape', shape: 'sparkle', x: 6, y: 43, w: 7, h: 7, fill: 'accent' },
|
|
{
|
|
kind: 'text',
|
|
role: 'subtitle',
|
|
x: 16,
|
|
y: 41,
|
|
w: 68,
|
|
h: 12,
|
|
font: 'dancing',
|
|
size: 7,
|
|
italic: false,
|
|
weight: 500,
|
|
tone: 'ink',
|
|
},
|
|
{ kind: 'shape', shape: 'sparkle', x: 87, y: 43, w: 7, h: 7, fill: 'accent' },
|
|
],
|
|
},
|
|
{
|
|
id: 'retro-shadow',
|
|
descr: 'A heavy retro title in the accent, outlined in ink with a hard ink shadow, a subtitle and the year',
|
|
height: 48,
|
|
share: 0.75,
|
|
parts: [
|
|
{
|
|
kind: 'text',
|
|
role: 'title',
|
|
x: 0,
|
|
y: 0,
|
|
w: 100,
|
|
h: 28,
|
|
font: 'shrikhand',
|
|
size: 21,
|
|
weight: 400,
|
|
leading: 0.95,
|
|
tracking: -0.01,
|
|
tone: 'accent',
|
|
outline: { tone: 'ink', width: 0.5 },
|
|
shadow: { dx: 1.3, dy: 1.3, tone: 'ink' },
|
|
},
|
|
spaced('subtitle', 32, 2.8, 'ink', { h: 7, tracking: 0.35 }),
|
|
spaced('year', 40, 2.4, 'muted', { h: 7, tracking: 0.35 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'outline-echo',
|
|
descr: 'The title three times in poster capitals: two hollow outlines over the solid word, the year under it',
|
|
height: 66,
|
|
share: 0.7,
|
|
parts: [
|
|
poster('title', 0, 17, { h: 18, fill: { tone: 'ink', alpha: 0 }, outline: { tone: 'ink', width: 0.3 } }),
|
|
poster('title', 19, 17, { h: 18, fill: { tone: 'ink', alpha: 0 }, outline: { tone: 'ink', width: 0.3 } }),
|
|
poster('title', 38, 17, { h: 18 }),
|
|
spaced('year', 59, 2.6, 'muted', { h: 6, tracking: 0.45 }),
|
|
],
|
|
},
|
|
{
|
|
id: 'minimal-caps',
|
|
descr: 'A title in widely spaced light capitals, a hairline and the year: quiet and elegant',
|
|
height: 30,
|
|
share: 0.7,
|
|
parts: [
|
|
spaced('title', 0, 8, 'ink', { h: 13, weight: 300, tracking: 0.55 }),
|
|
bar(44, 16.5, 12, 0.3),
|
|
spaced('year', 21, 2.6, 'muted', { h: 7, weight: 400, tracking: 0.5 }),
|
|
],
|
|
},
|
|
];
|