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

前端之超好使的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 curve
        ctx.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 points
        ctx.fillStyle = 'red';
        ctx.beginPath();
        ctx.arc(+start.x, +start.y, 2, 0, 2 * Math.PI); // Start point
        ctx.arc(+end.x, +end.y, 2, 0, 2 * Math.PI); // End point
        ctx.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 = false
    const dom = document.querySelector('#dom')
    // 这里绘制图大小根据设备比例来
    const scale = window.devicePixelRatio * 1.5
    const 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

相关文章:

  • 黄金贵金属行情
  • 【学习方法一】
  • 【面试】Zookeeper
  • uniapp 自定义地图组件(根据经纬度展示地图地理位置)
  • 【Git】合并冲突
  • MySQL-MVCC
  • MPPT与PWM充电原理及区别详解
  • 使用 Vue 3 + TypeScript + Vant 4 构建现代移动端应用
  • 小米智能音箱Pro搭载“超级小爱”,支持远程控车
  • 2025科技项目申报预测月历来啦!
  • C++程序设计语言笔记——基本功能:指针、数组与引用
  • Grafana Loki
  • 深度学习实战车辆目标跟踪与计数
  • 全栈网络安全|渗透测试-1
  • 网络初级复习作业
  • react+ts+eslint+prettier 配置教程
  • 【AI】AI开源IDE:CLine源码分析报告
  • 54-WLAN 无线局域网配置方案-三层
  • 云曦25开学考复现
  • React-异步队列执行方法useSyncQueue
  • 百度品牌网站建设/成人短期技能培训
  • 邢台做外贸网站/推广普通话手抄报内容文字
  • 做b2b网站服务器空间多大的容量/seo教程之关键词是什么
  • 小企业网站建设系统哪个好/百度云网盘下载
  • 做的好看的国内网站欣赏/网站分享
  • 网站建设制作设计营销 上海/抖音seo教程