UNPKG

canvas-with-twemoji

Version:

Load emojis on canvas

88 lines (72 loc) 2.32 kB
const splitEntitiesFromText = require('./utils/splitEntitiesFromText'); const loadTwemojiImageByUrl = require('./utils/loadTwemojiImageByUrl'); const getFontSizeByCssFont = require('./utils/getFontSizeByCssFont'); const measureText = require('./measureText'); const { Canvas } = require('canvas'); module.exports = async function drawTextWithEmoji ( context, fillType, text, x, y, { maxWidth = Infinity, emojiSideMarginPercent = 0.1, emojiTopMarginPercent = 0.1 } = {} ) { const textEntities = splitEntitiesFromText(text); const fontSize = getFontSizeByCssFont(context.font); const baseLine = context.measureText('').alphabeticBaseline; const textAlign = context.textAlign; const transform = context.currentTransform; const emojiSideMargin = fontSize * emojiSideMarginPercent; const emojiTopMargin = fontSize * emojiTopMarginPercent; const textWidth = measureText(context, text, { emojiSideMarginPercent }).width; let textLeftMargin = 0; if (!['', 'left', 'start'].includes(textAlign)) { context.textAlign = 'left'; switch (textAlign) { case 'center': textLeftMargin = -textWidth / 2; break; case 'right': case 'end': textLeftMargin = -textWidth; break; } } let currentWidth = 0; if (textWidth > maxWidth) { let scale = maxWidth / textWidth; context.setTransform(scale, 0, 0, 1, 0, 0); x = x / scale; } for (let i = 0; i < textEntities.length; i++) { const entity = textEntities[i]; if (typeof entity === 'string') { if (fillType === 'fill') { context.fillText(entity, textLeftMargin + x + currentWidth, y); } else { context.strokeText(entity, textLeftMargin + x + currentWidth, y); } currentWidth += context.measureText(entity).width; } else { const emoji = await loadTwemojiImageByUrl(entity.url); emoji.width = fontSize; emoji.height = fontSize; context.drawImage( emoji, textLeftMargin + x + currentWidth + emojiSideMargin, y + emojiTopMargin - fontSize - baseLine, fontSize, fontSize ); currentWidth += fontSize + (emojiSideMargin * 2); } } if (textAlign) { context.textAlign = textAlign; } context.setTransform(transform); }