Canvas绘图API(路径、矩形、文本等)
Canvas是HTML5中一个强大的绘图工具,通过JavaScript API可以实现丰富的图形绘制功能。它支持路径、矩形、文本等多种绘图操作,适用于数据可视化、游戏开发、图像处理等场景。
路径绘制
路径是Canvas中最基础的绘图方式,通过一系列线段或曲线组合成任意形状。使用beginPath()
开始一个新路径,moveTo()
移动画笔到指定坐标,lineTo()
绘制直线到新坐标,最后用stroke()
或fill()
描边或填充路径。
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 绘制三角形
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(100, 50);
ctx.lineTo(75, 100);
ctx.closePath(); // 自动闭合路径
ctx.strokeStyle = 'blue';
ctx.stroke();
贝塞尔曲线可以创建平滑曲线,二次贝塞尔曲线使用quadraticCurveTo()
,三次贝塞尔曲线使用bezierCurveTo()
。
// 二次贝塞尔曲线
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.quadraticCurveTo(80, 100, 150, 20);
ctx.strokeStyle = 'red';
ctx.stroke();
// 三次贝塞尔曲线
ctx.beginPath();
ctx.moveTo(50, 150);
ctx.bezierCurveTo(100, 50, 150, 250, 200, 150);
ctx.strokeStyle = 'green';
ctx.stroke();
矩形绘制
Canvas提供了直接绘制矩形的API,比路径方式更简便。rect()
方法定义矩形路径,fillRect()
直接绘制填充矩形,strokeRect()
绘制描边矩形,clearRect()
清除矩形区域。
// 填充矩形
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
ctx.fillRect(10, 10, 100, 80);
// 描边矩形
ctx.lineWidth = 3;
ctx.strokeStyle = '#00f';
ctx.strokeRect(150, 10, 100, 80);
// 清除区域
ctx.clearRect(180, 30, 40, 40);
圆角矩形需要结合路径和arcTo()
方法实现:
function drawRoundedRect(x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
ctx.stroke();
}
文本绘制
Canvas支持两种文本绘制方法:fillText()
填充文本和strokeText()
描边文本。通过font
属性设置字体样式,textAlign
控制水平对齐,textBaseline
控制垂直对齐。
ctx.font = 'bold 24px Arial';
ctx.fillStyle = 'purple';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('Hello Canvas', canvas.width/2, 50);
ctx.font = 'italic 18px serif';
ctx.strokeStyle = 'black';
ctx.lineWidth = 1;
ctx.strokeText('描边文字效果', 100, 100);
测量文本宽度使用measureText()
方法:
const text = '测量文本宽度';
const metrics = ctx.measureText(text);
console.log(`文本宽度:${metrics.width}px`);
样式与颜色
Canvas提供了丰富的样式设置选项。fillStyle
和strokeStyle
接受颜色字符串、渐变对象或图案对象。线性渐变使用createLinearGradient()
,径向渐变使用createRadialGradient()
。
// 线性渐变
const gradient = ctx.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, 'red');
gradient.addColorStop(0.5, 'yellow');
gradient.addColorStop(1, 'green');
ctx.fillStyle = gradient;
ctx.fillRect(10, 10, 200, 100);
// 径向渐变
const radialGrad = ctx.createRadialGradient(100, 100, 10, 100, 100, 50);
radialGrad.addColorStop(0, 'white');
radialGrad.addColorStop(1, 'blue');
ctx.fillStyle = radialGrad;
ctx.arc(100, 100, 50, 0, Math.PI*2);
ctx.fill();
图像操作
Canvas可以绘制图像并进行各种变换。drawImage()
方法有三种形式:基本绘制、缩放绘制和切片绘制。
const img = new Image();
img.src = 'example.jpg';
img.onload = function() {
// 基本绘制
ctx.drawImage(img, 0, 0);
// 缩放绘制
ctx.drawImage(img, 0, 0, img.width/2, img.height/2);
// 切片绘制
ctx.drawImage(img,
10, 10, 100, 100, // 源图像切片区域
0, 0, 200, 200 // 目标绘制区域
);
};
变换与合成
Canvas支持多种图形变换:translate()
移动原点,rotate()
旋转,scale()
缩放,transform()
矩阵变换。使用save()
和restore()
可以保存和恢复绘图状态。
// 绘制旋转矩形
ctx.save();
ctx.translate(150, 150);
ctx.rotate(Math.PI/4);
ctx.fillStyle = 'orange';
ctx.fillRect(-50, -50, 100, 100);
ctx.restore();
// 图形合成
ctx.globalCompositeOperation = 'xor';
ctx.fillStyle = 'red';
ctx.fillRect(100, 100, 100, 100);
ctx.fillStyle = 'blue';
ctx.fillRect(150, 150, 100, 100);
动画实现
Canvas动画通过连续清除和重绘实现,通常使用requestAnimationFrame
优化性能。
let x = 0;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, 50, 50, 50);
x += 2;
if(x > canvas.width) x = 0;
requestAnimationFrame(animate);
}
animate();
性能优化
对于复杂绘图,可以采用以下优化策略:
- 使用
offscreenCanvas
进行离屏渲染 - 避免在动画循环中频繁创建对象
- 对静态内容分层绘制
- 合理使用
willReadFrequently
提示
// 离屏Canvas示例
const offscreen = new OffscreenCanvas(300, 150);
const offCtx = offscreen.getContext('2d');
// 在离屏Canvas上绘制复杂图形
offCtx.fillRect(0, 0, 300, 150);
// 将结果绘制到主Canvas
ctx.drawImage(offscreen, 0, 0);
高级路径操作
Canvas还支持路径剪裁和命中检测。clip()
方法可以创建剪裁区域,isPointInPath()
检测点是否在路径内。
// 创建圆形剪裁区域
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI*2);
ctx.clip();
// 后续绘制只会显示在剪裁区域内
ctx.fillRect(0, 0, 200, 200);
// 命中检测
canvas.addEventListener('click', (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
ctx.beginPath();
ctx.arc(100, 100, 50, 0, Math.PI*2);
if(ctx.isPointInPath(x, y)) {
alert('点击了圆形!');
}
});
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:'