UNPKG

comic-bubbles

Version:

Animated comic bubbles - what else?

132 lines (108 loc) 4.01 kB
import { getResourceUrl } from './helperFunctions.mjs' export let fontDescs = new Map() export let fontImages = new Map() async function loadImage(url) { const response = await fetch(url) const blob = await response.blob() const objectUrl = URL.createObjectURL(blob) return new Promise((resolve, reject) => { const image = new Image() image.addEventListener('load', () => resolve(image)) image.addEventListener('error', reject) image.src = objectUrl }) } export async function cacheFontDesc(fontName) { try { for (let bold = 0; bold <= 1; bold++) { for (let italic = 0; italic <= 1; italic++) { let fullFontName = getFullFontName(fontName, bold, italic) if (fontDescs.has(fullFontName)) continue const jsonPath = getResourceUrl('font JSON path', `/resources/fonts/${fontName}/${fullFontName}.json`) const response = await fetch(jsonPath) const data = await response.json() fontDescs.set(fullFontName, data.font) await cacheFontImage(fontName, data.font.image) } } } catch (error) { console.error(error) } } export async function cacheFontImage(fontName, imageName) { try { if (fontImages.has(imageName)) return const fontPath = getResourceUrl('font image path', `/resources/fonts/${fontName}/${imageName}`) let fontImage = await loadImage(fontPath) fontImages.set(imageName, fontImage) } catch (error) { console.error(error) } } export function drawChar(sceneId, charName, fontName, bold, italic, x, y) { const canvas = document.getElementById(sceneId) const ctx = canvas.getContext('2d') const char = getCharDesc(charName, fontName, bold, italic) ctx.globalCompositeOperation = 'multiply' let fontImageName = fontDescs.get(getFullFontName(fontName, bold, italic)).image let fontImage = fontImages.get(fontImageName) ctx.drawImage( fontImage, char.bounds.x, char.bounds.y, char.bounds.width, char.bounds.height, x + char.margin.left, y + char.margin.top, char.bounds.width, char.bounds.height ) ctx.globalCompositeOperation = 'source-over' } export function getFullFontName(fontName, bold, italic) { let boldTxt = bold ? '-bold' : '' let italicTxt = italic ? '-italic' : '' let regularTxt = !italic && !bold ? '-regular' : '' let fullFontName = fontName + boldTxt + regularTxt + italicTxt return fullFontName } export function getCharDesc(charName, fontName, bold, italic) { let char try { let fontDesc = fontDescs.get(getFullFontName(fontName, bold, italic)) char = fontDesc.chars.find((element) => element.char.name === charName).char } catch (exc) { console.log("Character missing in font map: '" + charName + "'") } return char } export function drawWord(sceneId, word, fontName, bold, italic, x, y) { for (let i = 0; i < word.length; i++) { const charName = word[i] drawChar(sceneId, charName, fontName, bold, italic, x, y) const charObj = getCharDesc(charName, fontName, bold, italic) let fontDesc = fontDescs.get(getFullFontName(fontName, bold, italic)) x += charObj.bounds.width + charObj.margin.left + charObj.margin.right if (i != word.length - 1) { x += fontDesc.letterSpacing } } } export function drawRow(sceneId, row) { let x = row.getX() let y = row.getY() for (let h = 0; h < row.getWordCount(); h++) { let word = row.word(h) for (let i = 0; i < word.getCharCount(); i++) { let char = word.char(i) drawChar(sceneId, char.name, char.font.name, char.font.bold, char.font.italic, x, y) let fontDesc = fontDescs.get(getFullFontName(char.font.name, char.font.bold, char.font.italic)) const charObj = getCharDesc(char.name, char.font.name, char.font.bold, char.font.italic) x += charObj.bounds.width + charObj.margin.left + charObj.margin.right if (i != word.getCharCount() - 1) { x += fontDesc.letterSpacing } } x += word.spaceWidth } }