La grille
Avant de vraiment commencer, nous devons discuter de la grille ou de l'espace de coordonnées de la toile. Dans le modèle HTML de la page précédente, il y a un objet canevas de 150 pixels de large et 150 pixels de haut. J'ai superposé la grille par défaut sur l'écran, comme indiqué à droite. Habituellement, 1 unité de grille correspond à 1 pixel sur la toile. L'origine de la grille est positionnée dans le coin supérieur gauche (coordonnées (0,0)). Les positions de tous les objets dans l'image sont relatives à cette origine. De cette façon, la position du carré bleu dans le coin supérieur gauche est de x pixels à partir de la gauche et de Y pixels à partir du haut (coordonnées (x, y)). Dans les didacticiels ultérieurs, nous apprendrons comment déplacer l'origine, faire pivoter et mettre à l'échelle le maillage. Mais pour l’instant, nous utiliserons l’état par défaut.
Dessiner des formes
la toile ne prend en charge qu'une seule forme de base - le rectangle, donc les autres formes sont composées d'un ou plusieurs chemins. Heureusement, il existe un ensemble de fonctions de dessin de chemins qui nous permettent de dessiner des formes assez complexes.
Rectangles
Regardons d'abord les rectangles. Il existe trois fonctions pour dessiner des rectangles :
fillRect(x,y,width,height) : Draws a filled rectangle strokeRect(x,y,width,height) : Draws a rectangular outline clearRect(x,y,width,height) : Clears the specified area and makes it fully transparent
Ils acceptent tous quatre paramètres, x et y spécifient le position du coin supérieur gauche du rectangle (par rapport à l'origine), et width et height sont la largeur et la hauteur du rectangle. D'accord, essayons-le.
Exemple de dessin d'un rectangleExemple de forme rectangulaire
function draw(){ var canvas = document.getElementById('tutorial'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.fillRect(25,25,100,100); ctx.clearRect(45,45,60,60); ctx.strokeRect(50,50,50,50); } }
Le résultat doit être le même que celui du dessous c'est pareil. La fonction fillRect
dessine un grand rectangle noir (100x100), la fonction clearRect
efface le carré 60x60 au milieu, puis la fonction StrokeRect
trace une bordure rectangulaire de 50x50 dans l'espace dégagé. Dans les pages suivantes, nous verrons deux autres méthodes similaires à la fonction clearRect
, et comment modifier les couleurs de remplissage et de bordure des graphiques.
Dessiner des chemins
Contrairement au dessin de rectangles, dessiner des chemins nécessite quelques étapes supplémentaires.
beginPath() closePath() stroke() fill()
La première étape consiste à créer un chemin avec beginPath
. En mémoire, les chemins sont stockés sous la forme d'un ensemble de sous-tracés (lignes, arcs, etc.), qui forment ensemble un graphique. Chaque fois que startPath
est appelé, le groupe de sous-chemins est réinitialisé et de nouveaux graphiques peuvent alors être dessinés.
La deuxième étape est le dessin proprement dit du chemin, comme nous le verrons sous peu.
La troisième étape consiste à appeler la méthode closePath
, qui tentera de fermer le chemin en connectant le point final actuel et le point final de départ avec une ligne droite, mais si la forme est déjà fermée ou s'il y a un seul point, ça ne servira à rien. Cette étape n'est pas nécessaire.
La dernière étape consiste à appeler la méthode trait ou remplissage. À ce stade, le graphique est réellement dessiné sur la toile. Le contour est la bordure pour dessiner des graphiques, et le remplissage en remplira un graphique solide.
Remarque : lorsque fill est appelé, le chemin ouvert sera automatiquement fermé sans appeler closePath.
Le code pour dessiner une forme simple (comme un triangle) est le suivant.
ctx.beginPath(); ctx.moveTo(75,50); ctx.lineTo(100,75); ctx.lineTo(100,25); ctx.fill();
moveTo
est une méthode très utile bien qu'elle ne puisse pas être utilisée pour dessiner quoi que ce soit, elle fait partie de la méthode pratique de dessin de chemins. Vous pouvez imaginer cela comme soulever un stylo et le déplacer d’un point à un autre. Il accepte x
et y (nouvelle position des coordonnées) comme paramètres. Lorsque Canvas est initialisé ou que BeginPath est appelé, le paramètre de coordonnées de départ est l'origine (0,0). Dans la plupart des cas, nous utilisons la méthode moveTo pour déplacer les coordonnées de départ vers d'autres endroits ou pour tracer des chemins discontinus. Regardez le visage souriant ci-dessous. La ligne rouge est la trajectoire déplacée à l'aide de moveTo.
ctx.beginPath(); ctx.arc(75,75,50,0,Math.PI*2,true); // Outer circle ctx.moveTo(110,75); ctx.arc(75,75,35,0,Math.PI,false); // Mouth (clockwise) ctx.moveTo(65,65); ctx.arc(60,65,5,0,Math.PI*2,true); // Left eye ctx.moveTo(95,65); ctx.arc(90,65,5,0,Math.PI*2,true); // Right eye ctx.stroke(); ctx.beginPath(); ctx.moveTo(40,75); ctx.lineTo(60,65); ctx.lineTo(90,65); ctx.moveTo(110,75); ctx.lineTo(125,75); ctx.stroke();
我们用lineTo方法来画直线。lineTo方法接受终点的坐标(x,y)作为参数。起始坐标取决于前一路径,前一路径的终点即当前路径的起点,起始坐标也可以通过moveTo方法来设置。示例(如下图)画的是两个三角形,一个实色填充,一个勾边。首先调用beginPath方法创建一个新路径,然后用moveTo方法将起始坐标移至想要的位置,然后画两条直线来构成三角形的两条边。
// 填充三角形 ctx.beginPath(); ctx.moveTo(25,25); ctx.lineTo(105,25); ctx.lineTo(25,105); ctx.fill(); // 勾边三角形 ctx.beginPath(); ctx.moveTo(125,125); ctx.lineTo(125,45); ctx.lineTo(45,125); ctx.closePath(); ctx.stroke();
弧线 Arcs
我们用arc方法来绘制弧线或圆。标准说明中还包含arcTo方法,当前 Safari 是支持的,但基于 Gecko 的浏览器还未实现。方法接受五个参数:x,y 是圆心坐标,radius 是半径,startAngle和endAngle分别是起末弧度(以 x 轴为基准),anticlockwise为 true 表示逆时针,反之顺时针。警告:在 Firefox 的 beta 版本里,最后一个参数是clockwise,而最终版本不是。因此如果是从 beta 升级至发行版需要做相应修改。
注意:arc方法里用到的角度是以弧度为单位而不是度。度和弧度直接的转换可以用这个表达式:var radians = (Math.PI/180)*degrees;。
arc(x, y, radius, startAngle, endAngle, anticlockwise)
arc
的使用示例
这个示例比之前见到过的要复杂一些,画了12个不同的弧形,有不同夹角和填充状态的。如果我用上面画笑脸的方式来画这些弧形,那会是一大段的代码,而且, 画每一个弧形时我都需要知道其圆心位置。像我这里画 90,180 和 270 度的弧形看起来不是很麻烦,但是如果图形更复杂一些,则实现起来会越来越困难。这里使用两个for
循环来画多行多列的弧形。每一个弧形都用beginPath方法创建一个新路径。然后为了方便阅读和理解,我把所有参数都写成变量形式。显而易见,x 和 y 作为圆心坐标。radius和startAngle都是固定,endAngle从 180 度半圆开始,以 90 度方式递增至圆。anticlockwise则取决于奇偶行数。最后,通过 if语句判断使前两行表现为勾边,而后两行为填充效果。
for (i=0;i<4;i++){ for(j=0;j<3;j++){ //chinese_xu 原始代码 ctx.beginPath(); var x = 25+j*50; // x coordinate var y = 25+i*50; // y coordinate var radius = 20; // Arc radius var startAngle = 0; // Starting point on circle var endAngle = Math.PI+(Math.PI*j)/2; // End point on circle ---//修复错误标点 var anticlockwise = i%2==0 ? false : true; // clockwise or anticlockwise ctx.arc(x,y,radius,startAngle,endAngle, anticlockwise); if (i>1){ ctx.fill(); } else { ctx.stroke(); } } } //chinese_xu 原始代码并没有按照1/4圆递增来画。 //修改后输出4行4列,要把画布扩大到200*200观看 for (i=0;i<4;i++){ for(j=0;j<4;j++){ ctx.beginPath(); var x = 25+j*50; // x coordinate var y = 25+i*50; // y coordinate var radius = 20; // Arc radius var startAngle = 0; // Starting point on circle var endAngle = Math.PI*(2-j/2); // End point on circle var anticlockwise = i%2==0 ? false : true; // clockwise or anticlockwise ctx.arc(x,y,radius,startAngle,endAngle, anticlockwise); if (i>1){ ctx.fill(); } else { ctx.stroke(); } } }
以上就是canvas游戏开发学习之二:绘制基本图形的内容,更多相关内容请关注PHP中文网(www.php.cn)!