Start texture-space book renderer
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Book Texture Renderer Module
|
||||
* Draws the virtual book pages directly into texture-space canvases.
|
||||
*/
|
||||
import { BaseModule } from './base-module.js';
|
||||
|
||||
class BookTextureRendererModule extends BaseModule {
|
||||
constructor() {
|
||||
super('book-texture-renderer', 'Book Texture Renderer');
|
||||
this.dependencies = ['book-page-format', 'localization'];
|
||||
this.pageFormat = null;
|
||||
this.localization = null;
|
||||
this.metrics = null;
|
||||
this.canvases = {
|
||||
left: null,
|
||||
right: null
|
||||
};
|
||||
this.contexts = {
|
||||
left: null,
|
||||
right: null
|
||||
};
|
||||
this.hitMaps = {
|
||||
left: [],
|
||||
right: []
|
||||
};
|
||||
|
||||
this.bindMethods([
|
||||
'initialize',
|
||||
'createPageCanvases',
|
||||
'drawEmptySpread',
|
||||
'drawPageBase',
|
||||
'drawDebugText',
|
||||
'publishSpread',
|
||||
'getPageCanvas',
|
||||
'getHitMap',
|
||||
'handleSceneReady'
|
||||
]);
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
this.pageFormat = this.getModule('book-page-format');
|
||||
this.localization = this.getModule('localization');
|
||||
this.reportProgress(20, 'Preparing page texture canvases');
|
||||
this.createPageCanvases();
|
||||
this.drawEmptySpread();
|
||||
this.addEventListener(document, 'webgl-book:scene-ready', this.handleSceneReady);
|
||||
this.reportProgress(100, 'Book texture renderer ready');
|
||||
return true;
|
||||
}
|
||||
|
||||
createPageCanvases(textureWidth = 1280) {
|
||||
this.metrics = this.pageFormat.getTextureMetrics(textureWidth);
|
||||
['left', 'right'].forEach((side) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = this.metrics.width;
|
||||
canvas.height = this.metrics.height;
|
||||
this.canvases[side] = canvas;
|
||||
this.contexts[side] = canvas.getContext('2d');
|
||||
});
|
||||
}
|
||||
|
||||
drawEmptySpread() {
|
||||
this.drawPageBase('left');
|
||||
this.drawPageBase('right');
|
||||
this.drawDebugText('right', 'Book canvas renderer ready');
|
||||
this.publishSpread();
|
||||
}
|
||||
|
||||
drawPageBase(side) {
|
||||
const canvas = this.canvases[side];
|
||||
const ctx = this.contexts[side];
|
||||
if (!canvas || !ctx) return;
|
||||
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = '#fff7dc';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const shade = ctx.createLinearGradient(0, 0, canvas.width, 0);
|
||||
if (side === 'left') {
|
||||
shade.addColorStop(0, 'rgba(255, 255, 255, 0.10)');
|
||||
shade.addColorStop(0.78, 'rgba(255, 255, 255, 0)');
|
||||
shade.addColorStop(1, 'rgba(82, 42, 14, 0.16)');
|
||||
} else {
|
||||
shade.addColorStop(0, 'rgba(82, 42, 14, 0.16)');
|
||||
shade.addColorStop(0.22, 'rgba(255, 255, 255, 0)');
|
||||
shade.addColorStop(1, 'rgba(255, 255, 255, 0.10)');
|
||||
}
|
||||
ctx.fillStyle = shade;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
this.hitMaps[side] = [];
|
||||
}
|
||||
|
||||
drawDebugText(side, text) {
|
||||
const ctx = this.contexts[side];
|
||||
const metrics = this.metrics;
|
||||
if (!ctx || !metrics) return;
|
||||
|
||||
ctx.save();
|
||||
ctx.fillStyle = 'rgba(31, 19, 10, 0.82)';
|
||||
ctx.font = `${Math.round(metrics.typography.bodyFontSizePt * 1.55)}px ${metrics.typography.fontFamily}`;
|
||||
ctx.textBaseline = 'alphabetic';
|
||||
ctx.fillText(String(text || ''), metrics.content.x, metrics.content.y + 44);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
publishSpread() {
|
||||
document.dispatchEvent(new CustomEvent('webgl-book:page-canvases', {
|
||||
detail: {
|
||||
left: this.canvases.left,
|
||||
right: this.canvases.right,
|
||||
metrics: this.metrics,
|
||||
hitMaps: this.hitMaps
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
getPageCanvas(side) {
|
||||
return this.canvases[side] || null;
|
||||
}
|
||||
|
||||
getHitMap(side) {
|
||||
return this.hitMaps[side] || [];
|
||||
}
|
||||
|
||||
handleSceneReady() {
|
||||
this.publishSpread();
|
||||
}
|
||||
}
|
||||
|
||||
const bookTextureRenderer = new BookTextureRendererModule();
|
||||
|
||||
export { bookTextureRenderer as BookTextureRenderer };
|
||||
|
||||
if (window.moduleRegistry) {
|
||||
window.moduleRegistry.register(bookTextureRenderer);
|
||||
}
|
||||
|
||||
window.BookTextureRenderer = bookTextureRenderer;
|
||||
Reference in New Issue
Block a user