Search code examples
javascripthtmlcanvasgetelementbyid

Javascript : HTML5 Canvas and id loop with getElementById


I'm pretty new with Javascript and I would like to use canvas with javascript in my Django template.

I have a little html part and javascript part which looks like this :

{% for document in publication.documents.all %}
<td class="col-md-1">
    <canvas id="the-canvas"></canvas>
</td>
{% endfor %}

<script>
  pdfjsLib.getDocument('http://localhost:8000/media/media/loremipsum2.pdf').then(function (pdf) {
    console.log("pdf loaded");
    pdf.getPage(1).then(function (page) {
        var scale = 0.40;
        var viewport = page.getViewport(scale);

        var canvas = document.getElementById('the-canvas');
        var context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;

        var renderContext = {
            canvasContext: context,
            viewport: viewport
        };
        page.render(renderContext);
    });
  });
</script>

I'm trying to use PDF.js in order to make some things. In my javascript code, I would like to handle getElementById in order to loop over dynamical html canvas id.

So I have this code now :

{% for document in publication.documents.all %}
<td class="col-md-1">
    <canvas id="the-canvas{{document.id}}"></canvas>
</td>
{% endfor %}

<script>
  pdfjsLib.getDocument('http://localhost:8000/media/media/loremipsum2.pdf').then(function (pdf) {
    console.log("pdf loaded");
    pdf.getPage(1).then(function (page) {
        var scale = 0.40;
        var viewport = page.getViewport(scale);

        var canvas = document.getElementById('the-canvas{{document.id}}');
        var context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;

        var renderContext = {
            canvasContext: context,
            viewport: viewport
        };
        page.render(renderContext);
    });
  });
</script>

The first code displays only the first canvas object (it's normal). The second one should display each canvas object but it doesn't work. It displays nothing.

Did I make any mistake in my javascript code ?

Thank you

Edit :

Code with loop over tag <canvas> :

{% for document in publication.documents.all %}
<td class="col-md-1">
    <canvas id="the-canvas"></canvas>
</td>
{% endfor %}

<script>
  pdfjsLib.getDocument('http://localhost:8000/media/media/loremipsum2.pdf').then(function (pdf) {
    console.log("pdf loaded");
    pdf.getPage(1).then(function (page) {
        var scale = 0.40;
        var viewport = page.getViewport(scale);

        var canvas = document.getElementsByTagName('canvas');
        var context = canvas.getContext('2d');
        canvas.height = viewport.height;
        canvas.width = viewport.width;

        var renderContext = {
            canvasContext: context,
            viewport: viewport
        };
        page.render(renderContext);
    });
  });
</script>

Solution

  • Did I get this right you want to loop over multiple canvases? As the question was not tagged Django I have no idea what that "dynamic variable" stuff is :D. But maybe that block of code helps you:

    You should be iterating over all the canvas objects returned by document.getElementsByTagName('canvas') but you are treating it as a single object

    let canvases = Array.from(document.getElementsByTagName("canvas"));
    canvases.forEach(canvas => {
      let ctx = canvas.getContext("2d");
      ctx.fillStyle = "red";
      ctx.fillRect(0, 0, 100, 50);
    });
    canvas {
      border: 1px solid black;
      height: 100px;
      width: 100px;
    }
    <canvas></canvas>
    <canvas></canvas>
    <canvas></canvas>
    <canvas></canvas>
    <canvas></canvas>
    <canvas></canvas>

    In your example, it would look like:

    pdfjsLib.getDocument('http://localhost:8000/media/media/loremipsum2.pdf').then(function (pdf) {
        console.log("pdf loaded");
        pdf.getPage(1).then(function (page) {
            var scale = 0.40;
            var viewport = page.getViewport(scale);
    
            var canvases = document.getElementsByTagName('canvas');
            Array.from(canvases).forEach((canvas) => {
                var context = canvas.getContext('2d');
                canvas.height = viewport.height;
                canvas.width = viewport.width;
    
                var renderContext = {
                    canvasContext: context,
                    viewport: viewport
                };
                page.render(renderContext);
            });
        });
      });
    

    Edit: you could use stuff like:

    let can = Array.from(document.getElementsByClassName(<className>);
    let can = Array.from(document.querySelectorAll(<CSS query>);
    ...
    

    If the right on is not in the list just ask :3