Bezier and quadratic curves
The path to be introduced next is the Bezier curve, which can be in the form of quadratic and cubic, and is generally used Draw complex and regular shapes.
quadraticCurveTo(cp1x, cp1y, x, y) // BROKEN in Firefox 1.5 (see work around below) bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
The difference between the above two lines of code is shown in the picture on the right. They both have a starting point and an ending point (the blue point in the picture), but a quadratic Bezier curve has only one (red) control point (point) while a cubic Bezier curve has two. Parameters x and y are the coordinates of the end point, cp1x and cp1y are the coordinates of the first control point, and cp2x and cp2y are the second.
Working with quadratic and cubic Bezier curves is quite challenging because there is no immediate visual feedback like in the vector drawing software Adobe Illustrator. Because it is more troublesome to use it to draw complex graphics. But if you have time, and most importantly, patience, you can draw even complex graphics. Let's draw a simple and regular graph below. These examples are relatively simple. What we draw are complete graphs.
// Quadratric curves example ctx.beginPath(); ctx.moveTo(75,25); ctx.quadraticCurveTo(25,25,25,62.5); ctx.quadraticCurveTo(25,100,50,100); ctx.quadraticCurveTo(50,120,30,125); ctx.quadraticCurveTo(60,120,65,100); ctx.quadraticCurveTo(125,100,125,62.5); ctx.quadraticCurveTo(125,25,75,25); ctx.stroke();
Through calculation, two control points of the corresponding cubic curve can be obtained from a single control point of the quadratic curve, so it is possible to convert the quadratic to the cubic , but the opposite is not true. Conversion to a quadratic Bezier curve is only possible if the cubic term in the cubic equation is zero. Usually, multiple quadratic curves can be used to approximate the cubic Bezier curve through a subdivision algorithm.
// Bezier curves example ctx.beginPath(); ctx.moveTo(75,40); ctx.bezierCurveTo(75,37,70,25,50,25); ctx.bezierCurveTo(20,25,20,62.5,20,62.5); ctx.bezierCurveTo(20,80,40,102,75,120); ctx.bezierCurveTo(110,102,130,80,130,62.5); ctx.bezierCurveTo(130,62.5,130,25,100,25); ctx.bezierCurveTo(85,25,75,37,75,40); ctx.fill();
Rectangle PathRectangles
In addition to the three methods mentioned above that can directly draw rectangles, we also have a rect method for drawing Rectangular path.
rect(x, y, width, height)
It accepts four parameters, x and y are the coordinates of its upper left corner, width and height are its width and height. When it is called, the moveTo method will be called automatically with the parameter (0,0), so the starting coordinates are restored to the initial origin.
Comprehensive Example
In the entire example, the most noteworthy is the use of the roundedRect function and the setting of the fillStyle attribute. Custom functions are very useful for encapsulating the drawing of complex graphics. Using a custom function in this example saves about half the code. The use of the fillStyle attribute will be discussed in depth in the following examples. Here it is used to change the fill color from the default black, to white, and back to black.
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); roundedRect(ctx,12,12,150,150,15); roundedRect(ctx,19,19,150,150,9); roundedRect(ctx,53,53,49,33,10); roundedRect(ctx,53,119,49,16,6); roundedRect(ctx,135,53,49,33,10); roundedRect(ctx,135,119,25,49,10); ctx.beginPath(); ctx.arc(37,37,13,Math.PI/7,-Math.PI/7,false); //chiensexu 本来是true呵呵,反了 ctx.lineTo(31,37); ctx.fill(); for(i=0;i<8;i++){ ctx.fillRect(51+i*16,35,4,4); } for(i=0;i<6;i++){ ctx.fillRect(115,51+i*16,4,4); } for(i=0;i<8;i++){ ctx.fillRect(51+i*16,99,4,4); } ctx.beginPath(); ctx.moveTo(83,116); ctx.lineTo(83,102); ctx.bezierCurveTo(83,94,89,88,97,88); ctx.bezierCurveTo(105,88,111,94,111,102); ctx.lineTo(111,116); ctx.lineTo(106.333,111.333); ctx.lineTo(101.666,116); ctx.lineTo(97,111.333); ctx.lineTo(92.333,116); ctx.lineTo(87.666,111.333); ctx.lineTo(83,116); ctx.fill(); ctx.fillStyle = "white"; ctx.beginPath(); ctx.moveTo(91,96); ctx.bezierCurveTo(88,96,87,99,87,101); ctx.bezierCurveTo(87,103,88,106,91,106); ctx.bezierCurveTo(94,106,95,103,95,101); ctx.bezierCurveTo(95,99,94,96,91,96); ctx.moveTo(103,96); ctx.bezierCurveTo(100,96,99,99,99,101); ctx.bezierCurveTo(99,103,100,106,103,106); ctx.bezierCurveTo(106,106,107,103,107,101); ctx.bezierCurveTo(107,99,106,96,103,96); ctx.fill(); ctx.fillStyle = "black"; ctx.beginPath(); ctx.arc(101,102,2,0,Math.PI*2,true); ctx.fill(); ctx.beginPath(); ctx.arc(89,102,2,0,Math.PI*2,true); ctx.fill(); } function roundedRect(ctx,x,y,width,height,radius){ ctx.beginPath(); ctx.moveTo(x,y+radius); ctx.lineTo(x,y+height-radius); ctx.quadraticCurveTo(x,y+height,x+radius,y+height); ctx.lineTo(x+width-radius,y+height); ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius); ctx.lineTo(x+width,y+radius); ctx.quadraticCurveTo(x+width,y,x+width-radius,y); ctx.lineTo(x+radius,y); ctx.quadraticCurveTo(x,y,x,y+radius); ctx.stroke(); }
The above is the third part of canvas game development learning: drawing complex shapes. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!