JavaScript 绘制简单不规则图形:三角形与五角星实战教程

1. 前言

在 Web 开发中,使用 JavaScript 绘制图形是一项基础且实用的技能。无论是数据可视化、游戏开发还是 UI 设计,都离不开图形的绘制。本文将重点介绍如何使用原生 JavaScript 绘制两种常见的不规则图形:三角形五角星。我们将从最基础的 Canvas API 入手,逐步构建出完整的图形。

2. 准备工作:创建画布

在开始绘制之前,我们需要一个 HTML 画布(Canvas)元素作为绘图区域。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>绘制不规则图形</title>
    <style>
        canvas {
            border: 1px solid #ccc;
            display: block;
            margin: 20px auto;
        }
    </style>
</head>
<body>
    <canvas id="myCanvas" width="400" height="300"></canvas>
    <script src="script.js"></script>
</body>
</html>

同时,创建一个 script.js 文件,并获取 Canvas 的 2D 绘图上下文。

javascript 复制代码
// script.js
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

3. 绘制三角形

三角形是最简单的多边形。在 Canvas 中,我们通过定义三个顶点并连接它们来绘制。

3.1 基本三角形绘制

使用 beginPath()moveTo()lineTo()closePath() 方法。

javascript 复制代码
function drawTriangle(x1, y1, x2, y2, x3, y3, fillColor = '#3498db') {
    ctx.beginPath();
    ctx.moveTo(x1, y1); // 起点
    ctx.lineTo(x2, y2); // 第二个点
    ctx.lineTo(x3, y3); // 第三个点
    ctx.closePath();    // 自动连接回起点

    ctx.fillStyle = fillColor;
    ctx.fill(); // 填充三角形

    // 可选:绘制边框
    ctx.strokeStyle = '#2c3e50';
    ctx.lineWidth = 2;
    ctx.stroke();
}

// 绘制一个三角形
drawTriangle(100, 50, 50, 150, 150, 150);

这段代码会在画布上绘制一个蓝色的填充三角形。

3.2 绘制等边三角形

等边三角形的三个顶点坐标可以通过数学公式计算得出。

javascript 复制代码
function drawEquilateralTriangle(centerX, centerY, sideLength, fillColor = '#e74c3c') {
    const height = sideLength * Math.sqrt(3) / 2; // 等边三角形的高

    const x1 = centerX;
    const y1 = centerY - height / 2; // 顶点

    const x2 = centerX - sideLength / 2;
    const y2 = centerY + height / 2; // 左下角点

    const x3 = centerX + sideLength / 2;
    const y3 = centerY + height / 2; // 右下角点

    drawTriangle(x1, y1, x2, y2, x3, y3, fillColor);
}

// 在画布中心绘制一个边长为100的等边三角形
drawEquilateralTriangle(200, 150, 100);

4. 绘制五角星

五角星的绘制比三角形复杂,需要计算十个顶点(五个外顶点和五个内顶点)。

4.1 计算五角星顶点

五角星的顶点坐标可以通过圆上的角度和半径来计算。

javascript 复制代码
function drawStar(centerX, centerY, outerRadius, innerRadius, fillColor = '#f1c40f') {
    ctx.beginPath();

    for (let i = 0; i < 10; i++) {
        const radius = i % 2 === 0 ? outerRadius : innerRadius; // 交替使用外半径和内半径
        const angle = Math.PI / 2 + i * Math.PI / 5; // 每个顶点间隔36度(π/5弧度)

        const x = centerX + radius * Math.cos(angle);
        const y = centerY - radius * Math.sin(angle); // Canvas Y轴向下为正,故用减号

        if (i === 0) {
            ctx.moveTo(x, y);
        } else {
            ctx.lineTo(x, y);
        }
    }

    ctx.closePath();
    ctx.fillStyle = fillColor;
    ctx.fill();

    ctx.strokeStyle = '#d35400';
    ctx.lineWidth = 2;
    ctx.stroke();
}

// 在画布中心绘制一个五角星
drawStar(200, 150, 80, 40);

outerRadius 是外顶点到中心的距离,innerRadius 是内顶点到中心的距离。调整这两个值可以改变五角星的"胖瘦"。

4.2 绘制多个不同样式的星星

我们可以封装一个更通用的函数,并绘制多个星星。

javascript 复制代码
function drawStyledStar(centerX, centerY, outerRadius, innerRadius, fillColor, rotation = 0) {
    ctx.save(); // 保存当前绘图状态
    ctx.translate(centerX, centerY); // 将原点移动到星星中心
    ctx.rotate(rotation * Math.PI / 180); // 旋转(角度转弧度)

    ctx.beginPath();
    for (let i = 0; i < 10; i++) {
        const radius = i % 2 === 0 ? outerRadius : innerRadius;
        const angle = Math.PI / 2 + i * Math.PI / 5;

        const x = radius * Math.cos(angle);
        const y = -radius * Math.sin(angle); // 注意Y轴方向

        if (i === 0) {
            ctx.moveTo(x, y);
        } else {
            ctx.lineTo(x, y);
        }
    }
    ctx.closePath();
    ctx.fillStyle = fillColor;
    ctx.fill();
    ctx.strokeStyle = '#2c3e50';
    ctx.lineWidth = 1;
    ctx.stroke();

    ctx.restore(); // 恢复绘图状态
}

// 绘制多个星星
drawStyledStar(100, 80, 30, 12, '#9b59b6', 0);
drawStyledStar(300, 80, 40, 18, '#1abc9c', 15);
drawStyledStar(100, 220, 35, 14, '#e67e22', -10);
drawStyledStar(300, 220, 25, 10, '#e74c3c', 30);

5. 完整示例与交互

将以上代码整合,并添加简单的交互(例如点击画布随机绘制三角形或星星)。

javascript 复制代码
// 整合后的 script.js 文件
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// ... 此处插入前面定义的 drawTriangle, drawEquilateralTriangle, drawStar, drawStyledStar 函数 ...

// 初始绘制
drawEquilateralTriangle(200, 150, 100, '#3498db');
drawStar(200, 150, 80, 40, '#f1c40f');

// 点击交互:随机绘制图形
canvas.addEventListener('click', function(event) {
    const rect = canvas.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;

    ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空画布

    // 随机选择绘制三角形或星星
    if (Math.random() > 0.5) {
        const size = 20 + Math.random() * 50;
        drawEquilateralTriangle(x, y, size, `hsl(${Math.random() * 360}, 70%, 60%)`);
    } else {
        const outerR = 15 + Math.random() * 40;
        const innerR = outerR * 0.5;
        drawStyledStar(x, y, outerR, innerR, `hsl(${Math.random() * 360}, 70%, 60%)`, Math.random() * 360);
    }
});

6. 总结

通过本文,我们学习了使用 JavaScript 和 Canvas API 绘制两种不规则图形的方法:

  • 三角形:通过连接三个顶点实现,可以轻松绘制任意三角形或等边三角形。
  • 五角星:通过计算外顶点和内顶点的坐标,并按顺序连接而成。

核心步骤可以归纳为:获取上下文 → 计算路径点 → 开始路径 → 移动/连线 → 闭合路径 → 设置样式 → 填充/描边。掌握这些基础后,你可以举一反三,绘制出更复杂的多边形和自定义图形。

你可以尝试修改代码中的坐标、颜色、大小和旋转角度,创造出丰富多彩的图形效果。

相关推荐
想要成为糕糕手4 小时前
NO.48 旋转图像 —— LeetCode 热题 100 面试导向深度解析
javascript·算法·面试
数聚天成DeepSData4 小时前
企业知识库 RAG 数据准备与文档清洗:Dify、RAGFlow、扣子选型指南
开发语言·人工智能·机器学习·自然语言处理·sentinel·cocos2d
我是唐青枫4 小时前
Java SLF4J 实战指南:从日志门面到 Logback、MDC 和链路追踪
java·开发语言·logback
aramae4 小时前
C++11:现代C++的里程碑
c语言·开发语言·c++·windows·git·后端
JieE2124 小时前
LeetCode 138 随机链表的复制|两种解法详解(哈希表 + 原地 O (1) 空间)
javascript·算法·面试
用户852495071844 小时前
RAG实战:从零打造智能知识库问答系统
javascript
weixin_446729164 小时前
java实现发送邮件
java·开发语言
秋天的一阵风4 小时前
🔥 ECMAScript 2026 来了!使用这些新特性,JS 代码直接少一半
前端·javascript·ecmascript 6
米尔的可达鸭5 小时前
深入操作系统 Socket 底层:EPOLLOUT 可写事件管理 + 非阻塞异步
开发语言·网络·数据结构·经验分享·websocket·网络协议