Files
ai.interactive.fiction/public/js/book-page-format-module.js
T

109 lines
3.3 KiB
JavaScript

/**
* Book Page Format Module
* Defines the canonical page geometry used by the WebGL book renderer.
*/
import { BaseModule } from './base-module.js';
class BookPageFormatModule extends BaseModule {
constructor() {
super('book-page-format', 'Book Page Format');
this.dependencies = [];
this.format = Object.freeze({
id: 'us-mass-market-paperback',
trim: Object.freeze({
widthIn: 4.25,
heightIn: 6.87
}),
margins: Object.freeze({
topIn: 0.46,
bottomIn: 0.58,
innerIn: 0.56,
outerIn: 0.44
}),
typography: Object.freeze({
fontFamily: '"EB Garamond", "EB Garamond 12", serif',
linesPerPage: 25,
bodyLineRatio: 1.5,
headingScale: 1,
dropCapLines: 2
})
});
this.bindMethods([
'getFormat',
'getAspectRatio',
'getTextureMetrics',
'inchesToTexture'
]);
}
async initialize() {
this.reportProgress(100, 'Book page format ready');
return true;
}
getFormat() {
return this.format;
}
getAspectRatio() {
return this.format.trim.widthIn / this.format.trim.heightIn;
}
inchesToTexture(valueIn, textureHeight) {
return (Number(valueIn) / this.format.trim.heightIn) * textureHeight;
}
getTextureMetrics(textureWidth = 1280) {
const width = Math.max(1, Math.round(Number(textureWidth) || 1280));
const height = Math.round(width / this.getAspectRatio());
const margins = {
top: this.inchesToTexture(this.format.margins.topIn, height),
bottom: this.inchesToTexture(this.format.margins.bottomIn, height),
inner: this.inchesToTexture(this.format.margins.innerIn, height),
outer: this.inchesToTexture(this.format.margins.outerIn, height)
};
const content = {
x: margins.outer,
y: margins.top,
width: Math.max(1, width - margins.outer - margins.inner),
height: Math.max(1, height - margins.top - margins.bottom)
};
const contentBySide = {
left: {
...content,
x: margins.outer
},
right: {
...content,
x: margins.inner
}
};
const linesPerPage = Math.max(1, Number(this.format.typography.linesPerPage || 25));
const typographyLineHeightPx = content.height / linesPerPage;
const bodyFontSizePx = typographyLineHeightPx / Math.max(1, Number(this.format.typography.bodyLineRatio || 1.5));
return {
width,
height,
aspectRatio: this.getAspectRatio(),
margins,
content,
contentBySide,
linesPerPage,
bodyFontSizePx,
typographyLineHeightPx,
typography: this.format.typography
};
}
}
const bookPageFormat = new BookPageFormatModule();
export { bookPageFormat as BookPageFormat };
if (window.moduleRegistry) {
window.moduleRegistry.register(bookPageFormat);
}
window.BookPageFormat = bookPageFormat;