Les canvas HTML5 : chapitre 2 les calques

Ainsi continue la suite d’articles que j’avais commencée a propos des canvas html5 il y a deux semaines.

Je suis très heureux de constater que cet article est déjà bien référencé dans Google. Cela ne fait que renforcer ma motivation.

Ainsi, ce second chapitre portera sur la possibilité de créer des calques avec des canvas.

Le concept de calque :

Le concept des calques est très utilisé dans les logiciels de traitement d’image complexes style photoshop ou gimp.

Il s’agit de séparer votre images en plusieurs sous-images que vous superposerez ensuite selon un mode que vous choisirez, par exemple via un xor…

Les canvas permettent d’émuler ce genre de comportement assez intuitivement.

En effet , en créant plusieurs calques avec un fond transparent, puis en les superposant via CSS, on a autant de calques que de canvas.

Ce sera par la suite grâce ? la propriété z-index que vous pourrez switcher entre deux calques.

Pour gérer l’opacité il faudra utiliser le système rgba qui vous permet de renseigner une couleur sur 32bits avec un canal alpha.

Par exemple pour créer une ligne estompée de moitié et qui permet de voir au travers une partie du fond, vous aurez ce code :
[cc lang=”javascrip”]
context.strokeStyle=’rgba(255,0,0,0.5)’;
context.moveTo(0,0);
context.lineTo(100,100);[/cc]
En parlant de l’opacité un problème auquel j’ai dû faire face est qu’habituellement, je stocke mes couleurs sous forme d’entier, puis avec un jeu de masque/décalage de bit je pouvais obtenir les composantes rouge vertes et bleues facilement.

Le problème ici, c’est que le canal alpha est représenté par un flottant, pas un entier de 0 à 255.

En fait, il suffit alors de stocker la couleur sur un entier 32 bits, de récupérer la composante de poids faible et de la diviser par 255.
[cc lang=”javascript”]/**
*convertit un entier en couleur rgba
*@param integer l’entier à convertir
*@return la couleur rgba désirée
*/
var getRGBAColorFromInteger = function(integer){
return ‘rgba(‘+(integer>>24) +’,’+((integer>>16) & 255) +’,’+((integer >> 8) & 255) +’,’+((integer & 255)/255)+’)’;

}[/cc]

Obtenir les dessins faits sur un calque :

Une fois que vous avez travaillé sur votre calque, il peut être intéressant de connaître tous les pixels qui y ont été dessinés, notamment pour coder une fusion spéciale ou tout simplement pour déplacer le calque par exemple.

Pour faire cela, il vous faudra utiliser la fonction getImageData qui vous retourne un objet/structure composé de :

  1. un champ length = 4*nombre de pixel
  2. un champ data = un tableau où sont rangés vos pixel. Un pixel équivaut ? quatre cases dans ce tableau ([4n]=>Rouge, [4n+1]=>Vert, [4n+2]=>Bleu, [4n+3]=>alpha)

La fonction getImageData vous demande quatre arguments :

  1. x = L’abscisse ? partir de laquelle on commence
  2. y = L’ordonnée ? partir de laquelle on commence
  3. width = La largeur du rectangle qu’on désire sélectionner. Cette largeur peut être positive ou négative selon qu’on veuille aller ? droite ou ? gauche.
  4. height = La hauteur du rectangle qu’on désire sélectionner. Cette hauteur peut être positive ou négative selon qu’on veuille aller en haut ou en bas

Notons que si vous sélectionnez un pixel en dehors du canvas, il sera mis en tant que noir transparent dans le imageData (rgba(0,0,0,0)) cela est très courant avec les canvas. Par exemple la méthode fillRect() remplit le canvas de pixels noirs transparents.

Cela peut être gênant puisque le noir transparent se confond avec le background sur lequel est posé le canvas. Ainsi, si vous ne prenez pas peine d’initialiser correctement votre canvas, il se peut que vous ayez des comportement inattendus, par exemple pour des algorithmes de remplissage.

Mettre des pixels dans un canvas :

Cette fois ci il suffira d’utiliser la fonction putImageData. Les paramètres de cette dernière sont ;

  1. imageData = l’objet ImageData ? copier
  2. x = L’abscisse ? partir de laquelle on commence
  3. y = L’ordonnée ? partir de laquelle on commence
  4. width = La largeur du rectangle qu’on désire copier. Cette largeur peut être positive ou négative selon qu’on veuille aller ? droite ou ? gauche.
  5. height = La hauteur du rectangle qu’on désire copier. Cette hauteur peut être positive ou négative selon qu’on veuille aller en haut ou en bas

Cette méthode est apparemment très optimisée pour remplir des canvas, d’après le MDN.

2 thoughts on “Les canvas HTML5 : chapitre 2 les calques

  1. Je cherche désespérément comment pouvoir dessiner derrière une image.
    J’avais imaginé une simple gestion de calques : premier plan l’image, second plan le dessin…
    Mais je ne trouve nulle part une explication autre que des images sur différent plan…
    Suis-je le seul à avoir ce besoin ???
    Explication : je veux permettre aux enfants de faire du coloriage, avec le dessin au format png en traits noirs; et de colorier par dessous, ce qui évite des finition trop précises…

    Cordialement

    Claude

    • Si vous désirez faire que les bords soient “par dessus” contrairement à un dessin papier où ils sont “par dessous”, il est, je pense possible de procéder ainsi :
      – l’image du coloriage doit être un PNG, le blanc doit être transparent
      – faire un drawImage du PNG assez souvent pour que le dessin apparaissent quand il y a des débordements.

      Si au contraire vous voulez que le dessin soit comme sur un dessin “papier” avec les débords qui passent sur le trait de base, alors simplement mettre la propriété css background-image avec votre coloriage de base devrait être bon.

Leave a Reply

Your email address will not be published. Required fields are marked *