fill-warp-text.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /** 绘制换行字体原型方法 */
  2. export default {
  3. name: 'fillWarpText',
  4. handle: (canvas, ctx, config) => {
  5. const newConfig = config = Object.assign({ maxWidth: 100, layer: 2, lineHeight: Number(ctx.font.replace(/[^0-9.]/g, '')), x: 0, y: Number(ctx.font.replace(/[^0-9.]/g, '')) / 1.2, splitText: '', notFillText: false }, config);
  6. const { text, splitText, maxWidth, layer, lineHeight, notFillText, x, y } = newConfig;
  7. // 当字符串为空时, 抛出错误
  8. if (!text) {
  9. throw Error('warpFillText Error: text is empty string');
  10. }
  11. // 分割所有单个字符串
  12. const chr = text.split(splitText);
  13. // 存入的每行字体的容器
  14. let row = [];
  15. // 判断字符串
  16. let timp = '';
  17. if (splitText) {
  18. row = chr;
  19. }
  20. else {
  21. // 遍历所有字符串, 填充行容器
  22. for (let i = 0; i < chr.length; i++) {
  23. // 当超出行列时, 停止执行遍历, 节省计算时间
  24. if (row.length > layer) {
  25. break;
  26. }
  27. if (ctx.measureText(timp).width < maxWidth) {
  28. // 如果超出长度, 添加进row数组
  29. timp += chr[i];
  30. }
  31. else {
  32. // 如超出一行长度, 则换行, 并清除容器
  33. i--;
  34. row.push(timp);
  35. timp = '';
  36. }
  37. }
  38. // 如有剩下字体, 则在最后时添加一行
  39. if (timp) {
  40. row.push(timp);
  41. }
  42. // 如果数组长度大于指定行数
  43. if (row.length > layer) {
  44. row = row.slice(0, layer);
  45. // 结束的索引
  46. const end = layer - 1;
  47. for (let i = 0; i < row[end].length; i++) {
  48. const currentWidth = ctx.measureText(`${row[end]}...`).width;
  49. if (currentWidth > maxWidth) {
  50. // 加上... 当前宽度大于最大宽度时, 去除一位字符串
  51. const strEnd = row[end].length - 1;
  52. row[end] = row[end].slice(0, strEnd);
  53. }
  54. else {
  55. row[end] += '...';
  56. break;
  57. }
  58. }
  59. }
  60. }
  61. // 储存并返回绘制信息
  62. const drawInfos = row.map((item, index) => {
  63. const info = {
  64. text: item,
  65. y: y + index * lineHeight,
  66. x: x,
  67. };
  68. // 默认执行绘制信息
  69. if (!notFillText) {
  70. ctx.fillText(info.text, info.x, info.y);
  71. }
  72. return info;
  73. });
  74. return drawInfos;
  75. }
  76. };