1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- export default class TextWrapper {
- constructor() {
- this.margin = {left: 8, right: 8}
- this.padding = {top:4, left: 8, bottom: 4, right: 8}
- this.fontSize = 24
- }
- draw(ctx, text, options) {
- let width = options.width
- let line = 0;
- text.split("\n").forEach(textLine => {
- while (this.textIsTooLong(ctx, textLine, width)) {
- let shortTextIndex = this.getShortTextIndex(ctx, textLine, width)
- let shortText = textLine.substr(0, shortTextIndex).trim()
- textLine = textLine.substr(shortTextIndex)
- this.drawTextLine(ctx, shortText, line)
- line++;
- }
-
- this.drawTextLine(ctx, textLine.trim(), line)
- line++
- })
-
- }
- drawTextLine(ctx, text, line) {
- let bounds = ctx.measureText(text);
- let textHeight = Math.max(Math.ceil(this.fontSize), bounds.actualBoundingBoxAscent + bounds.actualBoundingBoxDescent);
- ctx.fillText(text, this.padding.left, this.padding.top + (line * textHeight));
- }
- getShortTextIndex(ctx, text, width) {
- let timeout = 0
- while (this.textIsTooLong(ctx, text, width)) {
- timeout++
- let words = text.split(" ");
- words.pop();
- text = words.join(" ");
- if(timeout > 50) {
- throw new Error(`Text won't fit in ${width}`)
- }
- }
- return text.length;
- }
- textIsTooLong(ctx, text, width) {
- let bounds = ctx.measureText(text);
- let areaWidth = width - (this.padding.left + this.padding.right + this.margin.left + this.margin.right);
- return bounds.width > areaWidth
- }
- }
|