当前位置: 首页 > article >正文

2_使用 HTML5 Canvas API (1) --[HTML5 API 学习之旅]

1.在页面中加入 canvas

在网页中加入 <canvas> 元素可以通过简单的 HTML 和 JavaScript 实现。以下是两个具体的示例,展示了如何在页面中使用 <canvas> 绘制图形和处理用户交互。

示例 1: 简单的静态绘图

这个例子展示了一个基础的 <canvas> 应用程序,它会在画布上绘制一个彩色矩形和一段文本。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Static Drawing</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>简单静态绘图示例</h1>
    <canvas id="staticCanvas" width="400" height="300"></canvas>

    <script>
        // 获取 canvas 元素和绘图上下文
        const canvas = document.getElementById('staticCanvas');
        const ctx = canvas.getContext('2d');

        // 设置填充颜色并绘制矩形
        ctx.fillStyle = 'blue';
        ctx.fillRect(50, 50, 200, 100);

        // 添加一些文本
        ctx.font = '24px Arial';
        ctx.fillStyle = 'white';
        ctx.textAlign = 'center';
        ctx.fillText('Hello Canvas!', 150, 100);
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • 我们定义了一个宽度为400像素、高度为300像素的 <canvas>
  • 使用 JavaScript 获取该元素的2D绘图上下文,并通过 fillRect 方法绘制一个蓝色矩形。
  • 接着设置了字体样式并通过 fillText 方法在矩形内添加了一段白色文本。

示例 2: 交互式绘图(用户可以画线)

这个例子创建了一个更复杂的 <canvas> 应用程序,允许用户通过鼠标在画布上绘制线条。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Interactive Canvas Drawing</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>交互式绘图示例</h1>
    <canvas id="interactiveCanvas" width="600" height="400"></canvas>

    <script>
        const canvas = document.getElementById('interactiveCanvas');
        const ctx = canvas.getContext('2d');

        let painting = false;

        function startPosition(e) {
            painting = true;
            draw(e);
        }

        function finishedPosition() {
            painting = false;
            ctx.beginPath();
        }

        function draw(e) {
            if (!painting) return;
            ctx.lineWidth = 5;
            ctx.lineCap = 'round';
            ctx.strokeStyle = 'black';

            ctx.lineTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
            ctx.stroke();
            ctx.beginPath();
            ctx.moveTo(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
        }

        canvas.addEventListener('mousedown', startPosition);
        canvas.addEventListener('mouseup', finishedPosition);
        canvas.addEventListener('mousemove', draw);
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • 我们创建了一个更大尺寸的 <canvas>(600x400),并且添加了事件监听器来捕捉用户的鼠标动作。
  • 当用户按下鼠标按钮时,调用 startPosition 函数开始绘制;当释放鼠标按钮时,调用 finishedPosition 函数结束绘制。
  • draw 函数中,根据鼠标的当前位置绘制线条。我们还确保只在 painting 变量为 true 时才进行绘制操作,以防止意外拖动鼠标时产生不必要的线条。

这两个示例展示了如何将 <canvas> 集成到网页中,并分别演示了静态绘图和基于用户输入的交互式绘图功能。你可以根据自己的需求进一步扩展这些例子,比如添加更多图形、颜色选择、橡皮擦等功能。

2.变换

<canvas> 中,变换(Transformations)是通过修改绘图上下文的坐标系统来实现的。这包括平移(translate)、旋转(rotate)、缩放(scale)等操作。以下是两个具体的变换示例,展示了如何使用这些功能来创建动态和交互性的图形效果。

示例 1: 平移与旋转

这个例子展示了如何结合平移和旋转来绘制一个旋转的矩形。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Transformation Example 1</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>平移与旋转示例</h1>
    <canvas id="transformCanvas1" width="400" height="400"></canvas>

    <script>
        const canvas = document.getElementById('transformCanvas1');
        const ctx = canvas.getContext('2d');

        // 设置矩形的颜色和初始位置
        ctx.fillStyle = 'blue';
        const rectWidth = 100;
        const rectHeight = 50;

        function drawRotatedRect(angle) {
            // 保存当前状态
            ctx.save();

            // 平移到矩形中心作为旋转点
            ctx.translate(200, 200);

            // 旋转画布
            ctx.rotate(angle * Math.PI / 180); // 将角度转换为弧度

            // 绘制矩形(相对于新的原点)
            ctx.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth, rectHeight);

            // 恢复之前的状态
            ctx.restore();
        }

        // 绘制多个不同角度的矩形
        for (let i = 0; i < 360; i += 30) {
            drawRotatedRect(i);
        }
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • 我们定义了一个函数 drawRotatedRect,它接受一个角度参数,并根据该角度旋转并绘制一个矩形。
  • 使用 ctx.save()ctx.restore() 来保存和恢复绘图状态,确保每次变换后都能回到原始状态。
  • 通过循环调用 drawRotatedRect 函数,在不同角度下绘制多个矩形,形成一个围绕中心点旋转的效果。

示例 2: 缩放与动画

这个例子展示了如何使用缩放变换创建一个简单的动画效果,使一个圆形逐渐放大和缩小。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Transformation Example 2</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>缩放与动画示例</h1>
    <canvas id="transformCanvas2" width="400" height="400"></canvas>

    <script>
        const canvas = document.getElementById('transformCanvas2');
        const ctx = canvas.getContext('2d');

        let scaleValue = 1.0;
        let direction = 1;

        function animateCircle() {
            // 清除画布
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            // 保存当前状态
            ctx.save();

            // 平移到画布中心
            ctx.translate(canvas.width / 2, canvas.height / 2);

            // 应用缩放变换
            ctx.scale(scaleValue, scaleValue);

            // 绘制圆形
            ctx.beginPath();
            ctx.arc(0, 0, 50, 0, 2 * Math.PI);
            ctx.fillStyle = 'red';
            ctx.fill();

            // 恢复之前的状态
            ctx.restore();

            // 更新缩放值并切换方向
            scaleValue += direction * 0.01;
            if (scaleValue > 1.5 || scaleValue < 0.5) {
                direction *= -1;
            }

            // 请求下一帧动画
            requestAnimationFrame(animateCircle);
        }

        // 开始动画
        animateCircle();
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • 我们定义了一个 animateCircle 函数,用于绘制一个红色圆形,并应用缩放变换使其看起来像是在不断放大和缩小。
  • 使用 requestAnimationFrame 方法来创建平滑的动画效果。
  • 通过调整 scaleValue 的值来控制缩放程度,并在达到一定界限时反转缩放方向,从而实现循环的放大和缩小效果。

这两个示例展示了如何利用 <canvas> 的变换功能来创建丰富的视觉效果。你可以根据需要进一步探索其他类型的变换组合,如倾斜(skewing),或者将这些变换应用于更复杂的图形和动画场景中。

3.路径

<canvas> 中,路径(Path)是创建形状的基本方式之一。路径是由直线、曲线等组成的线段序列,可以用来绘制各种图形。下面我将提供两个具体的路径示例,以展示如何使用路径来创建不同的图形。

示例 1: 绘制五角星

这个例子展示了如何使用路径和基本的绘图命令来绘制一个五角星。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Path Example 1</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>绘制五角星示例</h1>
    <canvas id="starCanvas" width="400" height="400"></canvas>

    <script>
        const canvas = document.getElementById('starCanvas');
        const ctx = canvas.getContext('2d');

        function drawStar(cx, cy, spikes, outerRadius, innerRadius) {
            let rot = Math.PI / 2 * 3;
            let x = cx;
            let y = cy;
            let step = Math.PI / spikes;

            ctx.beginPath();
            ctx.moveTo(cx, cy - outerRadius);

            for (let i = 0; i < spikes; i++) {
                x = cx + Math.cos(rot) * outerRadius;
                y = cy + Math.sin(rot) * outerRadius;
                ctx.lineTo(x, y);
                rot += step;

                x = cx + Math.cos(rot) * innerRadius;
                y = cy + Math.sin(rot) * innerRadius;
                ctx.lineTo(x, y);
                rot += step;
            }

            ctx.lineTo(cx, cy - outerRadius);
            ctx.closePath(); // 关闭路径
            ctx.lineWidth = 5;
            ctx.strokeStyle = 'blue';
            ctx.stroke(); // 描边
            ctx.fillStyle = 'yellow';
            ctx.fill(); // 填充
        }

        drawStar(canvas.width / 2, canvas.height / 2, 5, 100, 50); // 在画布中心绘制五角星
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • drawStar 函数接受参数来定义五角星的位置 (cx, cy)、尖角的数量 (spikes)、外圆半径 (outerRadius) 和内圆半径 (innerRadius)。
  • 使用 ctx.beginPath() 开始新的路径,并通过一系列的 lineTo 方法来定义路径上的点。
  • 使用 ctx.closePath() 来关闭路径,使最后一点与起始点相连。
  • 最后使用 strokefill 方法来描边和填充五角星。

示例 2: 贝塞尔曲线路径

这个例子展示了如何使用二次贝塞尔曲线(quadratic Bezier curve)和三次贝塞尔曲线(cubic Bezier curve)来创建平滑的路径。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Path Example 2</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>贝塞尔曲线路径示例</h1>
    <canvas id="bezierCanvas" width="600" height="400"></canvas>

    <script>
        const canvas = document.getElementById('bezierCanvas');
        const ctx = canvas.getContext('2d');

        // 绘制二次贝塞尔曲线
        ctx.beginPath();
        ctx.moveTo(50, 50);
        ctx.quadraticCurveTo(200, 10, 350, 50);
        ctx.strokeStyle = 'green';
        ctx.lineWidth = 3;
        ctx.stroke();

        // 绘制三次贝塞尔曲线
        ctx.beginPath();
        ctx.moveTo(50, 350);
        ctx.bezierCurveTo(150, 100, 450, 300, 550, 350);
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 3;
        ctx.stroke();

        // 标记控制点
        ctx.fillStyle = 'black';
        ctx.beginPath();
        ctx.arc(200, 10, 5, 0, 2 * Math.PI);
        ctx.arc(350, 50, 5, 0, 2 * Math.PI);
        ctx.arc(150, 100, 5, 0, 2 * Math.PI);
        ctx.arc(450, 300, 5, 0, 2 * Math.PI);
        ctx.fill();
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • 我们首先使用 quadraticCurveTo 方法来绘制一条从 (50, 50)(350, 50) 的二次贝塞尔曲线,其中 (200, 10) 是控制点。
  • 然后使用 bezierCurveTo 方法来绘制一条从 (50, 350)(550, 350) 的三次贝塞尔曲线,其中 (150, 100)(450, 300) 是两个控制点。
  • 最后,我们用小圆圈标记了所有控制点的位置,以便更清晰地看到贝塞尔曲线是如何被控制点影响的。

这两个示例展示了如何利用 <canvas> 的路径功能来创建复杂且平滑的图形。你可以根据需要调整这些路径的参数,或者探索更多关于路径的操作方法,如添加弧线、矩形等其他形状。

4.描边样式

<canvas> 中,描边样式可以通过设置 strokeStyle 属性来改变。这个属性可以接受颜色、渐变或模式作为其值。下面我将提供两个具体的描边样式示例,以展示如何使用不同的描边样式。

示例 1: 使用纯色和渐变作为描边样式

此示例展示了如何使用纯色以及线性渐变来设置路径的描边样式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Stroke Style Example 1</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>纯色与渐变描边样式示例</h1>
    <canvas id="colorGradientCanvas" width="600" height="400"></canvas>

    <script>
        const canvas = document.getElementById('colorGradientCanvas');
        const ctx = canvas.getContext('2d');

        // 纯色描边
        ctx.strokeStyle = 'blue'; // 设置描边颜色为蓝色
        ctx.lineWidth = 5;
        ctx.beginPath();
        ctx.moveTo(50, 50);
        ctx.lineTo(550, 50);
        ctx.stroke();

        // 线性渐变描边
        let gradient = ctx.createLinearGradient(0, 100, 600, 100);
        gradient.addColorStop(0, 'red'); // 开始颜色为红色
        gradient.addColorStop(0.5, 'yellow'); // 中间颜色为黄色
        gradient.addColorStop(1, 'green'); // 结束颜色为绿色

        ctx.strokeStyle = gradient; // 设置描边颜色为渐变
        ctx.beginPath();
        ctx.moveTo(50, 150);
        ctx.lineTo(550, 150);
        ctx.stroke();
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • 我们首先设置了 strokeStyle 为纯色(‘blue’),并用它绘制了一条水平线。
  • 接着创建了一个线性渐变,并通过 addColorStop 方法定义了渐变的颜色停止点。然后我们使用这个渐变作为描边样式来绘制另一条水平线。

示例 2: 使用图案作为描边样式

这个例子展示了如何使用一个图像作为描边样式,即创建一个图案(Pattern)对象。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Stroke Style Example 2</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>图案描边样式示例</h1>
    <canvas id="patternCanvas" width="600" height="400"></canvas>

    <script>
        const canvas = document.getElementById('patternCanvas');
        const ctx = canvas.getContext('2d');

        // 创建一个小图案用于描边
        const patternCanvas = document.createElement('canvas');
        patternCanvas.width = 20;
        patternCanvas.height = 20;
        const patternCtx = patternCanvas.getContext('2d');
        patternCtx.fillStyle = 'red';
        patternCtx.fillRect(0, 0, 10, 10); // 绘制左上角的红色方块
        patternCtx.fillStyle = 'blue';
        patternCtx.fillRect(10, 10, 10, 10); // 绘制右下角的蓝色方块

        // 将图案应用到主画布上的线条描边
        const pattern = ctx.createPattern(patternCanvas, 'repeat'); // 创建重复的图案
        ctx.strokeStyle = pattern;
        ctx.lineWidth = 20;
        ctx.lineCap = 'round'; // 圆头线帽
        ctx.beginPath();
        ctx.moveTo(50, 300);
        ctx.lineTo(550, 300);
        ctx.stroke();
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • 我们创建了一个小的辅助 <canvas> 元素,并在其上绘制了简单的图案(本例中是一个红蓝相间的格子)。
  • 然后使用 createPattern 方法基于该辅助 <canvas> 创建了一个图案对象,并将其设置为 strokeStyle
  • 最后我们用这个图案样式绘制了一条宽线,线的端点被设置为圆头(lineCap = 'round'),以便更美观地展示图案效果。

这两个示例展示了如何利用 <canvas> 的描边样式功能来实现多样化的效果。你可以根据需要调整这些描边样式的参数,或者探索更多关于描边和其他绘图属性的方法。

5.填充样式

<canvas> 中,填充样式可以通过设置 fillStyle 属性来改变。这个属性同样可以接受颜色、渐变或模式作为其值。下面我将提供两个具体的填充样式示例,以展示如何使用不同的填充样式。

示例 1: 使用纯色和径向渐变作为填充样式

此示例展示了如何使用纯色以及径向渐变来设置图形的填充样式。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Fill Style Example 1</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>纯色与径向渐变填充样式示例</h1>
    <canvas id="colorRadialGradientCanvas" width="600" height="400"></canvas>

    <script>
        const canvas = document.getElementById('colorRadialGradientCanvas');
        const ctx = canvas.getContext('2d');

        // 纯色填充
        ctx.fillStyle = 'green'; // 设置填充颜色为绿色
        ctx.fillRect(50, 50, 150, 100); // 绘制一个矩形并填充

        // 径向渐变填充
        let gradient = ctx.createRadialGradient(350, 150, 30, 350, 150, 80);
        gradient.addColorStop(0, 'red'); // 内圈颜色为红色
        gradient.addColorStop(1, 'blue'); // 外圈颜色为蓝色

        ctx.fillStyle = gradient; // 设置填充颜色为径向渐变
        ctx.beginPath();
        ctx.arc(350, 150, 80, 0, Math.PI * 2, false); // 创建一个圆
        ctx.fill(); // 填充圆形
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • 我们首先设置了 fillStyle 为纯色(‘green’),并用它绘制了一个矩形。
  • 接着创建了一个径向渐变,并通过 addColorStop 方法定义了渐变的颜色停止点。然后我们使用这个渐变作为填充样式来绘制并填充了一个圆形。

示例 2: 使用图案作为填充样式

这个例子展示了如何使用一个图像作为填充样式,即创建一个图案(Pattern)对象。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas Fill Style Example 2</title>
    <style>
        body { font-family: Arial, sans-serif; }
        canvas { border: 1px solid black; display: block; margin: 20px auto; }
    </style>
</head>
<body>
    <h1>图案填充样式示例</h1>
    <canvas id="patternFillCanvas" width="600" height="400"></canvas>

    <script>
        const canvas = document.getElementById('patternFillCanvas');
        const ctx = canvas.getContext('2d');

        // 创建一个小图案用于填充
        const patternCanvas = document.createElement('canvas');
        patternCanvas.width = 20;
        patternCanvas.height = 20;
        const patternCtx = patternCanvas.getContext('2d');
        patternCtx.fillStyle = 'yellow';
        patternCtx.fillRect(0, 0, 20, 20); // 绘制黄色背景
        patternCtx.fillStyle = 'black';
        patternCtx.beginPath();
        patternCtx.arc(10, 10, 8, 0, Math.PI * 2, true); // 创建一个小黑圆
        patternCtx.fill();

        // 将图案应用到主画布上的图形填充
        const pattern = ctx.createPattern(patternCanvas, 'repeat'); // 创建重复的图案
        ctx.fillStyle = pattern;
        ctx.beginPath();
        ctx.arc(300, 250, 100, 0, Math.PI * 2, false); // 创建一个大圆
        ctx.fill(); // 使用图案填充圆形
    </script>
</body>
</html>

在这里插入图片描述

在这个例子中:

  • 我们创建了一个小的辅助 <canvas> 元素,并在其上绘制了一个简单的图案(本例中是一个带有黑色圆点的黄色方块)。
  • 然后使用 createPattern 方法基于该辅助 <canvas> 创建了一个图案对象,并将其设置为 fillStyle
  • 最后我们用这个图案样式填充了一个较大的圆形,使得圆形内部充满了重复的小图案。

这两个示例展示了如何利用 <canvas> 的填充样式功能来实现多样化的效果。你可以根据需要调整这些填充样式的参数,或者探索更多关于填充和其他绘图属性的方法。


http://www.kler.cn/a/442898.html

相关文章:

  • 服务器登陆后有java变量
  • Uniapp Android 本地离线打包(详细流程)
  • 【机器学习:四、多输入变量的回归问题】
  • Windows下调试Dify相关组件(2)--后端Api
  • HarmonyOS开发:传参方式
  • 【Notepad++】Notepad++如何删除包含某个字符串所在的行
  • Java毕设项目:基于Springboot生鲜销售商城网站系统设计与实现开题报告
  • Spring Boot 3.X:Unable to connect to Redis错误记录
  • [LeetCode-Python版]142. 环形链表 II
  • Springboot3.x 进阶-配置和序列化
  • Android绘图Path基于LinearGradient线性渐变,Kotlin(1)
  • 免费开源了一个图床工具 github-spring-boot-starter
  • 汽车发动机电控系统-【传感器】篇
  • 实践环境-docker安装mysql8.0.40步骤
  • elasticsearch 使用enrich processor填充数据
  • 代码随想录算法训练营第五十天 | 图 | 并查集
  • fpga系列 HDL:Quartus II PLL (Phase-Locked Loop) IP核 (Quartus II 18.0)
  • Long类型的数据在网络传输的过程中丢失精度
  • Python-基于Pygame的小游戏(滑雪大冒险)(一)
  • 社交电商新风口:短视频交友+自营商城源码运营
  • filecoin boost GraphQL API 查询
  • AI开发 - 用GPT写一个GPT应用的真实案例
  • 在 Webpack 中Plugin有什么作用?Plugin是什么?
  • 华为认证HCIA——数据传输形式,数据封装的基本概念
  • 企业为什么会需要高防IP?
  • Elasticsearch:什么是信息检索?