Table of contents
1. Low-version browsers do not display canvas and give a prompt
2. Canvas is an inline element. If you want to center it, you need to turn it into a block element
1. Low-version browsers do not display canvas and give a prompt
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<!-- canvas在低版本中不兼容,需要提示用户 -->
<canvas width="500px" height="500px">您的浏览器版本过低,请升级浏览器或者使用chrome打开!</canvas>
</body>
</html>
If the canvas can be displayed, there will be no text prompt, and if the canvas is not displayed, the prompt text will be displayed
2. Canvas is an inline element. If you want to center it, you need to turn it into a block element
<!DOCTYPE html> <html lang="en"> <head> <style> canvas { display: block; margin: 0 auto; border: 1px solid #aaa; } </style> </head> <body> <!-- canvas在低版本中不兼容,需要提示用户 --> <canvas width="500px" height="500px">您的浏览器版本过低,请升级浏览器或者使用chrome打开!</canvas> </body> </html>
Effect:
3. Draw the line
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
// 只能使用原生js操作canvas, jq不可以
// 画一条线的步骤
//(1)获取画布
var canvas = document.querySelector("#cont");
//(2)获取画布的能力
var ctx = canvas.getContext("2d");
// (3)开始一条路径
ctx.beginPath();
// (4)确定起点
ctx.moveTo(100, 100);
// (5)确定结束点
ctx.lineTo(400, 400);
// 添加线宽和颜色 (这个必须在着色之前写)
// 设置颜色
ctx.strokeStyle = 'green'
// 设置线宽
ctx.lineWidth=5
// (6)着色
ctx.stroke();
// (7)结束路径
ctx.closePath();
</script>
</body>
</html>
Effect:
4. Draw a dotted line
grammar:
ctx.setLineDash([虚线长度, 虚线间隔])
drawLine(起始点的x坐标, 起始点的y坐标, 终点的x坐标, 终点的y坐标, 虚线的颜色 )
4. Draw a rectangle
rect(x, y, width, height) // 可描边、填充
fillRect(x, y, width, height) // 不可描边、只能填充
strokeRect(x, y, width, height) // 只能描边、不可填充
x | The x-coordinate of the upper left corner of the rectangle |
y | The y-coordinate of the upper-left corner of the rectangle |
width | The width of the rectangle, in pixels |
height | the height of the rectangle in pixels |
Note: Note that you need to fill and stroke first and then stroke , otherwise the fill will press the stroke
case:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
//(1)获取画布
var canvas = document.querySelector("#cont");
//(2)获取画布的能力
var ctx = canvas.getContext("2d");
/**
* rect(x, y, width, height) // 有描边也有填充
*/
ctx.rect(100, 100, 300, 200)
// 填充
ctx.fillStyle = "red"
ctx.fill();
// 描边
ctx.strokeStyle = 'blue'
ctx.lineWidth=5
ctx.stroke();
/**
* fillRect(x, y, width, heihgt) // 只能填充, 不可描边
*/
ctx.fillStyle = 'pink'
ctx.fillRect(100, 400, 100, 1000)
/**
* strokeRect(x, y, width, heihgt)
*/
ctx.strokeStyle= 'gold'
ctx.strokeRect(300, 400, 100, 100)
ctx.closePath();
</script>
</body>
</html>
Effect:
5. Clear the canvas
grammar:
clearRect(x, y, width, height)
case:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
//(1)获取画布
var canvas = document.querySelector("#cont");
//(2)获取画布的能力
var ctx = canvas.getContext("2d");
ctx.rect(100, 100, 300, 200)
// 填充
ctx.fillStyle = "red"
ctx.fill();
// 描边
ctx.strokeStyle = 'blue'
ctx.lineWidth=5
ctx.stroke();
// 清除画布
ctx.clearRect(120, 120,200, 100)
ctx.closePath();
</script>
</body>
</html>
Effect:
6. Draw a circle
grammar:
arc(x, y, radius, startAngle, endAngle, counterclockwise)
parameter
x | Center x coordinate |
y | Center y coordinate |
radius | radius |
startAngle | starting angle |
endAngle | end angle |
counterclockwise | true: counterclockwise, false: clockwise |
case:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
//(1)获取画布
var canvas = document.querySelector("#cont");
//(2)获取画布的能力
var ctx = canvas.getContext("2d");
ctx.arc(250, 250, 200, 0, Math.PI*2, false)
ctx.fillStyle = 'gold'
ctx.fill()
ctx.lineWidth = 10;
ctx.strokeStyle = 'red'
ctx.stroke()
ctx.closePath();
</script>
</body>
</html>
Effect:
7. Draw an arc
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
//(1)获取画布
var canvas = document.querySelector("#cont");
//(2)获取画布的能力
var ctx = canvas.getContext("2d");
ctx.beginPath()
ctx.arc(100, 100, 100, 0, Math.PI*1, true)
ctx.stroke()
ctx.beginPath() // 当前使用了新了一个beginPath() 所以上一个不需要closePath 因为他默认给你加上了
ctx.arc(300, 100, 100, 0, Math.PI*1, false)
ctx.stroke()
ctx.closePath();
</script>
</body>
</html>
Note: A new beginPath() is currently used, so the previous one does not need closePath because he added it to you by default
Eight, draw pictures
method one
// 在画布上定位图像
ctx.drawImage(img, x, y)
way two
// 在画布上定位图像 并规定图像的宽、高
ctx.drawImage(img, x, y, width, height)
way three
// 剪切图像,并在画布上定位被裁剪的部分
ctx.drawImage(img, sx, sy, swidth, sheight, x, y, width, height)
parameter:
img | Image, Canvas, Video to use |
sx | optional. x coordinate to start clipping |
and | optional. The y coordinate at which to start clipping |
swidth | optional. The width of the cropped image |
sheight | optional. The height of the clipped image |
x | x coordinate to place the image on the canvas |
y | The y coordinate to place the image on the canvas |
width | optional. The width of the image to use. (stretch or shrink image) |
height | optional. The height of the image to use. (stretch or shrink image) |
8. Case: Small ball hits the wall detection
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
//(1)获取画布
var canvas = document.querySelector("#cont");
//(2)获取画布的能力
var ctx = canvas.getContext("2d");
// 画布宽高
var w=h=500;
var x = 100;
var y = 100;
var r = 30;
// 水平速度
var xSpeed = 10;
// 垂直运动
var ySpeed = 6;
setInterval(function() {
// 每次都要清除整个画布
ctx.clearRect(0, 0, w, h);
// 在小球碰到边缘时,速度取相反即可
if(x-r <= 0 || x+r > w ) {
xSpeed = -xSpeed;
}
x = x+xSpeed
if(y-r <= 0 || y+r > w ) {
ySpeed = -ySpeed;
}
y = y+ySpeed
// 水平运动
drawCircle(x, y, r);
}, 50)
function drawCircle(x, y, r) {
// 加这个相当于把上面一次的画笔清除掉 否则就相当于你的笔重来都没有离开过画布
ctx.beginPath()
ctx.arc(x, y, r, 0, Math.PI*2);
ctx.fillStyle = 'gold'
ctx.fill()
}
</script>
</body>
</html>
Effect: It will bounce around when it hits the surrounding
9. Case: Small ball hits the wall detection (object-oriented)
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
//(1)获取画布
var canvas = document.querySelector("#cont");
//(2)获取画布的能力
var ctx = canvas.getContext("2d");
// 画布宽高
var w = 500
var h = 500
var ballArr = []
/**
* 面向对象
*
*/
function r(num) {
return Math.random()*num
}
/**
* @param x 起始x坐标
* @param y 起始y坐标
* @param r 小球半径
* @param color 小球颜色
* @param xSpeed x轴速度
* @param ySpeed y轴速度
* @author: @郑建
*/
function Ball() {
this.x = r(5) + 60;
this.y = r(3) + 60;
this.r = r(50) + 10 // [10, 100)
this.color = '#' + parseInt(Math.random()*0xffffff).toString(16)
this.xSpeed = r(3) + 2; // [2, 5)
this.ySpeed = r(3) + 1; // [1, 4)
}
// 在原型链上定义小球的公共方法
Ball.prototype.show = function() {
this.run()
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, Math.PI*2);
ctx.fillStyle = this.color
ctx.fill();
}
// 在原型链上定义小球的公共方法
Ball.prototype.run = function() {
if(this.x-this.r <= 0 || this.x+this.r >= w) {
this.xSpeed = -this.xSpeed
}
this.x = this.x + this.xSpeed
if(this.y-this.r <= 0 || this.y+this.r >= w) {
this.ySpeed = -this.ySpeed
}
this.y = this.y + this.ySpeed
}
for(var i = 0; i < 1000; i++) {
var ball = new Ball()
ballArr.push(ball)
ball.show()
}
setInterval(function() {
ctx.clearRect(0, 0, w, h)
for(var i = 0; i < ballArr.length; i++) {
var ball = ballArr[i]
ball.show()
}
}, 20)
</script>
</body>
</html>
Effect:
Ten, pictographs
1. Basic display
grammar:
fillText(text, x, y, maxWidth); // 实心文字
strokeText(text, x, y, maxWidth); // 空心文字
parameter:
text | Text output on the canvas |
x | The x-coordinate position at which to start drawing the text |
y | The y-coordinate position at which to start drawing the text |
maxWidth | optional. the maximum text width allowed, |
Case number one:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
var canvas = document.querySelector("#cont");
var ctx = canvas.getContext("2d");
// 1.设置字体样式
// font
ctx.font = '30px 微软雅黑';
//字体颜色
ctx.fillStyle = 'gold'
// 2.画文字
ctx.fillText('实心文字', 250, 250)
// 空心文字
ctx.strokeStyle = 'red'
ctx.strokeText('空心文字', 0, 250)
// 未设置最大宽度
ctx.fillStyle = 'red'
ctx.fillText('你好!我是未设置最大宽度的字体', 100, 50)
// 设置最大宽度
ctx.fillStyle = 'green'
ctx.fillText('你好!我设置最大宽度的字体', 100, 100, 300)
</script>
</body>
</html>
Effect:
2. Text Gradient
grammar:
var gradient = ctx.createLinearGradient(x0, y0, x1, y1)
parameter:
x0 | The x-coordinate of the gradient start point |
y0 | The y coordinate of the gradient start point |
x1 | The x coordinate of the end point of the gradient |
y1 | The y coordinate of the end point of the gradient |
case:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
canvas {
display: block;
margin: 0 auto;
border: 1px solid #aaa;
}
</style>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
var canvas = document.querySelector("#cont");
var ctx = canvas.getContext("2d");
ctx.font = '50px 微软雅黑';
/**
* 设置线性渐变
*/
var gradient = ctx.createLinearGradient(0, 0, canvas.width, 0)
gradient.addColorStop('0', "yellow")
gradient.addColorStop('0.5', 'blue')
gradient.addColorStop('1.0', 'red')
ctx.fillStyle = gradient
ctx.fillText('今天天气不错, 风和日丽!', 0, 100, 500)
ctx.strokeStyle = gradient
ctx.strokeText('适合出去玩儿!happy~', 0, 300, 500)
</script>
</body>
</html>
Effect:
3. Text position
grammar:
textAlign = 'start' | 'end' | 'left' | 'right' | 'center' // 水平方向
textBaseLine = 'top' | 'bottom' | 'moddle' | 'alphabetic' | 'hanging'
pixel
grammar:
ctx.getImageData(x, y, width, height)
parameter:
x | The x-coordinate of the upper-left corner location to start copying |
y | The y-coordinate of the upper-left corner position to start copying |
width | The width of the rectangular area to be copied |
height | 将要复制的矩形区域的高度 |
介绍:
返回的getImageData对象,该对象拷贝了画布指定矩形的像素数据
对于getImageData对象中的每个像素,都存在着四方面的信息, 即RGBA值
R - 红色 (0 - 255)
G - 绿色 (0 - 255)
B - 蓝色 (0 - 255)
A - alpha 通道 (0 - 255) ; 0: 透明; 255:完全不透明
color / alpha 以数组的形式存在,并存储于getImage对象的data属性中
案例:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
var canvas = document.querySelector("#cont");
var ctx = canvas.getContext("2d");
// 1 创建图片
var img = new Image();
img.src = 'u10.png'
img.onload = function() {
// 2 绘制图片
ctx.drawImage(img, 0, 0, img.width, img.height)
// 3 获取像素点
var copy = ctx.getImageData(0, 0, 10, 10);
console.log('像素数据', copy);
}
</script>
</body>
</html>
打印:
把像素点放到画布上
语法:
putImageData(imgData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight)
参数:
imgData | 规定要放回画布的ImageData对象 |
x | ImageData对象左上角的 x 坐标,以像素计 |
y | ImageData对象左上角的 y 坐标,以像素计 |
dirtyX | 可选。 水平值(x), 在画布上放置图片的位置 |
dirtyY | 可选。 水平值(y), 在画布上放置图片的位置 |
dirtyWidth | 可选。 在画布上绘制图像所使用的宽度 |
dirtyHeight | 可选。 在画布上绘制图像所使用的高度 |
案例:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<canvas id="cont" width="500px" height="500px"></canvas>
<script>
var canvas = document.querySelector("#cont");
var ctx = canvas.getContext("2d");
// 1 创建图片
var img = new Image();
img.src = 'u10.png'
img.onload = function() {
// 2 绘制图片
ctx.drawImage(img, 0, 0, 250, 250)
// 3 获取像素点
var copy1 = ctx.getImageData(0, 0, 100, 100);
ctx.putImageData(copy1, 0, 350)
}
</script>
</body>
</html>
效果: