这篇文章记录了在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.绘制路径
图形的基本元素是路径。
路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。
一个路径,甚至一个子路径,都是闭合的。
使用路径绘制图形需要一些额外的步骤:
- 创建路径起始点
- 调用绘制方法去绘制出路径
- 把路径封闭
- 一旦路径生成,通过描边或填充路径区域来渲染图形。
下面是需要用到的方法:
-
beginPath()
新建一条路径,路径一旦创建成功,图形绘制命令被指向到路径上生成路径
-
moveTo(x, y)
把画笔移动到指定的坐标
(x, y)
。相当于设置路径的起始点坐标。 -
closePath()
闭合路径之后,图形绘制命令又重新指向到上下文中
-
stroke()
通过线条来绘制图形轮廓
-
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
表示顺时针(默认是顺时针)。
注意:
-
这里的度数都是弧度。
-
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.添加样式和颜色
如果想要给图形上色,有两个重要的属性可以做到。
-
fillStyle = color
设置图形的填充颜色 -
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博客
感谢作者!!!!