135 votes

Comment réparer un texte flou dans mon canevas HTML5 ?

Je suis un total n00b con HTML5 et je travaille avec le canvas pour rendre des formes, des couleurs et du texte. Dans mon application, j'ai un adaptateur visuel qui crée un canevas de façon dynamique et le remplit de contenu. Cela fonctionne très bien, sauf que mon texte est rendu de manière très floue/floue/étirée. J'ai vu beaucoup d'autres messages expliquant pourquoi la définition de l'option largeur y hauteur en CSS causera ce problème, mais je définis tout cela en javascript .

Le code correspondant (vue Violon ):

var width  = 500;//FIXME:size.w;
var height = 500;//FIXME:size.h;

var canvas = document.createElement("canvas");
//canvas.className="singleUserCanvas";
canvas.width=width;
canvas.height=height;
canvas.border = "3px solid #999999";
canvas.bgcolor = "#999999";
canvas.margin = "(0, 2%, 0, 2%)";

var context = canvas.getContext("2d");

//////////////////
////  SHAPES  ////
//////////////////

var left = 0;

//draw zone 1 rect
context.fillStyle = "#8bacbe";
context.fillRect(0, (canvas.height*5/6)+1, canvas.width*1.5/8.5, canvas.height*1/6);

left = left + canvas.width*1.5/8.5;

//draw zone 2 rect
context.fillStyle = "#ffe381";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*2.75/8.5, canvas.height*1/6);

left = left + canvas.width*2.75/8.5 + 1;

//draw zone 3 rect
context.fillStyle = "#fbbd36";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*1.25/8.5, canvas.height*1/6);

left = left + canvas.width*1.25/8.5;

//draw target zone rect
context.fillStyle = "#004880";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*0.25/8.5, canvas.height*1/6);

left = left + canvas.width*0.25/8.5;

//draw zone 4 rect
context.fillStyle = "#f8961d";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*1.25/8.5, canvas.height*1/6);

left = left + canvas.width*1.25/8.5 + 1;

//draw zone 5 rect
context.fillStyle = "#8a1002";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width-left, canvas.height*1/6);

////////////////
////  TEXT  ////
////////////////

//user name
context.fillStyle = "black";
context.font = "bold 18px sans-serif";
context.textAlign = 'right';
context.fillText("User Name", canvas.width, canvas.height*.05);

//AT:
context.font = "bold 12px sans-serif";
context.fillText("AT: 140", canvas.width, canvas.height*.1);

//AB:
context.fillText("AB: 94", canvas.width, canvas.height*.15);

//this part is done after the callback from the view adapter, but is relevant here to add the view back into the layout.
var parent = document.getElementById("layout-content");
parent.appendChild(canvas);

<div id="layout-content"></div>

Les résultats que je vois (en Safari ) sont beaucoup plus asymétriques que ce que montre le violon :

Mine

Rendered output in Safari

Violon

Rendered output on JSFiddle

Qu'est-ce que je fais de manière incorrecte ? Ai-je besoin d'un canevas distinct pour chaque élément de texte ? S'agit-il de la police ? Dois-je d'abord définir le canevas dans la mise en page HTML5 ? Y a-t-il une faute de frappe ? Je suis perdu.

0voto

Polina Potrebko Points 36

Pour moi, ce n'était pas seulement l'image mais aussi le texte qui était de mauvaise qualité. La solution la plus simple, qui fonctionne sur plusieurs navigateurs pour les écrans rétina/non-rétina, est de rendre l'image deux fois plus grande que prévu et de mettre à l'échelle le contexte du canevas comme le suggère cet homme : https://stackoverflow.com/a/53921030/4837965

0voto

sharmav Points 11

Le code suivant a fonctionné directement pour moi (alors que d'autres ne l'ont pas fait) :

    const myCanvas = document.getElementById("myCanvas");
    const originalHeight = myCanvas.height;
    const originalWidth = myCanvas.width;
    render();
    function render() {
      let dimensions = getObjectFitSize(
        true,
        myCanvas.clientWidth,
        myCanvas.clientHeight,
        myCanvas.width,
        myCanvas.height
      );
      const dpr = window.devicePixelRatio || 1;
      myCanvas.width = dimensions.width * dpr;
      myCanvas.height = dimensions.height * dpr;

      let ctx = myCanvas.getContext("2d");
      let ratio = Math.min(
        myCanvas.clientWidth / originalWidth,
        myCanvas.clientHeight / originalHeight
      );
      ctx.scale(ratio * dpr, ratio * dpr); //adjust this!
    }

    // adapted from: https://www.npmjs.com/package/intrinsic-scale
    function getObjectFitSize(
      contains /* true = contain, false = cover */,
      containerWidth,
      containerHeight,
      width,
      height
    ) {
      var doRatio = width / height;
      var cRatio = containerWidth / containerHeight;
      var targetWidth = 0;
      var targetHeight = 0;
      var test = contains ? doRatio > cRatio : doRatio < cRatio;

      if (test) {
        targetWidth = containerWidth;
        targetHeight = targetWidth / doRatio;
      } else {
        targetHeight = containerHeight;
        targetWidth = targetHeight * doRatio;
      }

      return {
        width: targetWidth,
        height: targetHeight,
        x: (containerWidth - targetWidth) / 10,
        y: (containerHeight - targetHeight) / 10
      };
    }

La mise en œuvre a été adaptée de este Poste moyen.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X