可以给canvas图形上色的两个重要属性:
默认情况下,canvas 线条和填充都是黑色(色值:#000000)。
一旦设置了 strokeStyle 或者 fillStyle 的值,那么这个新值就会成为新绘制的图形的默认值。如果你要给每个图形上不同的颜色,你需要重新设置 fillStyle 或 strokeStyle 的值。
示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas设置颜色</title>
<style>
body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(200, 0, 0)';
ctx.fillRect(10, 10, 55, 50);
ctx.fillStyle = 'rgb(0, 0, 200)';
ctx.fillRect(70, 70, 55, 50);
ctx.strokeStyle = '#008800';
ctx.strokeRect(130, 130, 55, 50);
ctx.strokeStyle = 'rgb(0, 0, 200)';
ctx.strokeRect(190, 190, 55, 50);
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate;"></canvas>
</body>
</html>
有两种方式可以设置canvas图形透明度:
该属性设置canvas里所有图形的透明度,有效值范围:0.0(完全透明)到 1.0(完全不透明),默认是1.0。
示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 设置透明度 globalAlpha</title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
// 画背景
ctx.fillStyle = '#FD0';
ctx.fillRect(10, 10, 125, 125);
ctx.fillStyle = '#6C0';
ctx.fillRect(135, 10, 125, 125);
ctx.fillStyle = '#09F';
ctx.fillRect(10, 135, 125, 125);
ctx.fillStyle = '#F30';
ctx.fillRect(135, 135, 125, 125);
ctx.fillStyle = '#FFF';
// 设置透明度
ctx.globalAlpha = 0.2;
// 画半透明圆
for (let i = 0; i < 7; i++) {
ctx.beginPath();
ctx.arc(135, 135, 15 + 15 * i, 0, Math.PI * 2, true);
ctx.fill();
}
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>
将 strokeStyle 和 fillStyle 的属性值设置为 rgba 格式的色值。这种方式优点是更灵活,可操作性强。
示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 设置透明度 rgba()</title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
// 画背景
ctx.fillStyle = 'rgb(255, 221, 0)';
ctx.fillRect(10, 10, 280, 60);
ctx.fillStyle = 'rgb(102, 204, 0)';
ctx.fillRect(10, 71, 280, 60);
ctx.fillStyle = 'rgb(0, 153, 255)';
ctx.fillRect(10, 132, 280, 60);
ctx.fillStyle = 'rgb(255, 51, 0)';
ctx.fillRect(10, 193, 280, 60);
// 画半透明矩形
for (let i = 0; i < 19; i++) {
ctx.fillStyle = `rgba(255, 255, 255, ${(i + 1) / 19})`;
for (let j = 0; j < 4; j++) {
ctx.fillRect(15 + i * 14, 16 + j * 60, 14, 50);
}
}
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>
可以通过一系列属性来设置线的样式。
属性值必须为正数。默认值是 1.0。
注意:线宽是指给定路径的中心到两边的粗细。换句话说就是在路径的两边各绘制线宽的一半。(不理解,请参考下面的示例)
示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 线型 lineWidth</title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
for (let i = 0; i < 10; i++) {
// 不同粗细的线条
ctx.lineWidth = 1 + i;
ctx.beginPath();
ctx.moveTo(5 + i * 14, 5);
ctx.lineTo(5 + i * 14, 140);
ctx.stroke();
// 路径中心
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(5 + i * 14, 140);
ctx.lineTo(5 + i * 14, 180);
ctx.stroke();
}
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>
可选值:butt、round、square。
示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 线型 lineCap</title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
const lineCap = ['butt', 'round', 'square'];
// 创建路径
ctx.strokeStyle = '#09F';
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineTo(180, 20);
ctx.moveTo(20, 140);
ctx.lineTo(180, 140);
ctx.stroke();
// 画线条
ctx.strokeStyle = '#000';
for (let i = 0; i < lineCap.length; i++) {
ctx.lineWidth = 15;
ctx.lineCap = lineCap[i];
ctx.beginPath();
ctx.moveTo(45 + i * 50, 20);
ctx.lineTo(45 + i * 50, 140);
ctx.stroke();
}
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>
lineJoin 的属性值决定了图形中两线段连接处的样式。可选值:round、bevel 和 miter。默认是 miter。
示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 线型 lineJoin</title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
const lineJoin = ['round', 'bevel', 'miter'];
ctx.strokeStyle = '#000';
ctx.lineWidth = 15;
for (let i = 0; i < lineJoin.length; i++) {
ctx.lineJoin = lineJoin[i];
ctx.beginPath();
ctx.moveTo(25, 25 + i * 80);
ctx.lineTo(55, 65 + i * 80);
ctx.lineTo(85, 25 + i * 80);
ctx.lineTo(115, 65 + i * 80);
ctx.lineTo(145, 25 + i * 80);
ctx.stroke();
}
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>
两条线段相交,线段的外侧边缘会被延伸交汇于一点上。线段之间夹角比较大时,交点不会太远,但随着夹角变小,交点距离会呈指数级增大。结合上面 lineJoin 的示例来看更容易理解。
miterLimit 属性就是用来设定外延焦点与连接点的最大距离(即:指线条交接处内角顶点到外角顶点的长度)。
示例:
实现代码如下:(可以更改miterLimit的值来观察不同的绘制结果)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas 线型 miterLimit</title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
// 清空画布
ctx.clearRect(0, 0, 300, 300);
// 绘制参考线
ctx.strokeStyle = '#09f';
ctx.lineWidth = 2;
ctx.strokeRect(10, 50, 360, 50)
// 设置线条样式
ctx.strokeStyle = '#000';
ctx.lineWidth = 10;
// 设置miterLimit
ctx.miterLimit = 5;
// 绘制相交的线条
ctx.beginPath();
ctx.moveTo(0, 100);
for (let i = 0; i < 24; i++) {
let dy = i % 2 == 0 ? 25 : -25;
ctx.lineTo(Math.pow(i, 1.5) * 2, 75 + dy);
}
ctx.stroke();
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate;"></canvas>
</body>
</html>
先了解几个绘制虚线的API:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas 绘制虚线</title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
// 绘制一些常见的虚线样式
let y = 15;
function drawDashedLine(pattern) {
ctx.beginPath();
ctx.setLineDash(pattern);
ctx.moveTo(10, y);
ctx.lineTo(260, y);
ctx.stroke();
y += 20;
}
drawDashedLine([]);
drawDashedLine([1, 1]);
drawDashedLine([10, 10]);
drawDashedLine([20, 5]);
drawDashedLine([15, 3, 3, 3]);
drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3]);
drawDashedLine([12, 3, 3]); // 等于 [12, 3, 3, 12, 3, 3],可以通过getLineDash获取虚线样式来验证
console.log(ctx.getLineDash()) // 获取上面的虚线样式
// 虚线偏移:无偏移的虚线
ctx.setLineDash([8, 16]);
ctx.beginPath();
ctx.moveTo(10, 200);
ctx.lineTo(200, 200);
ctx.stroke();
// 虚线偏移:有偏移的虚线
ctx.beginPath();
ctx.lineDashOffset = 8;
ctx.moveTo(10, 210);
ctx.lineTo(200, 210);
ctx.stroke();
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate;"></canvas>
</body>
</html>
蚂蚁线示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 虚线 蚂蚁线 </title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
let offset = 0;
function drawDashRect() {
ctx.clearRect(0, 0, 200, 200)
ctx.setLineDash([4, 2]);
ctx.lineDashOffset = -offset;
ctx.strokeRect(10, 10, 100, 100);
}
function march() {
offset++;
if (offset > 16) offset = 0;
drawDashRect();
setTimeout(march, 20);
}
march();
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>
首先新建一个 canvasGradient 对象,然后 addColorStop() 方法上色。最后就可以把渐变像颜色一样赋值给 fillStyle 或 strokeStyle 了。
创建线性渐变的方法:
createLinearGradient(x1, y1, x2, y2)
createLinearGradient 方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)。
创建径向渐变的方法:
createRadialGradient(x1, y1, r1, x2, y2, r2)
createRadialGradient 方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。
给渐变上色
addColorStop(position, color)
addColorStop 方法接受 2 个参数,position 参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置。例如,0.5 表示颜色会出现在正中间。color 参数必须是一个有效的 CSS 颜色值(如 #FFF,rgba(0,0,0,1),等等)。
createLinearGradient 示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 渐变示例 createLinearGradient </title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
const lingrad = ctx.createLinearGradient(0, 0, 0, 300);
lingrad.addColorStop(0, '#00ABEB');
lingrad.addColorStop(0.5, '#FFF');
lingrad.addColorStop(0.5, '#26C000');
lingrad.addColorStop(1, '#FFF');
const lingrad2 = ctx.createLinearGradient(0, 100, 0, 195);
lingrad2.addColorStop(0.5, '#555');
lingrad2.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = lingrad;
ctx.strokeStyle = lingrad2;
ctx.fillRect(10, 10, 280, 280);
ctx.lineWidth = 3;
ctx.strokeRect(50, 70, 200, 190);
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>
createRadialGradient 示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 渐变示例 createRadialGradient </title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
const radgrad = ctx.createRadialGradient(65, 65, 10, 72, 70, 30);
radgrad.addColorStop(0, '#A7D30C');
radgrad.addColorStop(0.9, '#019F62');
radgrad.addColorStop(1, 'rgba(1, 159, 98, 0)');
const radgrad2 = ctx.createRadialGradient(175, 175, 20, 182, 180, 50);
radgrad2.addColorStop(0, "#FF5F98");
radgrad2.addColorStop(0.75, "#FF0188");
radgrad2.addColorStop(1, "rgba(255,1,136,0)");
const radgrad3 = ctx.createRadialGradient(145, 95, 15, 155, 90, 40);
radgrad3.addColorStop(0, "#00C9FF");
radgrad3.addColorStop(0.8, "#00B5E2");
radgrad3.addColorStop(1, "rgba(0,201,255,0)");
const radgrad4 = ctx.createRadialGradient(100, 150, 50, 100, 140, 90);
radgrad4.addColorStop(0, "#F4F201");
radgrad4.addColorStop(0.8, "#E4C700");
radgrad4.addColorStop(1, "rgba(228,199,0,0)");
ctx.fillStyle = radgrad4;
ctx.fillRect(0, 0, 300, 300);
ctx.fillStyle = radgrad3;
ctx.fillRect(0, 0, 300, 300);
ctx.fillStyle = radgrad2;
ctx.fillRect(0, 0, 300, 300);
ctx.fillStyle = radgrad;
ctx.fillRect(10, 10, 150, 150);
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>
上面使用渐变填充 canvas 图形,可以通过图案样式 Pattern 使用图片填充 canvas 图形。
createPattern(image, type)
该方法接受两个参数:
图案的应用跟渐变很类似的,创建出一个 pattern 之后,赋给 fillStyle 或 strokeStyle 属性即可。
示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 图案 Pattern 填充示例 </title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
const img = new Image();
img.src = './logo.png';
img.onload = function () {
const ptrn = ctx.createPattern(img, 'repeat');
ctx.fillStyle = ptrn;
ctx.fillRect(10, 10, 280, 280);
}
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>
相关属性如下:
文字阴影示例:
实现代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 文字阴影 </title>
<style>
body {
height: 100vh;
padding: 30px;
}
</style>
<script>
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.font = '40px Times New Roman';
ctx.fillStyle = '#000';
ctx.fillText('Sample String', 25, 130);
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 2;
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.fillText('Sample String', 25, 180);
} else {
alert('您的浏览器不支持Canvas!');
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300" style="background-color: #f3f4f8; color: chocolate"></canvas>
</body>
</html>