Search code examples
htmlcanvasselectioncopy-paste

Adding "alt" content to canvas


I am writing a program that embeds text in canvases, each canvas contains one character (Kanji) that will be animated, drawn one stroke at a time.

I have encountered a few problems so far:

  1. The user cannot select the canvases.
  2. The use cannot copy the text, as there is no text, but just images.

I might have overcome the second issue by inserting the text inside the <canvas> tag (though I have no way to check if it works, as I can't select the canvases to copy the content); but I have no idea on how to solve the first issue.

So the question is: how can I make my canvases behave as images with alt attributes, so that users can copy them as if they were normal characters?

JsFiddle example with <img alt="...">

Thanks!

UPDATE

I have written a few more tests:

I've also tried with labels, but there were even more issues and no noticeable advantage.


Solution

  • There is no such alt attribute to canvas element.

    From "MDN - Basic Usage of canvas":

    At first sight a <canvas> looks like the <img> element, with the only clear difference being that it doesn't have the src and alt attributes.

    Also, the innerHTML of the canvas will only be accessible to browsers which don't support <canvas> element.

    What you could do however, if you only draw once on the canvas and if there is no Cross-Origin involved in those drawings (i.e external images), is to create new <img> tags with their src set to the canvas.toDataURL(), and assign those an alt attribute.

    var img = new Image();
    img.onload = function(){
      canvas.parentNode.replaceChild(this, canvas);
      this.alt = 'your alt content';
      }
    img.src = canvas.toDataURL();
    

    Or alternatively, for your particular case, you could also append a <span>element with its opacity set to 0 , its height/width to 1px and positionning it absolutely.

    It should not be visible, but you would be able to copy paste its content.

    body {
      font-size: 14px;
    }
    img {
      display: inline-block;
      vertical-align: baseline;
      cursor: text;
      height: 1em;
    }
    .canvas_alt {
      position: absolute;
      max-height: 1px;
      max-width: 1px;
      opacity: 0
    }
    canvas {
      border: 1px solid
    }
    Copy the images as if text:
    <br />
    <br />X<canvas height="50" width="50"></canvas><span class="canvas_alt">alt text</span>Y
    <br />
    <br />Try pasting it here, is should be 'XiiY':
    <br />
    <input />