[30 minutes] completion canvas animation | game basis (2): scratch painting

Foreword

The first part is an overview of the main theories herein, this will be more of these practices, basic usage Laijiangjiang canvas and contains some basic trigonometric functions of the application, no canvas recommendation based on friends to read, familiar friends can be skipped.
They have limited ability to welcome people to discuss cattle, criticism.

Draw it together

There are a lot of canvas API, enumerated 30 minutes if you are absolutely endless, and see for yourself how the document might as running account of it (laughs), the idea of this tutorial is a step by step example to explain the basic usage from scratch .
canvas Related Documents

Ready to work

  1. Canvas arrangement: by adding <canvas>a tag, add canvas element;
  2. Gets canvas: by <canvas>id tags, get canvas objects;
  3. Get the brush: getContext ( "2d") through the canvas object methods, to obtain 2D environment.
<canvas id="canvas" width="400" height="400"></canvas>
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');

Draw arrows

First, we draw the red edge of the bottom yellow arrows , using object-oriented code organization, all the code as follows.
Class named Arrow. It has the x coordinate, y coordinate axis, the end of the color color, rotation arc of rotation of four attributes.
Examples of methods draw (), which requires a context object as a parameter, it is ready to work in the context, it is equivalent to a paintbrush, there is in fact similar to the dependency injection process, the canvas brush to draw the instance () method, examples of using this brush to draw an arrow, the process of painting see code comments. Pay particular attention to the following points:

  • beginPath () method call after moveTo () and lineTo coordinates are moved relative to the brush when the coordinate beginPath) (a , be appreciated that the brush comes into a coordinate system, it can be rotated and moved in the canvas coordinate work are plotted belong to this coordinate system;
  • calling the beginPath () is the starting point of the drawing set state, it draws a state after the code is provided in the end of the scope drawing method stroke (), fill () or the closePath ();
  • Effect save () is to preserve the state pen, because only a canvas of a pen, will be delivered in different subjects, in order not to contaminate subsequent painting should first save, unfinished and then restore () reduction;
  • <canvas>Itself is transparent , you can use CSS to give it a background example commonly used white background.
/**
 * 箭头类
 * @class Representing a arrow.
 */
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "Arrow" }] */
class Arrow {
  /**
    * Create a arrow.
    */
  constructor() {
    this.x = 0;
    this.y = 0;
    this.color = '#ffff00';
    this.rotation = 0;
  }
  /**
   * Draw the arrow.
   * @param {Object} _context - The canvas context.
   */
  draw(_context) {
    const context = _context;
    // 会先保存画笔状态
    context.save();
    // 移动画笔
    context.translate(this.x, this.y);
    // 旋转画笔
    context.rotate(this.rotation);
    // 设置线条宽度
    context.lineWidth = 2;
    // 设置线条颜色
    context.strokeStyle = '#ff0000';
    // 设置填充颜色
    context.fillStyle = this.color;
    // 开始路径
    context.beginPath();
    // 将笔移动到相对位置
    context.moveTo(-50, -25);
    // 画线到相对位置
    context.lineTo(0, -25);
    context.lineTo(0, -50);
    context.lineTo(50, 0);
    context.lineTo(0, 50);
    context.lineTo(0, 25);
    context.lineTo(-50, 25);
    context.lineTo(-50, -25);
    // 闭合路径
    context.closePath();
    // 填充路径包围区
    context.fill();
    // 绘制路径
    context.stroke();
    // 载入保存的笔信息
    context.restore();
  }
}

Similarly we can also draw something else, such as a round ball.js , a little more of these parameters, slowly understanding.
This effect can look finished (slight spoilers): a position of the mouse arrow tracks

Join circulation moving up

Now that we have mastered the basic skills of painting, and you can draw arrows arrow.js and round ball.js , but it just still pictures, then we need a loop, constantly erasing and redrawing of work to achieve frame animation .
In drawing functions drawFrame following piece of code is executed immediately, and calls itself recursively, you'll see in most cases.
On the principle of a cycle already described will not be repeated. It is noted that herein the clearRect (), this function takes a rectangle coordinates, i.e. (x-coordinate axis, y-axis coordinates, rectangular width and height of the rectangle), for removing painted within a rectangular region.
Examples are in direct clearing the entire canvas, but this is not absolute, brush does not refresh, or a partial refresh to refresh all, need to be flexible.
There is not a refreshing example: mouse drawing tool

(function drawFrame() {
  // 类似setTimeout的操作
  window.requestAnimationFrame(drawFrame, canvas);
  // 将画布擦干净
  context.clearRect(0, 0, canvas.width, canvas.height);
  // ...继续你的作画
}());

Give it some power

Now the picture has been constantly redrawn, but why is it still? Because nothing has changed content to draw every refresh.
It is a goal that we gave it, so that it can move, for example, let the arrow always points the mouse.
The following is the core code, the main purpose is to obtain the rotation angle of each frame of the arrow, the tools used herein mouse mouse returns in real time x, y-axis coordinates, the principles of a package already said, this mouse coordinates and the arrow according to coordinates, the mouse can be obtained with respect to the arrow distance dx and Dy, as shown below:

Arrow angle demo

I.e., the rotation angle of the arrow arctangent function can be obtained by using the dx and dy, where points to note:

  • Look carefully arrow in the drawing process in the above code, whose origin is found in the central position, the angle of rotation is just the rotation angle of the brush;
  • dx and dy are the coordinates of the mouse relative to the arrow, so the figures to move the arrow center coordinates are not illnesses;
  • Atan2 using, instead of atan, because the value of tan already may be duplicated, such as 1/2, and 1 / (- 2) are two -0.5, indistinguishable quadrant, and atan2 can be distinguished.

Complete example: a track the position of the mouse arrow

window.onload = function () {
  const canvas = document.getElementById('canvas');
  const context = canvas.getContext('2d');
  const mouse = utils.captureMouse(canvas);
  const arrow = new Arrow();

  arrow.x = canvas.width / 2;
  arrow.y = canvas.height / 2;

  (function drawFrame() {
    window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, canvas.width, canvas.height);
    const dx = mouse.x - arrow.x;
    const dy = mouse.y - arrow.y;

    arrow.rotation = Math.atan2(dy, dx);
    arrow.draw(context);
  }());
};

Trigonometric functions

Down movement

Finally a smooth transition to the topic of trigonometric functions (laughs). Arctangent trigonometric there is more than one application, a look at the following example.
The following is a ball in the up and down movement of the core code, is focused on the y-axis coordinates change ball, it is the phrase:

ball.y = clientY + Math.sin(angle) * range;

Math.sin, using (angle) is in the range -1 to 1, as angle increases and will be repeated, so that the upper and lower ball movement range.
Complete example: a down movement of the ball (tunable version)

window.onload = function () {
  const canvas = document.getElementById('canvas');
  const context = canvas.getContext('2d');
  const ball = new Ball();
  let angle = 0;
  // 运动中心
  const clientY = 200;
  // 范围
  const range = 50;
  // 速度
  const speed = 0.05;

  ball.x = canvas.width / 2;
  ball.y = canvas.height / 2;

  (function drawFrame() {
    window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, canvas.width, canvas.height);

    ball.y = clientY + Math.sin(angle) * range;
    angle += speed;
    ball.draw(context);
  }());
};

Forward movement

Just move up and down quickly, let the round go forward, in fact, is to change the position of the x-axis of each frame.
Core code is as follows, compared to the front of the vertical movement, a multi-speed x-axis, each frame is formed move a little forward wave effect.
Complete example: a wave motion of the ball

window.onload = function () {
  const canvas = document.getElementById('canvas');
  const context = canvas.getContext('2d');
  const ball = new Ball();
  let angle = 0;
  const centerY = 200;
  const range = 50;
  const xspeed = 1;
  const yspeed = 0.05;

  ball.x = 0;
  (function drawFrame() {
    window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, canvas.width, canvas.height);
    ball.x += xspeed;
    ball.y = centerY + Math.sin(angle) * range;
    angle += yspeed;
    ball.draw(context);
  }());
};

Other examples

Other applications can not explain one by one, set out some of them:

Guess you like

Origin www.cnblogs.com/homehtml/p/11963842.html