Lorsque j'ai écrit mon dernier billet sur mes expérimentations HTML5, j'ai expliqué comment dessiner un coeur sous prétexte que la St-Valentin approchait. Pour être franc, ce n'était pas mon objectif principal. J'ai eu l'idée de dessiner un coeur lorsque j'ai reçu mon compte de taxes de la ville de Montréal et que j'ai aperçu le logo en forme de rosace composée de 4 coeurs. Le premier billet reflète donc le premier but à atteindre (bien que la façon d'y arriver et le résultat sont différents) et celui d'aujourd'hui démontre comment je suis arrivé à faire une reproduction approximative du logo de Montréal en utilisant le canvas HTML5.
Bien sûr, j'ai triché ici et là alors je laisserai le soin aux designers graphiques soucieux des détails de relever les imprécisions, mon approche de programmeur étant surtout basée sur l'apprentissage du calcul des arcs, cloner le canvas, la translation et rotation d'éléments ainsi que le calcul de courbes quadratiques. Je suis quand même assez satisfait du résultat.
Pour vous aider à suivre, j'ai préparé un graphique pour illustrer les étapes à suivre.
À partir d'un canvas de 500 pixels de côté, je récupère les références, j'applique la couleur rouge aux propriétés du trait et de remplissage et je définis l'épaisseur du tracé avec une valeur qui me semble raisonnable à l'oeil.
var canvas = document.getElementById('myCanvas');Pour faciliter le travail et pour centrer le logo au milieu du canvas, je déplace mon origine au centre calculé.
var context = canvas.getContext('2d');
context.strokeStyle = '#CE2123';
context.fillStyle = '#CE2123';
context.lineWidth = 18;
context.translate(canvas.width/2, canvas.height/2);Je crée les deux premiers arcs de cercles qui se trouvent complètement au haut du logo (étape 1).
// arc haut gaucheÀ l'extrémité de l'arc gauche, je place un cercle central (étape 2). L'idée est que je clonerai ce gabarit pour le dupliquer pour compléter la rosace avec moins d'efforts.
context.beginPath();
context.arc(-50, -150, 50, 130*(Math.PI/180), 0*(Math.PI/180));
context.stroke();
context.closePath();
// arc haut droit
context.beginPath();
context.arc(50, -150, 50, Math.PI, 50*(Math.PI/180));
context.stroke();
context.closePath();
// cercle internePremier clonage et rotation (étape 3).
context.beginPath();
context.arc(-70, -98, 25, 0, Math.PI*2, false);
context.fill();
context.closePath();
// copie à gauche avec rotationDeuxième clonage (étape 4).
context.save();
var canvas1 = canvas.getContext('2d');
context.rotate(270*Math.PI/180);
canvas1.drawImage(canvas, -221, -222);
context.restore();Enfin, je trace la croix centrale qui donne l'illusion d'une juxtaposition de quatre coeurs (étape 5).
var canvas2 = canvas.getContext('2d');
context.rotate(180*Math.PI/180);
canvas1.drawImage(canvas, -250, -192);
// lignesCe n'est pas tout. Si on regarde comme il faut le croisement des deux axes qu'on vient de tracer, on voit que chaque angle a une courbure. C'est ici que j'ai utilisé les courbes quadratiques mais j'aurais très bien pu utiliser la composition avec globalCompositeOperation en source-in (étape 6).
context.beginPath();
context.moveTo(0, -100);
context.lineTo(0, 150);
context.closePath()
context.stroke();
context.rotate(90*Math.PI/180);
context.beginPath();
context.moveTo(29, -125);
context.lineTo(29, 125);
context.closePath()
context.stroke();
context.rotate(270*Math.PI/180);
context.translate(0, 27); // centre
context.save();
// courbes quadratiques pour le centreVoilà le logo terminé.
context.translate(7, 7);
// la preuve que j'y suis allé à tâton,
// j'étais tanné de remplacer la valeur dans les appels suivants!
var curve = 35;
context.beginPath();
context.moveTo(0, curve);
context.quadraticCurveTo(0, 0, curve, 0);
context.lineTo(0,0);
context.fill();
context.restore();
context.save();
context.translate(-7, 7);
context.beginPath();
context.moveTo(-curve, 0);
context.quadraticCurveTo(0, 0, 0, curve);
context.lineTo(0,0);
context.fill();
context.restore();
context.save();
context.beginPath();
context.arc(0, 0, 3, 0, Math.PI*2, false);
context.fill();
context.closePath();
context.translate(7, -7);
context.beginPath();
context.moveTo(0, -curve);
context.quadraticCurveTo(0, 0, curve, 0);
context.lineTo(0,0);
context.fill();
context.restore();
context.save();
context.translate(-7, -7);
context.beginPath();
context.moveTo(-curve, 0);
context.quadraticCurveTo(0, 0, 0, -curve);
context.lineTo(0,0);
context.fill();
Selon le site de la ville, l'emblème de Montréal, créé en 1981, s'inspire des armoiries et représente une fleur dont les quatre pétales forment une interprétation graphique des initiales de la Ville de Montréal: V et M. Au centre, un croisement rappelle que Montréal a toujours été au carrefour des grandes voies de communication et de civilisation.
Enfin, les quatre coeurs créés par le jeu des lignes représentent l'attachement des Montréalais et des Montréalaises à leur ville. La ligne ondoyante qui encercle l'ensemble stylisé rappelle que Montréal est une île; la forme à la fois végétale et aquatique exprime la richesse de l'environnement naturel et le souci qu'a la population de le préserver (source).