lazydevpro
lazydevpro

Reputation: 127

javaScript clear image source not working

I am trying to convert a div with text and image into a single image then setting that image as my image source but the image is getting copied multiple times or getting error and code not working.

I am getting the text from textarea and then setting that text on the above of image and then converting that text and image into a single image by using html5canavs. Code is working fine but the issue is image is getting copied multiple times and if I am trying to clear the image it is not working.

Here's the image of how it is looking after overlapping multiple times.Image Priview

Here's my code

window.onload = function() {
  
  }

  function myFunction() {
    var v = document.getElementById("mTextArea").value;
    document.getElementById("wow").innerHTML = v;

    html2canvas(document.getElementById("imagewrap"), {
      onrendered: function(canvas) {
        theCanvas = canvas;

        canvas.className = "html2canvas";
        var image = canvas.toDataURL("image/png");
        // document.body.removeChild("container2"); <<---Throwing Error
        document.getElementById("img_prev").src = image;
      },
      useCORS: true
    });
  }
*{
    font-family: 'Roboto', sans-serif;
}
#container1{
    float: left;
}
#container2{
    float: right;
}
#mImage{
    height: 300px;
    width: 300px;
}

.desc {
    position: absolute;
    text-align: center;
    top: 1px;
    left: 30px;
}
.outer, .wrap, .html2canvas, .image_text {
display: inline-block;
vertical-align: top;
}
.wrap {
text-align: center;
}
#imagewrap {
    position: relative;
background-color: white;
}
#wow {
    text-align: center;
    font-size: 25pt;
    position: absolute;
    color: red;
    display: block;
    top: 50px;
    left: 50px;
    right: 50px;
    align-items: center;
    word-wrap: break-word;
}
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="styles.css">
        <script src="script.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
        <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap" rel="stylesheet"> 
        <title>Social Poster</title>
    </head>
    <body>
        <h1>Social Poster</h1>
        <div id="container1">
            <textarea name="inputT" id="mTextArea" cols="30" rows="10"></textarea>
            <button id="mButton" onclick="myFunction()">Click ME!</button>
        </div>
        <div id="container2">
              <div class="outer">
                <div id="imagewrap" class="wrap" style="border: solid;">
                  <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQ2w0Uf5u-qRiqYZVXmHukxNQxPENtwoEqh2qBpj871sojoaePh&usqp=CAU" id="img_prev" width="500" />
                  <span id="wow">WOW!</span>
                </div>
              </div>

        </div>
    </body>
</html>

Upvotes: 0

Views: 126

Answers (2)

Blindman67
Blindman67

Reputation: 54099

You are rendering the image ontop of its self causing the feedback effect.

Just use two images. Showing the background and text when you click render and when the result has rendered hide the original background and text just showing the result image.

Move the border out of the rendered image to stop the shrinking background.

Example

mButton.addEventListener("click",createImage);

function createImage() {
  // show text and background image
  wow.textContent = mTextArea.value;
  wow.classList.remove("hide");
  backgroundImage.classList.remove("hide");
  
  // hide prev rendered image
  resultImage.classList.add("hide");
  
  // render to canvas
  html2canvas(imagewrap, {
    onrendered(canvas) {
      // hide background and text image
      backgroundImage.classList.add("hide");
      backgroundImage.classList.add("hide");
      
      // show rendered image
      resultImage.classList.remove("hide");
      resultImage.src = canvas.toDataURL("image/png");
    },
    useCORS: true
  });
}
*{
    font-family: 'Roboto', sans-serif;
}
#container1{
    float: left;
}
#container2{
    float: right;
}
#mImage{
    height: 300px;
    width: 300px;
}

.desc {
    position: absolute;
    text-align: center;
    top: 1px;
    left: 30px;
}
.outer, .wrap, .html2canvas, .image_text {
  display: inline-block;
  vertical-align: top;
}
.wrap {
  text-align: center;
}
#imagewrap {
    position: relative;
    background-color: white;
}
#wow {
    text-align: center;
    font-size: 25pt;
    position: absolute;
    color: red;
    display: block;
    top: 50px;
    left: 50px;
    right: 50px;
    align-items: center;
    word-wrap: break-word;
}

.hide {
  display: none;
}
.resultBorder {
  border: solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap" rel="stylesheet"> 

<h1>Social Poster</h1>
<div id="container1">
    <textarea name="inputT" id="mTextArea" cols="30" rows="10"></textarea>
    <button id="mButton" >Create Image!</button>
</div>
<div id="container2">
      <div class="outer resultBorder">
        <div id="imagewrap" class="wrap" >
          <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQ2w0Uf5u-qRiqYZVXmHukxNQxPENtwoEqh2qBpj871sojoaePh&usqp=CAU" id="backgroundImage" width="500" />
          <img class="hide" id="resultImage"></img>
          <span id="wow">WOW!</span>
        </div>
      </div>

</div>

Upvotes: 1

M A Salman
M A Salman

Reputation: 3820

Problem - Multiple images -- why?

After first click it captures the div into canvas.You can clearly see there is some border outside image. So after you are setting the image in the div to the "canvas created image" border will remain and the div captured into image will have inturn the border as its like screenshot of it.

Solution:

Remove the border and avoid spacing

Problem - Text over Text -- why?

You are setting the value of span with id "wow" to the value of text area whenever you click the "click me" button and then you are doing html2canvas which will make an image of div since you have span inside div with text it will also be there in the canvas.After canvas is generated you are setting the src of image to canvas.toDataURL(). When you again click on "click me" with different text , it will place the text on current image(which already has some previous text)

Solution:

Set the text of the span with id="wow" after img.src=canvas.toDateURL()

function myFunction() {
   document.getElementById("wow").innerHTML =""
    html2canvas(document.getElementById("imagewrap"), {
      onrendered: function(canvas) {
        var image = canvas.toDataURL();      
      document.getElementById("img_prev").src = image
      document.getElementById("wow").innerHTML =
      document.getElementById("mTextArea").value;
      },
      useCORS: true
    });
  }
*{
    font-family: 'Roboto', sans-serif;
}
#container1{
    float: left;
}
#container2{
    float: right;
}
#mImage{
    height: 300px;
    width: 300px;
}

.desc {
    position: absolute;
    text-align: center;
    top: 1px;
    left: 30px;
}
.outer, .wrap, .html2canvas, .image_text {
display: inline-block;
vertical-align: top;
}
.wrap {
text-align: center;
}
#imagewrap {
    position: relative;
background-color: white;
}
#wow {
    text-align: center;
    font-size: 25pt;
    position: absolute;
    color: red;
    display: block;
    top: 50px;
    left: 50px;
    right: 50px;
    align-items: center;
    word-wrap: break-word;
}
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="styles.css">
        <script src="script.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
        <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap" rel="stylesheet"> 
        <title>Social Poster</title>
    </head>
    <body>
        <h1>Social Poster</h1>
        <div id="container1">
            <textarea name="inputT" id="mTextArea" cols="30" rows="10"></textarea>
            <button id="mButton" onclick="myFunction()">Click ME!</button>
        </div>
        <div id="container2">
              <div class="outer">
                <div id="imagewrap" class="wrap" >
                  <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQ2w0Uf5u-qRiqYZVXmHukxNQxPENtwoEqh2qBpj871sojoaePh&usqp=CAU" id="img_prev" width="500" />
                  <span id="wow">WOW!</span>
                </div>
              </div>

        </div>
    </body>
</html>

Upvotes: 0

Related Questions