欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 明星 > 前端之超好使的canvas的场景应用

前端之超好使的canvas的场景应用

2025/3/10 13:30:34 来源:https://blog.csdn.net/weixin_44258964/article/details/146130721  浏览:    关键词:前端之超好使的canvas的场景应用

canvas基础介绍

canvas是啥,做啥用基本就不介绍,下面MDN解释可以看看
在这里插入图片描述
废话不多说,下面我直接开始介绍一些canvas最基础使用以及一些应用场景

canvas基础使用

关于canvas使用,我自己总结了四步走,可以快速应用canvas,当然一切的开始都要从canvas节点<canvas id="myCanvas">,获取开始

const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d"); // 返回canvas 的上下文,相当于canvas的一个实例

ok开始四步实操:

第一步:ctx.beginPath() 开始绘制;

  • 绘制不同路径,最好都以beginPath开始,否则会被之前的绘制方式影响

第二步:moveTo() 绘制开始的点、lineTo()绘制结束的点

  • 通常moveTo和lineTo组合使用
  • moveTo也可以和塞贝尔曲线绘制bezierCurveTo等

第三步:以stroke(绘制路径、线条)或者fill(填充) 完成绘制

第四步:ctx.closePath()关闭绘制

canvas基础样式配置

// 画圆润的5px宽的线条配置
ctx.value.strokeStyle = "#55FF7A";
ctx.value.lineCap = "round";
ctx.value.lineJoin = "round";
ctx.value.globalAlpha = 0.5;
ctx.value.lineWidth = 5;

canvas四部实操基本绘制

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");ctx.beginPath();
ctx.moveTo(50, 50); // 开始绘制第一条子路径
ctx.lineTo(200, 50);
ctx.stroke();
ctx.closePath()

canvas其他应用场景

下面总结了博主用到过的四个canvas使用场景,欢迎评论提问~

1、canvas截图

绘制图很简单,只用到一个drawImage API即可

  • drawImage 可以在画布中绘制一张图像
    • 第一个参数可以是绘制到上下文的元素。允许任何的画布图像源,例如:HTMLImageElement、SVGImageElement、HTMLVideoElement、HTMLCanvasElement、ImageBitmap、OffscreenCanvas 或 VideoFrame。
    • 二三参数则为绘制的起始坐标,四五参数则为绘制的图大小

下面案例则是绘制video第一秒的帧图片

const canvas = document.getElementById("myCanvas");
const curPlayVideo = document.getElementById("video");
curPlayVideo.currentTime = 1000
const ctx = canvas.getContext("2d");
const width = curPlayVideo.videoWidth;
const height = curPlayVideo.videoHeight;
ctx.drawImage(curPlayVideo, 0, 0, width, height); //绘制视频

2、贝塞尔曲线

绘制贝塞尔曲线用到的相关API:

  1. .bezierCurveTo:是用于绘制三段式的贝塞尔曲线,参数如下
    • 该方法需要三个点:前两个点是控制点,第三个点是结束点
    • 起始点是当前路径的最后一个点,绘制贝赛尔曲线前,可以通过调用 moveTo() 进行修改
  2. .arc:是用于绘制小点的,参数如下
    • 用于将一个圆弧添加到当前子路径中
    • arc() 方法创建一个以坐标 (x, y) 为中心,以 radius 为半径的圆弧。
    • 路径从 startAngle 开始,到 endAngle 结束,路径方向由 counterclockwise 参数决定(默认为顺时针方向)。
// bezierCurveTo、arc参数
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
arc(x, y, radius, startAngle, endAngle, counterclockwise)
arc(x, y, 2, 0, 2 * Math.PI) // 绘制一个2px半径的圆

绘制贝塞尔曲线代码

    const canvas = document.getElementById("myCanvas");const ctx = canvas.getContext("2d");const BEZIER_CURVE_HANDLER_RATE = 0.42; // 贝塞尔曲率手柄控制点的相对位置const CANVAS_PADDING = 10; // 画布安全距离const CANVAS_WIDTH = 400;const CANVAS_HEIGHT = 300;const getControllPoint = (start, end) => {const xDelta = +end.x - +start.x;return [// cp1{ x: +start.x + BEZIER_CURVE_HANDLER_RATE * xDelta, y: start.y },// cp2{ x: +end.x - BEZIER_CURVE_HANDLER_RATE * xDelta, y: end.y },];};function drawBezierCurveBetween(ctx,start,end,) {const [cp1, cp2] = getControllPoint(start, end);// Cubic Bézier curvectx.beginPath();ctx.moveTo(+start.x, +start.y);ctx.bezierCurveTo(+cp1.x, +cp1.y, +cp2.x, +cp2.y, +end.x, +end.y);ctx.stroke();// Start and end pointsctx.fillStyle = 'red';ctx.beginPath();ctx.arc(+start.x, +start.y, 2, 0, 2 * Math.PI); // Start pointctx.arc(+end.x, +end.y, 2, 0, 2 * Math.PI); // End pointctx.fill();ctx.fillText(`(${end.coordinateX}, ${end.coordinateY})`, +end.x - 30, +end.y - 10);}drawBezierCurveBetween(ctx, { x: 10, y: 10 }, { x: 100, y: 100, coordinateX: 100, coordinateY: 100 })drawBezierCurveBetween(ctx, { x: 100, y: 100 }, { x: 150, y: 150, coordinateX: 150, coordinateY: 150 })drawBezierCurveBetween(ctx, { x: 150, y: 150 }, { x: 250, y: 100, coordinateX: 250, coordinateY: 100 })

这是大概效果
在这里插入图片描述

3、根据图片信息,反转图片颜色

大概思路

  1. 首先使用使用API drawImage绘制图片
  2. 在根据getImageData获取图片的像素信息,便利像素再反转rgb的颜色
  3. 最后使用putImageData绘制反转过后的图片

使用API参数详解
getImageData() 返回一个 ImageData 对象,用于描述 canvas 指定区域的隐含像素数据。
.putImageData() 方法用于将数据从已有的 ImageData 对象绘制到画布上

ctx.getImageData(sx, sy, sw, sh) // 前两参数是图片起始坐标,后来参数是图片宽高
ctx.putImageData(imageData, dx, dy) // 第一个参数是getImageData获取的data,二三参数是起始坐标

绘制代码

const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");
const img = document.getElementById("img");
ctx.drawImage(img, 0, 0);
const imgData=ctx.getImageData(0,0,c.width,c.height);// invert colors
for (var i=0;i<imgData.data.length;i+=4){imgData.data[i]=255-imgData.data[i];imgData.data[i+1]=255-imgData.data[i+1];imgData.data[i+2]=255-imgData.data[i+2];imgData.data[i+3]=255;}
ctx.putImageData(imgData,0,0);

4、画一个以圆心为起点的平均射线

  • 100毫秒画一条,基本按照博主四步走理论
function drawRadial(x0, y0, r, angle) {r = r || 10;angle = angle || 10;var len = 360 / angle;var radian = (2 * Math.PI * angle) / 360;for (var i = 1; i <= len; i++) {(function (j) {setTimeout(function timer() {x1 = x0 + r * Math.cos(radian * j);y1 = y0 + r * Math.sin(radian * j);ctx.beginPath();ctx.moveTo(x0, y0);ctx.lineTo(x1, y1);ctx.stroke();}, j * 100);})(i);}
}
drawRadial(100, 100, 50, 10);

最后效果
在这里插入图片描述

其他

博主用过的canvas插件

插件html2canvas,可以制定html节点使用canvas绘制成图片

  • 只要指定节点dom元素即可绘制
  • 需要注意一点是每个设备像素不一样,所以绘制的时候设置1.5倍的像素比,确保绘制图片的清晰度

具体代码实现

    import html2canvas from 'html2canvas'const getCanvasToImage = async () => {canCopyPoster.value = falseconst dom = document.querySelector('#dom')// 这里绘制图大小根据设备比例来const scale = window.devicePixelRatio * 1.5const options = {useCORS: true,allowTaint: false,backgroundColor: 'rgba(0,0,0,0.7)',scale,}const canvas = await html2canvas(dom, options)posterUrl.value = canvas.toDataURL() // 即可得到html节点图片}

常用的canvas API了解

一些常用的API:
fillStyle:设置填充颜色或渐变。
strokeStyle:设置描边颜色。
lineWidth:设置线宽。
lineCap、lineJoin:分别设置线条的末端样式和两条线相交时的形状。
beginPath()、closePath():分别用于开始一个新的路径或完成当前路径。
moveTo()、lineTo():分别用于移动到某个点并绘制直线到另一个点。
arc()、arcTo():用于绘制圆弧和圆角矩形。
fill()、stroke():分别用于填充和描边当前路径。
clearRect():清除指定矩形区域‌。

canvas的其他API我就不过多介绍了,感兴趣的可以去看看官网

MDN:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/canvas

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词