You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.2 KiB
JavaScript

'use strict';
const canvassed = require("canvassed");
const objectPick = require("object.pick");
const tagParser = require("./tag-parser");
const layout = require("./layout");
const fromTree = require("./text-components/from-tree");
const setTextStyles = require("./render/set-text-styles");
const measureText = require("./render/measure-text");
function getTextProperties(item) {
return objectPick(item, ["fontSize", "fontFamily", "fontStyle", "fontWeight"]);
}
module.exports = function createTextShape(options) {
let textObject = canvassed.createObject(Object.assign({
_layout: null,
_lines: null,
type: "text",
cacheBustingProperties: ["fillColor", "strokeColor", "strokeWidth", "text", "fontSize", "fontFamily", "fontStyle", "fontWeight"],
sizeBustingProperties: ["text", "fontSize", "fontFamily", "fontStyle", "fontWeight"],
fillColor: "red",
strokeColor: "red",
strokeWidth: 0,
fontFamily: "sans-serif",
fontSize: 16,
fontWeight: "normal",
lineHeight: 1.16,
onRender: function onRender(context) {
if (this.tags === true) {
let currentLineOffset = 0;
let currentComponentOffset = 0;
this._layout.forEach((line) => {
line.items.forEach((item) => {
setTextStyles(context, item.style);
context.fillText(item.text, currentComponentOffset, currentLineOffset - line.lineMinAscender);
currentComponentOffset += item.measurements.width;
});
currentLineOffset += line.lineHeight * this.lineHeight;
currentComponentOffset = 0;
});
} else {
let currentLineOffset = 0;
setTextStyles(context, getTextProperties(this));
console.log(this._lines, this.renderWidth, this.renderHeight);
this._lines.forEach((line) => {
context.fillText(line.text, 0, currentLineOffset - line.lineMinAscender);
currentLineOffset += line.measurements.height * this.lineHeight;
});
}
},
onRecalculateSize: function onRecalculateSize() {
if (this.tags === true) {
this._layout = layout(this.text, {
classes: options.classes,
defaultStyle: getTextProperties(this)
});
let combinedLineHeight = this._layout.reduce((total, line, i) => {
if (i !== this._layout.length - 1) {
return total + (line.lineHeight * this.lineHeight);
} else {
/* The last line doesn't get a lineHeight multiplier... */
return total + line.lineHeight;
}
}, 0);
return {
height: Math.ceil(combinedLineHeight),
width: Math.ceil(Math.max.apply(null, this._layout.map(line => line.lineWidth)))
}
} else {
this._lines = this.text.split("\n").map((line) => {
return {
text: line,
measurements: measureText(line, getTextProperties(this))
}
});
console.log("line", this._lines)
function sum(values) {
return values.reduce((total, value) => {
return total + value;
}, 0);
}
let multipliedLineHeights = this._lines.slice(0, -1).map(line => line.measurements.height * this.lineHeight);
let combinedLineHeight = sum(multipliedLineHeights) + this._lines[this._lines.length - 1].measurements.height;
return {
height: Math.ceil(combinedLineHeight),
width: Math.ceil(Math.max.apply(null, this._lines.map(line => line.measurements.width)))
}
}
}
}, options));
return textObject;
}