vue3中使用 HTML5 Canvas 做一个案例总结笔记

news/2024/11/17 18:19:57/

        这篇文章记录了在vue3中如何使用HTML5 Canvas做一个时钟的案例, 当然主要是HTML5 Canvas, 如何需要了解更多关于vue的知识前面也已经写过好几篇了,辛苦翻一下的...

        开始写代码之前我们先来了解一下关于HTML5 Canvas 的基础知识

目录

一 .基础知识

1.了解canvas

1.1 基本用法

 1.2 简单例子

2.绘制形状

3.绘制路径

3.1 绘制圆弧

4.添加样式和颜色

二.案例

1.结果展示 


一 .基础知识

1.了解canvas

<canvas> 是 HTML5 新增的,一个可以使用脚本(通常为 JavaScript) 在其中绘制图像的 HTML 元素。它可以用来制作照片集或者制作简单(也不是那么简单)的动画,甚至可以进行实时视频处理和渲染。

1.1 基本用法
<canvas id="myCanvas" width="300" height="300"></canvas>

<canvas></canvas> 是双标签, 可以设置宽高属性的大小,默认是width=300 height=150 

如果对于一些老旧的浏览器,不支持canvas的会显示提示信息

<canvas>你的浏览器不支持 canvas,请升级你的浏览器。
</canvas>

canvas标签也可以使用<img /> 标签

<canvas><img src="./pig.jpg" alt=""> 
</canvas>

渲染上下文

var canvas = document.getElementById('myCanvas');
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');

检测可用性

function draw(){var canvas = document.getElementById('myCanvas');if(!canvas.getContext) return;// 判断浏览器是否支持var ctx = canvas.getContext("2d");//开始代码
}
 1.2 简单例子

用上面的知识我们已经可以完成一个简单的例子了

<canvas id="myCanvas" width="300" height="300"></canvas>
<script type="text/javascript">
function draw(){var canvas = document.getElementById('myCanvas');if(!canvas.getContext) return;var ctx = canvas.getContext("2d");ctx.fillStyle = "rgb(200,0,0)";//绘制矩形ctx.fillRect (10, 10, 55, 50);ctx.fillStyle = "rgba(0, 0, 200, 0.5)";ctx.fillRect (30, 30, 55, 50);
}
draw();
</script>

2.绘制形状

2.1 ​<canvas> 只支持一种原生的图形绘制:矩形。所有其他图形都至少需要生成一种路径 (path)。

canvast 提供了三种方法绘制矩形:

  • 1、fillRect(x, y, width, height):绘制一个填充的矩形。
  • 2、strokeRect(x, y, width, height):绘制一个矩形的边框。
  • 3、clearRect(x, y, widh, height):清除指定的矩形区域,然后这块区域会变的完全透明。

说明:这 3 个方法具有相同的参数。

  • x, y:指的是矩形的左上角的坐标。(相对于canvas的坐标原点)
  • width, height:指的是绘制的矩形的宽和高。

3.绘制路径

图形的基本元素是路径。

路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。

一个路径,甚至一个子路径,都是闭合的。

使用路径绘制图形需要一些额外的步骤:

  1. 创建路径起始点
  2. 调用绘制方法去绘制出路径
  3. 把路径封闭
  4. 一旦路径生成,通过描边或填充路径区域来渲染图形。

下面是需要用到的方法:

  1. beginPath()

    新建一条路径,路径一旦创建成功,图形绘制命令被指向到路径上生成路径

  2. moveTo(x, y)

    把画笔移动到指定的坐标(x, y)。相当于设置路径的起始点坐标。

  3. closePath()

    闭合路径之后,图形绘制命令又重新指向到上下文中

  4. stroke()

    通过线条来绘制图形轮廓

  5. fill()

    通过填充路径的内容区域生成实心的图形

function draw(){var canvas = document.getElementById('myCanvas');if (!canvas.getContext) return;var ctx = canvas.getContext("2d");ctx.beginPath(); //新建一条pathctx.moveTo(50, 50); //把画笔移动到指定的坐标ctx.lineTo(200, 50);  //绘制一条从当前位置到指定坐标(200, 50)的直线.ctx.lineTo(200, 200); //绘制三角形边框//闭合路径。会拉一条从当前点到path起始点的直线。如果当前点与起始点重合,则什么都不做ctx.closePath();ctx.stroke(); //绘制路径。ctx.fill(); //填充闭合区域。如果path没有闭合,则fill()会自动闭合路径。
}
draw();
3.1 绘制圆弧

有两个方法可以绘制圆弧:

1、arc(x, y, r, startAngle, endAngle, anticlockwise): 以(x, y) 为圆心,以r 为半径,从 startAngle 弧度开始到endAngle弧度结束。anticlosewise 是布尔值,true 表示逆时针,false 表示顺时针(默认是顺时针)。

注意:

  1. 这里的度数都是弧度。

  2. 0 弧度是指的 x 轴正方向。

    radians=(Math.PI/180)*degrees   //角度转换成弧度

2、arcTo(x1, y1, x2, y2, radius): 根据给定的控制点和半径画一段圆弧,最后再以直线连接两个控制点。

例子:

function draw(){var canvas = document.getElementById('myCanvas');if (!canvas.getContext) return;var ctx = canvas.getContext("2d");ctx.beginPath();ctx.arc(50, 50, 40, 0, Math.PI / 2, false);ctx.stroke();
}
draw();

4.添加样式和颜色

​ 如果想要给图形上色,有两个重要的属性可以做到。

  1. fillStyle = color 设置图形的填充颜色

  2. strokeStyle = color 设置图形轮廓的颜色

备注:

  • 1. color 可以是表示 css 颜色值的字符串、渐变对象或者图案对象。
  • 2. 默认情况下,线条和填充颜色都是黑色。
  • 3. 一旦您设置了 strokeStyle 或者 fillStyle 的值,那么这个新值就会成为新绘制的图形的默认值。如果你要给每个图形上不同的颜色,你需要重新设置 fillStyle 或 strokeStyle 的值。

线条末端样式 

 //lineCap = type  var lineCaps = ["butt", "round", "square"]; //线条末端以方形 圆形 增加了高度是线宽的一半ctx.lineCap = "butt";

绘制文本

 ctx.font = "100px sans-serif"ctx.fillText("天若有情", 10, 100);ctx.strokeText("天若有情", 10, 200)

绘制图片

  const img = new Image();img.onload = function(){ctx.drawImage(img,0,0); //绘制在canvas中  图片和坐标ctx.drawImage(img, 0, 0, 400, 200) //后面两个参数是缩放大小}img.src = 'img.png' //图片地址

切片

drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) 
//参数和其它的是相同的 前 4 个是定义图像源的切片位置和大小,
//后 4 个则是定义切片的目标显示位置和大小。

状态的保存和恢复

save() //Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存 可以调用任意多次 save方法(类似数组的 push())。restore()  //相当于撤销

变形

translate(x,y) //从原点移动到的位置  x左右偏移 y上下偏移

旋转坐标轴

rotate(angle)  //顺时针方向

放大缩小

用它来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大

//x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值 默认是1
scale(x, y)

变形矩阵

transform(a, b, c, d, e, f) 

合成 总共13种

globalCompositeOperation = typectx.globalCompositeOperation = "source-over"; //全局合成操作//source-in 仅显示新图像与老图像重叠部分//source-out 仅显示新图像与老图像没有重叠部分

裁剪路径

clip()  //只显示裁剪路径内的区域 适用于使用裁剪路径之后的绘制的图形 之前绘制的图形无法完成遮罩

 动画

基本步骤

  • 1.先清空动画 clearRect()

  • 2.保存canvas状态

  • 3.绘制动画帧

  • 4.恢复canvas状态

控制动画  定时执行重绘

setInterval()
setTimeout()
requestAnimationFrame()

二.案例

这是一个电子时钟的案例

let secondAngle = pi / 180 * 6 * s;  //计算出来s针的弧度

这里弧度计算 按照一周360度的话  pi / 180 = 1度  6\360  = 1\60  所以1s的弧度是之前的6倍

  import {onMounted} from 'vue';onMounted(() => {const canvas = document.getElementById('myCanvas');if(!canvas.getContext) return;// 获得2d上下文对象const ctx = canvas.getContext('2d');draw(ctx);});const draw = (ctx) => {requestAnimationFrame(function step(){drawDial(ctx); //绘制表盘drawAllHands(ctx); //绘制时分秒针requestAnimationFrame(step);});}//绘制时分秒针const drawAllHands = (ctx) => {let time = new Date();let s = time.getSeconds();let m = time.getMinutes();let h = time.getHours();let pi = Math.PI;let secondAngle = pi / 180 * 6 * s;  //计算出来s针的弧度let minuteAngle = pi / 180 * 6 * m + secondAngle / 60;  //计算出来分针的弧度let hourAngle = pi / 180 * 30 * h + minuteAngle / 12;  //计算出来时针的弧度drawHand(hourAngle, 60, 6, "red", ctx);  //绘制时针drawHand(minuteAngle, 106, 4, "green", ctx);  //绘制分针drawHand(secondAngle, 129, 2, "blue", ctx);  //绘制秒针}/*绘制时针、或分针、或秒针* 参数1:要绘制的针的角度* 参数2:要绘制的针的长度* 参数3:要绘制的针的宽度* 参数4:要绘制的针的颜色* 参数4:ctx* */const drawHand = (angle, len, width, color, ctx) => {ctx.save();ctx.translate(150, 150); //把坐标轴的远点平移到原来的中心ctx.rotate(-Math.PI / 2 + angle);  //旋转坐标轴。 x轴就是针的角度ctx.beginPath();ctx.moveTo(-4, 0);ctx.lineTo(len, 0);  // 沿着x轴绘制针ctx.lineWidth = width;ctx.strokeStyle = color;ctx.lineCap = "round";ctx.stroke();ctx.closePath();ctx.restore();}// 绘制表盘const drawDial = (ctx) => {let pi = Math.PI;ctx.clearRect(0, 0, 300, 300); //清除所有内容ctx.save();ctx.translate(150, 150); //一定坐标原点到原来的中心ctx.beginPath();ctx.arc(0, 0, 148, 0, 2 * pi); //绘制圆周ctx.stroke();ctx.closePath();for (let i = 0; i < 60; i++){//绘制刻度。ctx.save();ctx.rotate(-pi / 2 + i * pi / 30);  //旋转坐标轴。坐标轴x的正方形从 向上开始算起ctx.beginPath();ctx.moveTo(110, 0);ctx.lineTo(140, 0);ctx.lineWidth = i % 5 ? 2 : 4;ctx.strokeStyle = i % 5 ? "blue" : "red";ctx.stroke();ctx.closePath();ctx.restore();}ctx.restore();}

1.结果展示 

相关阅读:

前端常见的页面布局以及Flexbox总结 【收藏备用】_前端flex布局网站-CSDN博客 

参考原文:学习HTML5 Canvas这一篇文章就够了-CSDN博客 

感谢作者!!!!


http://www.ppmy.cn/news/1547775.html

相关文章

Linux下useradd 和 adduser的区别

useradd 和 adduser 是在类 Unix 系统中用于添加新用户的命令&#xff0c;但它们之间存在一些差异&#xff0c;主要体现在不同的系统环境和命令的具体实现上。 useradd useradd 命令通常用于基于 sysvinit 的系统&#xff0c;如早期的 Linux 发行版&#xff08;比如 CentOS 6…

Jmeter中的监听器(四)

13--用表格查看结果 功能特点 响应时间&#xff1a;显示每个请求的响应时间。响应码&#xff1a;显示每个请求的HTTP响应码。请求数据&#xff1a;显示发送的请求数据。响应数据&#xff1a;显示接收到的响应数据。错误信息&#xff1a;显示请求失败时的错误信息。详细信息&a…

【手撕 Spring】 -- 实现含构造函数的类实例化

&#x1f308;手写简化版 Spring 框架&#xff1a;通过构建一个精简版的 Spring 框架&#xff0c;深入理解 Spring 的核心机制&#xff0c;掌握其设计思想&#xff0c;进一步提升编程能力 &#x1f308;项目代码地址&#xff1a;https://github.com/YYYUUU42/mini-Spring 如果该…

计算机网络 (5)数据通信的基础知识

前言 数据通信是一种以信息处理技术和计算机技术为基础的通信方式&#xff0c;它通过数据通信系统将数据以某种信号方式从一处传送到另一处&#xff0c;为计算机网络的应用和发展提供了技术支持和可靠的通信环境&#xff0c;是现代通信技术的关键部分。 一、数据通信的基本概念…

C# DataTable使用Linq查询详解

前奏- C# 对DataTable进行查询 C# 可以对 DataTable 进行查询。在 .NET 框架中&#xff0c;DataTable 类提供了几种方法来查询数据&#xff0c;包括 Select 方法和 AsEnumerable 扩展方法&#xff08;在 System.Data.DataSetExtensions 命名空间中&#xff09;。 使用 Select…

机器学习: LightGBM模型(优化版)——高效且强大的树形模型

LightGBM&#xff08;Light Gradient Boosting Machine&#xff09;是一种基于梯度提升决策树&#xff08;GBDT&#xff09;的框架&#xff0c;由微软提出。它具有高效的训练速度、低内存占用、支持并行和GPU加速等特点&#xff0c;非常适合大规模数据的训练任务&#xff0c;尤…

1、使用vscode+eide+stm32cubeMx开发stm32

步骤1&#xff1a;在vscode中安装如下的插件 步骤2&#xff1a;点击Embedded IDE&#xff0c;点击“新建项目”-----空项目-----Cortex-M项目。 步骤3&#xff1a;输入项目名&#xff0c;回车后会要制定保存路径&#xff0c;此时就是一个已项目名命名的文件夹。 步骤4&#xff…

鸿蒙next ui安全区域适配(刘海屏、摄像头挖空等)

目录 相关api 团结引擎对于鸿蒙的适配已经做了安全区域的适配&#xff0c;也考虑到了刘海屏和摄像机挖孔的情况&#xff0c;在团结引擎内可以直接使用Screen.safeArea 相关api 团结引擎对于鸿蒙的适配已经做了安全区域的适配&#xff0c;也考虑到了刘海屏和摄像机挖孔的情况&am…