最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - html2canvas remove multiple spaces and Line Break - Stack Overflow

programmeradmin1浏览0评论

I'm using html2canvas to render html contents to image. But it supports only single blank space between word and also all text displayed only in One.

Example 1

if text is  `Word1      Word2` it bee to `word1 word2`

Example 2

This is First line 
This is Second Line 

Image: 

THis is First line This is Second Line

I looked in to the html2canvas Code and I believe below these two functions are responsible for drawing the text and spaces. Help me how can i achieve my target.

  function renderText(el, textNode, stack) {
    var ctx = stack.ctx,
    color = getCSS(el, "color"),
    textDecoration = getCSS(el, "textDecoration"),
    textAlign = getCSS(el, "textAlign"),
    metrics,
    textList,
    state = {
      node: textNode,
      textOffset: 0
    };

    if (Util.trimText(textNode.nodeValue).length > 0) {
      textNode.nodeValue = textTransform(textNode.nodeValue, getCSS(el, "textTransform"));
      textAlign = textAlign.replace(["-webkit-auto"],["auto"]);

      textList = (!options.letterRendering && /^(left|right|justify|auto)$/.test(textAlign) && noLetterSpacing(getCSS(el, "letterSpacing"))) ?
      textNode.nodeValue.split(/(\b| )/)
      : textNode.nodeValue.split("");

      metrics = setTextVariables(ctx, el, textDecoration, color);

      if (options.chinese) {
        textList.forEach(function(word, index) {
          if (/.*[\u4E00-\u9FA5].*$/.test(word)) {
            word = word.split("");
            word.unshift(index, 1);
            textList.splice.apply(textList, word);
          }
        });
      }

      textList.forEach(function(text, index) {
        var bounds = getTextBounds(state, text, textDecoration, (index < textList.length - 1), stack.transform.matrix);
        if (bounds) {
          drawText(text, bounds.left, bounds.bottom, ctx);
          renderTextDecoration(ctx, textDecoration, bounds, metrics, color);
        }
      });
    }
  }

      function drawText(currentText, x, y, ctx){
        if (currentText !== null && Util.trimText(currentText).length > 0) {
          ctx.fillText(currentText, x, y);
          numDraws+=1;
        }
      }

I'm using html2canvas to render html contents to image. But it supports only single blank space between word and also all text displayed only in One.

Example 1

if text is  `Word1      Word2` it bee to `word1 word2`

Example 2

This is First line 
This is Second Line 

Image: 

THis is First line This is Second Line

I looked in to the html2canvas Code and I believe below these two functions are responsible for drawing the text and spaces. Help me how can i achieve my target.

  function renderText(el, textNode, stack) {
    var ctx = stack.ctx,
    color = getCSS(el, "color"),
    textDecoration = getCSS(el, "textDecoration"),
    textAlign = getCSS(el, "textAlign"),
    metrics,
    textList,
    state = {
      node: textNode,
      textOffset: 0
    };

    if (Util.trimText(textNode.nodeValue).length > 0) {
      textNode.nodeValue = textTransform(textNode.nodeValue, getCSS(el, "textTransform"));
      textAlign = textAlign.replace(["-webkit-auto"],["auto"]);

      textList = (!options.letterRendering && /^(left|right|justify|auto)$/.test(textAlign) && noLetterSpacing(getCSS(el, "letterSpacing"))) ?
      textNode.nodeValue.split(/(\b| )/)
      : textNode.nodeValue.split("");

      metrics = setTextVariables(ctx, el, textDecoration, color);

      if (options.chinese) {
        textList.forEach(function(word, index) {
          if (/.*[\u4E00-\u9FA5].*$/.test(word)) {
            word = word.split("");
            word.unshift(index, 1);
            textList.splice.apply(textList, word);
          }
        });
      }

      textList.forEach(function(text, index) {
        var bounds = getTextBounds(state, text, textDecoration, (index < textList.length - 1), stack.transform.matrix);
        if (bounds) {
          drawText(text, bounds.left, bounds.bottom, ctx);
          renderTextDecoration(ctx, textDecoration, bounds, metrics, color);
        }
      });
    }
  }

      function drawText(currentText, x, y, ctx){
        if (currentText !== null && Util.trimText(currentText).length > 0) {
          ctx.fillText(currentText, x, y);
          numDraws+=1;
        }
      }
Share Improve this question edited Mar 11, 2014 at 6:19 Javed Akhtar asked Mar 11, 2014 at 6:13 Javed AkhtarJaved Akhtar 2871 gold badge3 silver badges8 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 6

html2canvas render the textarea or Input box value in the one line and trim all more than one spaces between words. So I found solution by converting text area into the div tag , Check out html contenteditable Attribute

 Replace  <textarea></textarea> with <div contenteditable="true"></div>

if you want to have the same textarea behavior to the div with jquery then use this code

$( '#EDITABLE' ).focus();

var selection = window.getSelection();
var range = document.createRange();
var div = $('#div2').get(0);

range.setStartBefore(div);
range.collapse(true);

selection.removeAllRanges();
selection.addRange(range);

// cursor should now be between div1 and div2
range = window.getSelection().getRangeAt(0);
console.log("range object returned is: ", range);

See Example: http://jsfiddle/9ZZpX/3/

I know it's old but, here is the workaround I came with using jquery/JS for your "Example 2":

var oldTextArea = $('#textArea').replaceWith("<div id='divForTA' class='divTextArea'>" + $('#textArea').val().replace(/\n/g, "<br>") + "</div>");
var el = document.querySelector("#container");
html2canvas(el).then(canvas => {
    canvas.toDataURL();
    $('#divForTA').replaceWith(oldTextArea);
});

So basicaly you replace your textArea with a "div" and once the canvas is rendered as image you revert the new created "div" to "textArea"

You can style the "div" using the "id" to add a border to make it looks like "textarea" like this:

 #divForTA {
     border: solid 1px lightgrey;
 }

I suggest to put a ment in the github html2canvas issue so at some point this will be fixed https://github./niklasvh/html2canvas/issues/2008

Hope this will help someone :-)

I tried all kinds of things, including a parameter that exists in a specific version of html2canvas which is: letterRendering: true in the options of your object.

In my case, I receive an error that this option doesn't exists in the lib that I've download

html2canvas(document.querySelector("#capture2image"), {
            allowTaint: true,
            useCORS: true,            
            logging: false
        })

So i just did a simple/non-maintainable thing:

{{ name.replace(" ", "&nbsp;") }}

maybe it will help others who also tried everything yet nothing worked ....

there is a race condition in html2canvas. try this:

  setTimeout(() => {
    canvas = html2canvas(element, {scale:1});
  }, 0)
发布评论

评论列表(0)

  1. 暂无评论