- Introduction
- Chapter 1 Values, Types, and Operators
- Chapter 2 Program Structure
- Expressions and statements
- Variables
- Keywords and reserved words
- The environment
- Functions
- The console.log function
- Return values
- prompt and confirm
- Control flow
- Conditional execution
- while and do loops
- Indenting Code
- for loops
- Breaking Out of a Loop
- Updating variables succinctly
- Dispatching on a value with switch
- Capitalization
- Comments
- Summary
- Exercises
- Chapter 3 Functions
- Chapter 4 Data Structures: Objects and Arrays
- Chapter 5 Higher-Order Functions
- Chapter 6 The Secret Life of Objects
- Chapter 7 Project: Electronic Life
- Chapter 8 Bugs and Error Handling
- Chapter 9 Regular Expressions
- Creating a regular expression
- Testing for matches
- Matching a set of characters
- Repeating parts of a pattern
- Grouping subexpressions
- Matches and groups
- The date type
- Word and string boundaries
- Choice patterns
- The mechanics of matching
- Backtracking
- The replace method
- Greed
- Dynamically creating RegExp objects
- The search method
- The lastIndex property
- Parsing an INI file
- International characters
- Summary
- Exercises
- Chapter 10 Modules
- Chapter 11 Project: A Programming Language
- Chapter 12 JavaScript and the Browser
- Chapter 13 The Document Object Model
- Chapter 14 Handling Events
- Chapter 15 Project: A Platform Game
- Chapter 16 Drawing on Canvas
- Chapter 17 HTTP
- Chapter 18 Forms and Form Fields
- Chapter 19 Project: A Paint Program
- Chapter 20 Node.js
- Chapter 21 Project: Skill-Sharing Website
- Eloquent JavaScript
- Exercise Hints
- Program Structure
- Functions
- Data Structures: Objects and Arrays
- Higher-Order Functions
- The Secret Life of Objects
- Project: Electronic Life
- Bugs and Error Handling
- Regular Expressions
- Modules
- Project: A Programming Language
- The Document Object Model
- Handling Events
- Project: A Platform Game
- Drawing on Canvas
- HTTP
- Forms and Form Fields
- Project: A Paint Program
- Node.js
- Project: Skill-Sharing Website
Drawing on Canvas
Shapes
The trapezoid (1) is easy to draw using a path. Pick suitable center coordinates and add each of the four corners around that.
The diamond (2) can be drawn the easy way, with a path, or the interesting way, with a rotate
transformation. To use rotation, you will have to apply a trick similar to what we did in the flipHorizontally
function. Because you want to rotate around the center of your rectangle and not around the point (0,0), you must first translate
to there, then rotate, and then translate back.
For the zigzag (3) it becomes impractical to write a new call to lineTo
for each line segment. Instead, you should use a loop. You can have each iteration draw either two line segments (right and then left again) or one, in which case you must use the evenness ( % 2
) of the loop index to determine whether to go left or right.
You’ll also need a loop for the spiral (4). If you draw a series of points, with each point moving further along a circle around the spiral’s center, you get a circle. If, during the loop, you vary the radius of the circle on which you are putting the current point and go around more than once, the result is a spiral.
The star (5) depicted is built out of quadraticCurveTo
lines. You could also draw one with straight lines. Divide a circle into eight pieces, or a piece for each point you want your star to have. Draw lines between these points, making them curve toward the center of the star. With quadraticCurveTo
, you can use the center as the control point.
The pie chart
You will need to call fillText
and set the context’s textAlign
and textBaseline
properties in such a way that the text ends up where you want it.
A sensible way to position the labels would be to put the text on the line going from the center of the pie through the middle of the slice. You don’t want to put the text directly against the side of the pie but rather move the text out to the side of the pie by a given number of pixels.
The angle of this line is currentAngle + 0.5 * sliceAngle
. The following code finds a position on this line, 120 pixels from the center:
var middleAngle = currentAngle + 0.5 * sliceAngle; var textX = Math.cos(middleAngle) * 120 + centerX; var textY = Math.sin(middleAngle) * 120 + centerY;
For textBaseline
, the value "middle"
is probably appropriate when using this approach. What to use for textAlign
depends on the side of the circle we are on. On the left, it should be "right"
, and on the right, it should be "left"
so that the text is positioned away from the pie.
If you are not sure how to find out which side of the circle a given angle is on, look to the explanation of Math.cos
in the previous exercise. The cosine of an angle tells us which x-coordinate it corresponds to, which in turn tells us exactly which side of the circle we are on.
A bouncing ball
A box is easy to draw with strokeRect
. Define a variable that holds its size or define two variables if your box’s width and height differ. To create a round ball, start a path, call arc(x, y, radius, 0, 7)
, which creates an arc going from zero to more than a whole circle, and fill it.
To model the ball’s position and speed, you can use the Vector
type from Chapter 15 . Give it a starting speed, preferably one that is not purely vertical or horizontal, and every frame, multiply that speed with the amount of time that elapsed. When the ball gets too close to a vertical wall, invert the x component in its speed. Likewise, invert the y component when it hits a horizontal wall.
After finding the ball’s new position and speed, use clearRect
to delete the scene and redraw it using the new position.
Precomputed mirroring
The key to the solution is the fact that we can use a canvas element as a source image when using drawImage
. It is possible to create an extra <canvas>
element, without adding it to the document, and draw our inverted sprites to it, once. When drawing an actual frame, we just copy the already inverted sprites to the main canvas.
Some care would be required because images do not load instantly. We do the inverted drawing only once, and if we do it before the image loads, it won’t draw anything. A "load"
handler on the image can be used to draw the inverted images to the extra canvas. This canvas can be used as a drawing source immediately (it’ll simply be blank until we draw the character onto it).
This is a book about getting computers to do what you want them to do. Computers are about as common as screwdrivers today, but they contain a lot more hidden complexity and thus are harder to operate and understand. To many, they remain alien, slightly threatening things.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论