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 绘制两种不规则图形的方法:

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

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

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

相关推荐
To_OC1 小时前
LC 35 搜索插入位置:二分查找谁都会,边界条件谁写谁懵
javascript·算法·leetcode
码哥DFS2 小时前
二叉树的直径
开发语言·javascript·算法
paopaokaka_luck2 小时前
基于springboot3+vue3的企业考勤管理系统(部门树递归、Echarts图形化分析)
开发语言·spring boot·学习·echarts·mybatis·需求分析·代码规范
梦雨生生4 小时前
java开发工具(学习第一天)
java·开发语言·学习
光影少年4 小时前
RN的Fabric 渲染流程
运维·前端·javascript·react native·react.js·fabric
啊啊啊啊啊!!!!5 小时前
【c++】stack和queue的接口使用以及底层实现
开发语言·c++
用户938515635076 小时前
React Router 进阶:路由守卫、登录鉴权与状态传递
前端·javascript·全栈
kyriewen6 小时前
我重写了自己用了两年的防抖节流Hook——发现里面藏着3个隐藏bug
前端·javascript·面试
松仔log6 小时前
Java中级——组合和继承
android·java·开发语言
漂流瓶jz6 小时前
Webpack开发环境:观察模式/webpack-dev-server/HMR热更新
前端·javascript·webpack