In this part
[Transformations,
Compositions
Animations
Pixel Manipulation]
Transformations
Recall some methods
First, we will need to recall the two methods that were mentioned in the last chapter.
save - saves the current state at the top of the stack
restore - sets the state from the top of the stack
The state should be understood: transformation matrix, drawing area, and the following properties: strokeStyle, fillStyle globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline.
Displace
translate(float x, float y)
- let's shift the current position of the origin of coordinates by x and y from the previous position.
Consider the following example:
ctx.save()
Turn

rotate(float angle)
- rotates the x-axis and ordinate angle angle, also do not forget that the angle is measured in radians, to convert the angle to radians from degrees, multiply degrees by Pi and divide by 180, that is: rad = deg * Math.PI // 180
For example, add a line after ctx.translate (100,100): ctx.rotate (45 * Math.PI / 180)
Reduce / increase

scale(float x, float y)
- will apply the new scale to the x and y axes.
For example, replace ctx.rotate (45 * Math.PI / 180) with ctx.scale (0.65,1.5)
Multiply the matrix
transform(float m11, float m12, float m21, float m22, float dx , float dy)
- multiply the old matrix to the new matrix.
Apply the matrix

setTransform(float m11, float m12, float m21, float m22, float dx , float dy)
- Apply a new matrix, for example, look at the following code.
var img = new Image(); img.onload = function(){ ctx.save() ctx.setTransform(1,0.5,0,1,1,1) ctx.drawImage(img,0,0,78,50) ctx.restore() } img.src = 'brick.jpg';
I used a brick wall picture and a
shearing transformation .
In addition, the transformations can be read in more detail in the
topic from Nutochka')
Compositions
Types of composition operations

The globalCompositeOperation property is responsible for the type of composition operation, we could paint all its possible values, but there is a
Canvas Cheat Sheet and it is better to show a part of the picture, a blue rectangle was drawn first, and a red circle second and depending on the value of globalCompositeOperation we will get different results .
GlobalAlpha property

The globalAlpha property is actually a multiplier by which the transparency of each image is multiplied, while only if 0 <= globalAlpha <= 1. For example, consider the code:
ctx.globalAlpha = 0.6; ctx.fillRect(0,0,100,100) ctx.fillRect(50,50,100,100)
Animation
requestAnimationFrame
If earlier timers were used for animation, now a special function called requestAnimationFrame has appeared, the topic is already covered so it is better to read the
translation from azproduction .
The basic principle of animation
The basic principle of animation is to erase the old frame and draw a new one. To erase the old frame is the easiest to use the clearRect function. For example, consider the following code. First, add the requestAnimationFrame definition to your code:
var x = 400, y = 300; (function loop(){ ctx.clearRect(0,0,800,600); ctx.beginPath(); ctx.arc(x++,y++,50,0,Math.PI*2,false); ctx.fill() requestAnimFrame(loop); })();
Also about animation can be read in the
topic from trickii
1 game! = 1 canvas
I saw this rule in the canvas acceleration presentation and realized that this is the simplest rule.
Instead of drawing complex images with each frame, you can save this image into a virtual canvas and then draw it with each frame, but however it is worth noting that you don’t have to shove everything into a virtual canvas, you only have to push shapes that are really difficult to draw (for example, text or gradient ).
For example, I did a small test on jsperf.com , not ideal, but I think the meaning is clear.
Manipulate pixels
Apart from high-level methods, canvas also has full access to pixels, using it you can create wonderful things (I mean filters and the like), and also draw simple things very quickly. There is a special type of ImageData for working with pixels, it has three properties, width, height (I think it doesn’t need to be explained) and data is an array of r, g, b, a values for each pixel.
How pixel data is stored

Data about the pixels as previously stated is stored in an array, while the number of elements in the array is equal to the number of pixels multiplied by 4. All elements take values in the range 0..255.
Including the alpha channel stored in values from 0..255. The picture shows that the four values of r, g, b, a form a segment, the segment in turn is a single indivisible cell storing the parameters of one pixel.
Creating an empty ImageData
ImageData = context.createImageData(int w, int h)
- creates an empty ImageData with width and height w and h, respectively.
ImageData = context.createImageData(imageData)
- create an empty ImageData with the width and height of the transferred imageData, note: the data is not copied.
Application ImageData
context.putImageData(imageData imgd, int x, int y)
- will change the array of pixels of the canvas in the area from the point xy with the width and height of imageData.
Simple example
But enough of the theory, let's get down to business, let's try to draw a graph of the function y = x * x, without smoothing:
var imgd = ctx.createImageData(800, 600); var x,y,segment,xround,yround; for (x=-40 ; x<=40 ; x+=0.01) { y = x*x; xround = ~~(x+0.5); yround = ~~(y+0.5); segment = ((-yround+400)*imgd.width + xround + 40)*4; imgd.data[segment+3] = 255; } ctx.putImageData(imgd, 0, 0);
To compare performance, I wrote similar
code using fillRect, again on jsperf , however, to draw one point, it is better to use fillRect since creating imageData also takes resources.
Manipulation of image pixels

ImageData = context.createImageData(int x, int y, int w, int h)
- returns an imageData object with data from canvas in a rectangular area with a left top vertex at (x; y) and a width, height w and h, respectively. For example, let's try to highlight white areas in a photo:
var img = new Image(); img.src = 'test.jpg';