This article will cover some canvas related drawing techniques, including:
- Drawing API
- Image to load
- Pixel processing
Drawing API
The related API can be referenced, but I won’t go into detail here.
- CanvasRenderingContext2D
Here are some examples
The mouse drawing
The code is as follows:
<canvas id="mainCanvas" style="background-color: #fff;" width="800" height="400"></canvas>
Copy the code
const canvas: HTMLCanvasElement | null = document.querySelector('#mainCanvas')
if (canvas) {
const context = canvas.getContext('2d')
if (context) {
const { offsetLeft, offsetTop } = canvas
let x
let y
const mouseMoveHandler = (e: MouseEvent) = > {
x = e.pageX
y = e.pageY
x -= offsetLeft
y -= offsetTop
context.lineTo(x, y)
context.lineCap = 'round'
context.lineJoin = 'round'
context.stroke()
}
canvas.addEventListener('mousedown'.(e) = > {
context.beginPath()
context.moveTo(e.pageX - offsetLeft, e.pageY - offsetTop)
canvas.addEventListener('mousemove', mouseMoveHandler)
})
canvas.addEventListener('mouseup'.() = > {
canvas.removeEventListener('mousemove', mouseMoveHandler)
})
}
}
Copy the code
Results the following
The demo link gaohaoyang. Making. IO/canvas – prac…
Source link github.com/Gaohaoyang/…
Draw the curve
Quadratic Bezier curve
Specific apis can reference documentation CanvasRenderingContext2D. QuadraticCurveTo ()
ctx.quadraticCurveTo(cpx, cpy, x, y);
Copy the code
It takes 2 points. The first point is the control point and the second point is the end point. The starting point is the most recent point of the current path, which can be changed using the moveTo() method before creating a quadratic Bezier curve.
The next step is to implement a demo that uses the mouse position as the control point to control the quadratic Bezier curve.
const canvas: HTMLCanvasElement | null = document.querySelector('#mainCanvas')
if (canvas) {
const context = canvas.getContext('2d')
const { offsetLeft, offsetTop } = canvas
const x0 = 300
const y0 = 100
const x1 = 600
const y1 = 300
if (context) {
canvas.addEventListener('mousemove'.(e) = > {
context.clearRect(0.0, canvas.width, canvas.height)
const x = e.pageX - offsetLeft
const y = e.pageY - offsetTop
context.beginPath()
context.moveTo(x0, y0)
context.quadraticCurveTo(x, y, x1, y1)
context.stroke()
})
}
}
Copy the code
Results the following
The demo link gaohaoyang. Making. IO/canvas – prac…
Source link github.com/Gaohaoyang/…
Quadratic Bezier curves through control points
const canvas: HTMLCanvasElement | null = document.querySelector('#mainCanvas')
if (canvas) {
const context = canvas.getContext('2d')
const { offsetLeft, offsetTop } = canvas
const x0 = 300
const y0 = 100
const x1 = 600
const y1 = 300
if (context) {
canvas.addEventListener('mousemove'.(e) = > {
context.clearRect(0.0, canvas.width, canvas.height)
const x = e.pageX - offsetLeft
const y = e.pageY - offsetTop
const cpx = x * 2 - (x0 + x1) / 2
const cpy = y * 2 - (y0 + y1) / 2
context.beginPath()
context.moveTo(x0, y0)
context.quadraticCurveTo(cpx, cpy, x1, y1)
context.stroke()
})
}
}
Copy the code
Its core is
const cpx = x * 2 - (x0 + x1) / 2
const cpy = y * 2 - (y0 + y1) / 2
Copy the code
Results the following
The demo link gaohaoyang. Making. IO/canvas – prac…
Source link github.com/Gaohaoyang/…
More curves
Draw a smooth curve, controlled by multiple points
import Ball from '.. /common/Ball'
const canvas: HTMLCanvasElement | null = document.querySelector('#mainCanvas')
if (canvas) {
const ctx = canvas.getContext('2d')
if (ctx) {
const points = []
const num = 4
for (let i = 0; i < num; i += 1) {
const ball = new Ball(2)
const x = Math.random() * canvas.width
const y = Math.random() * canvas.height
points.push({
x,
y,
})
ball.x = x
ball.y = y
ball.draw(ctx)
}
ctx.beginPath()
ctx.moveTo(points[0].x, points[0].y)
for (let i = 1; i < num - 2; i += 1) {
const xAv = (points[i].x + points[i + 1].x) / 2
const yAv = (points[i].y + points[i + 1].y) / 2
ctx.quadraticCurveTo(points[i].x, points[i].y, xAv, yAv)
}
ctx.quadraticCurveTo(points[num - 2].x, points[num - 2].y, points[num - 1].x, points[num - 1].y)
ctx.stroke()
}
}
Copy the code
The xAv and yAv edges are set to the average of the x and y coordinates of the current and subsequent points in the loop, so that a smooth curve can be drawn
Results the following
The demo link gaohaoyang. Making. IO/canvas – prac…
Source link github.com/Gaohaoyang/…
A closed curve
import Ball from '.. /common/Ball'
const canvas: HTMLCanvasElement | null = document.querySelector('#mainCanvas')
if (canvas) {
const ctx = canvas.getContext('2d')
if (ctx) {
const points = []
const num = 4
for (let i = 0; i < num; i += 1) {
const ball = new Ball(2)
const x = Math.random() * canvas.width
const y = Math.random() * canvas.height
points.push({
x,
y,
})
ball.x = x
ball.y = y
ball.draw(ctx)
}
const xAv1 = (points[0].x + points[num - 1].x) / 2
const yAv1 = (points[0].y + points[num - 1].y) / 2
ctx.beginPath()
ctx.moveTo(xAv1, yAv1)
for (let i = 0; i < num - 1; i += 1) {
const xAv = (points[i].x + points[i + 1].x) / 2
const yAv = (points[i].y + points[i + 1].y) / 2
ctx.quadraticCurveTo(points[i].x, points[i].y, xAv, yAv)
}
ctx.quadraticCurveTo(points[num - 1].x, points[num - 1].y, xAv1, yAv1)
ctx.stroke()
}
}
Copy the code
The demo link gaohaoyang. Making. IO/canvas – prac…
Source link github.com/Gaohaoyang/…
Graphics and fill colors
Generally speaking, the drawing order is as follows:
- BeginPath Begins to draw
- MoveTo moves the starting point
- Graphics.linestyle line style
- FillStyle fillStyle
- LineTo, quadraticCurveTo, etc
- ClosePath closed
- The fill to fill
- Stroke stroke
gradient
ctx.createLinearGradient(x0, y0, x1, y1)
The createLinearGradient() method requires you to specify four parameters representing the start and end points of the gradient line segment.
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
Arc () is the Canvas 2D API’s method for drawing arc paths. The arc path has a center at (x, y), radius r, and starts with startAngle and ends with endAngle in the direction specified by AnticLockWise (which defaults to clockwise).
const canvas: HTMLCanvasElement | null = document.querySelector('#mainCanvas')
if (canvas) {
const ctx = canvas.getContext('2d')
if (ctx) {
ctx.beginPath()
const gradient = ctx.createLinearGradient(100.100.200.200)
gradient.addColorStop(0.'#ff0000')
gradient.addColorStop(1.'# 000000')
ctx.fillStyle = gradient
ctx.fillRect(100.100.100.100)
const gradient2 = ctx.createLinearGradient(200.200.300.300)
gradient2.addColorStop(0.'#ff0000')
gradient2.addColorStop(0.6.'# 008880')
gradient2.addColorStop(1.'# 000000')
ctx.fillStyle = gradient2
ctx.fillRect(200.200.100.100)
const gradient3 = ctx.createRadialGradient(500.200.0.500.200.100)
gradient3.addColorStop(0.'# 000000')
gradient3.addColorStop(1.'#ff0000')
ctx.arc(500.200.100.0.2 * Math.PI)
ctx.fillStyle = gradient3
ctx.fill()
}
}
Copy the code
The effect is as follows:
The demo link gaohaoyang. Making. IO/canvas – prac…
Source link github.com/Gaohaoyang/…
Image to load
For some scenarios, you may need to draw an image inside the canvas. Let’s look at how to draw the image
Draw pictures
const canvas: HTMLCanvasElement | null = document.querySelector('#mainCanvas')
if (canvas) {
const ctx = canvas.getContext('2d')
if (ctx) {
const img = new Image()
img.src = 'https://gw.alicdn.com/imgextra/i2/O1CN01gR6ymq1dfV5RmYxYk_!! 6000000003763-2-tps-658-411.png'
img.addEventListener('load'.() = > {
ctx.drawImage(img, 0.0.658.329.0.0.800.400)}}}Copy the code
Results the following
The demo link gaohaoyang. Making. IO/canvas – prac…
Source link github.com/Gaohaoyang/…
Operate pixels
Let’s try removing all the green pixels from the demo above and see what happens
const canvas: HTMLCanvasElement | null = document.querySelector('#mainCanvas')
if (canvas) {
const ctx = canvas.getContext('2d')
if (ctx) {
const img = new Image()
img.src = '.. /assets/1.png'
img.addEventListener('load'.() = > {
ctx.drawImage(img, 0.0.658.329.0.0, canvas.width, canvas.height)
const imageData = ctx.getImageData(0.0, canvas.width, canvas.height)
const pixels = imageData.data
for (let i = 0; i < pixels.length; i += 4) {
pixels[i + 1] = 0
}
ctx.putImageData(imageData, 0.0)}}}Copy the code
The effect is as follows:
The demo link gaohaoyang. Making. IO/canvas – prac…
Source link github.com/Gaohaoyang/…
conclusion
This article doesn’t cover much animation, but it does give you an example of how to draw on Canvas 2D, and shows you how to load images and manipulate pixels. This set the foundation for the following animation learning.