Canvas--》使用Canvas完成基本绘图

news2024/11/15 23:57:30

 

🌟Canvas介绍

<canvas>是一个可以使用脚本 (通常为javaScript) 来绘制图形的HTML元素。例如,它可以用于绘制图表、制作图片构图或者制作简单的动画。如上面效果示例就是使用 <canvas> 来实现示例,后续将一步步实现上面效果。

Canvas 的默认大小为 300 像素 ×150 像素(宽 × 高,像素的单位是 px)。但是,可以使用 HTML 的高度和宽度属性来自定义 Canvas 的尺寸。为了在 Canvas 上绘制图形,我们使用一个 JavaScript 上下文对象,它能动态创建图像(creates graphics on the fly)。

🌟Canvas 的基本用法

获取绘制上下文

// cvs为canvas元素
const ctx = cvs.getContext("2d");
// 之后使用上下文对象ctx完成后续绘图
  • 所有的绘图都必须在上下文中完成
  • 同一个canvas元素只能产生唯一的上下文
  • 上下文类型可以是:
    • 2d:绘制2d图形
    • bitmaprenderer:绘制位图上下文
    • webgl:绘制3d的上下文,只在实现WebGL版本 1(OpenGL ES 2.0) 的浏览器上可用
    • webgl2:绘制3d的上下文,只在实现 WebGL 版本 2 (OpenGL ES 3.0) 的浏览器上可用

Context2D绘图

cvs.getContext('2d')

会产生一个CanvasRenderingContext2D对象,它里面包含非常多的绘图方法。

利用这些绘图方法,我们可以完成下列图形的绘制:

  1. 直线

  2. 曲线

  3. 文字

  4. 图片

利用上面基本形状以及它们的组合,再配合它提供的各种样式设置,就可以完成任意二维图像的绘制。

栅格

在我们开始画图之前,我们需要了解一下画布栅格(canvas grid)以及坐标空间。如上图所示,canvas 元素默认被网格所覆盖。通常来说网格中的一个单元相当于 canvas 元素中的一像素。栅格的起点为左上角(坐标为(0,0))。所有元素的位置都相对于原点定位。所以图中蓝色方形左上角的坐标为距离左边(X 轴)x 像素,距离上边(Y 轴)y 像素(坐标为(x,y))。

绘制路径

图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。使用路径绘制图形需要一些额外的步骤。

  1. 首先,你需要创建路径起始点。
  2. 然后你使用画图去画出路径。
  3. 之后你把路径封闭。
  4. 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。

以下是所要用到的函数:

beginPath()

新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。

closePath()

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

stroke()

通过线条来绘制图形轮廓。

fill()

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

生成路径的第一步叫做 beginPath()。本质上,路径是由很多子路径构成,这些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。而每次这个方法调用之后,列表清空重置,然后我们就可以重新绘制新的图形。

🌟开始画图

绘制基础线条及圆点

接下来就可以开始画图,首先来实现线条:

可以得到如下:

接下来使用arc()方法在线条两端绘制圆形 :

 效果如下:

封装方法

在随机位置生成圆

 多点连线

 🌟完整代码

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width= , initial-scale=1.0" />
    <title>Document</title>
    <style>
      canvas {
        position: fixed;
        left: 0;
        top: 0;
        background: #222;
      }
    </style>
  </head>
  <body>
    <canvas></canvas>
    <script src="./index.js"></script>
  </body>
</html>

JS

const cvs = document.querySelector('canvas');
const ctx = cvs.getContext('2d');

function init() {
  cvs.width = window.innerWidth;
  cvs.height = window.innerHeight;
}

init();

/**
 * 获取 [min, max] 范围内的随机整数
 * @return {Number}
 */
function getRandom(min, max) {
  return Math.floor(Math.random() * (max + 1 - min) + min);
}

class Point {
  constructor() {
    this.r = 6;
    this.x = getRandom(0, cvs.width - this.r / 2);
    this.y = getRandom(0, cvs.height - this.r / 2);
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
    ctx.fillStyle = 'rgb(200,200,200)';
    ctx.fill();
  }
}

class Graph {
  constructor(pointNumber = 30, maxDis = 200) {
    this.points = new Array(pointNumber).fill(0).map(() => new Point());
    this.maxDis = maxDis;
  }

  draw() {
    for (let i = 0; i < this.points.length; i++) {
      const p1 = this.points[i];
      p1.draw();
      for (let j = i + 1; j < this.points.length; j++) {
        const p2 = this.points[j];
        const d = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
        if (d > this.maxDis) {
          continue;
        }
        ctx.beginPath();
        ctx.moveTo(p1.x, p1.y);
        ctx.lineTo(p2.x, p2.y);
        ctx.closePath();
        ctx.strokeStyle = `rgba(200,200,200,${1 - d / this.maxDis})`;
        ctx.stroke();
      }
    }
  }
}

const g = new Graph();
g.draw();

🌟写在最后

Canvas--》将详细讲解关于绘制图表、制作图片构图或者制作简单的动画,如果文中出现有瑕疵的地方各位通过评论或者私信联系我,我们一起进步,有兴趣的伙伴可以关注订阅一下:点击查看更多实用技巧及技术

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1063837.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HDLbits: ece241 2014 q4

module top_module (input clk,input x,output z ); reg [2:0] Q;always(posedge clk)beginQ[0] < Q[0] ^ x;Q[1] < (~Q[1]) & x;Q[2] < (~Q[2]) | x;z < ~(| Q[2:0]); //错误&#xff01;&#xff01;&#xff01;&#xff01;endendmodule 正确答案&#xf…

Python python-docx 使用教程

openpyxl是Python下的Word库&#xff0c;它能够很容易的对Word文档进行读取 安装方法&#xff1a;pip install python-docx国内镜像安装&#xff1a;pip install -i https://mirrors.aliyun.com/pypi/simple/ python-docx&#xff08;推荐&#xff0c;安装更快&#xff09;中文…

【算法】关于排序你应该知道的一切(下)

和光同尘_我的个人主页 单程孤舟&#xff0c;出云入霞&#xff0c;如歌如吟。 --门孔 八大排序 &#x1f56f;️前言1. 常见排序算法2. 常见排序算法实现2.1. 冒泡排序2.1.1. 基本思想2.1.2. 代码实现2.1.3. 特性 2.2. 快速排序2.2.1. hoare法基本思想代码实现 2.2.2. 快速排…

静图表情包怎么做成动态图?动图表情包制作教程

静态的图片不如动态的图片吸引人&#xff0c;动态的图片内容丰富、生动&#xff0c;体积小还易于传播保存。Gif格式动图其实就是由一帧一帧的图片合成的带有动态效果的图片。下面&#xff0c;给大家介绍一下动图gif制作&#xff08;https://www.gif.cn/&#xff09;的方法&…

asp.net班级管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net班级管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言开发 asp.net班级管理系统 二、功能介绍 1…

操作系统和进程相关的认识

目录 冯诺依曼体系结构 冯诺依曼体系结构五大组成部分 为什么数据只能通过存储器进行输入和输出 操作系统 概念一&#xff1a;访问操作系统的请求都是通过系统调用完成的 操作系统如何管理用户信息 概念二&#xff1a;先描述&#xff0c;再组织。 进程的概念 在认识进行相关的知…

Java基础--泛型详解

一、背景 java推出泛型之前&#xff0c;集合元素类型可以是object类型&#xff0c;能够存储任意的数据类型对象&#xff0c;但是在使用过程中&#xff0c;如果不知道集合里面的各个元素的类型&#xff0c;在进行类型转换的时候就很容易引发ClassCastException异常。 二、概念 …

POJ 2104 K-th Number 平方分割(分桶法)

一、题目大意 长度为n&#xff08;n<100000&#xff09;的数组&#xff0c;进行m次查询&#xff08;m<5000&#xff09;&#xff0c;每次查询时&#xff0c;输入为 i j k&#xff0c;返回为数组 [i,j] 的分片里第k大数字&#xff08;1<i<j<n,k<j-i1) 二、解…

基于Java的校园自助洗衣系统设计与实现(源码+lw+ppt+部署文档+视频讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

python机器学习之梯度下降法

系列文章目录 第一章 Python 机器学习入门之线性回归 第一章 Python 机器学习入门之梯度下降法 梯度下降法 系列文章目录前言一、梯度下降法1.梯度下降法简介2.基本原理 梯度下降函数效果展示 前言 上一篇文章里面说到了用梯度下降法来对最小化代价函数和模型参数进行求解&am…

计算机网络八股

1、请你说说TCP和UDP的区别 TCP提供面向连接的可靠传输&#xff0c;UDP提供面向无连接的不可靠传输。UDP在很多实时性要求高的场景有很好的表现&#xff0c;而TCP在要求数据准确、对速度没有硬件要求的场景有很好的表现。TCP和UDP都是传输层协议&#xff0c;都是为应用层程序服…

八、【快速选择工具组】

文章目录 对象选择工具快速选择工具魔棒工具 对象选择工具 当我们选择对象选择工具时&#xff0c;需要先注意上边有一个循环的圆&#xff0c;它会进行内容识别&#xff0c;当识别完成会停止旋转。这个时候我们按住n键&#xff0c;或者将鼠标放上对应的图形时会出现选中的颜色。…

多实例学习MIL(easy / hard)

多示例学习&#xff08;Multiple Instance Learning&#xff09; - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/377220948 多示例学习 和弱监督&#xff08;weakly supervised&#xff09;有一定的关系&#xff0c;弱监督weakly supervised有三个含义&#xff08;或者说三…

ethercat EOE arp

1 网口设置 电脑地址位169.254.254.3 2 从站地址 3 PING 正常 异常 4 抓包

【方法】如何取消ZIP压缩包的密码?

我们知道&#xff0c;在压缩ZIP文件的时候&#xff0c;可以设置“打开密码”来保护压缩包&#xff0c;那后续不需要保护了&#xff0c;不想每次打开压缩包都输一次密码&#xff0c;要如何取消密码呢&#xff1f; 比较常用的方法是先把ZIP压缩包解压后&#xff0c;再压缩成没有…

铝合金分类及相关总结

1 铝合金常识 铝合金是工业中应用最广泛的一类有色金属结构材料&#xff0c;在航空、航天、汽车、机械制造、船舶及化学工业中已大量应用。对于常用的铝合金&#xff0c;我们通常根据其铝及其他元素的含量&#xff0c;将其分为两大类&#xff0c;分别是纯铝和铝合金。对这两大类…

网络安全行业真的内卷了吗?网络安全就业就业必看

前言 有一个特别流行的词语叫做“内卷”&#xff1a; 城市内卷太严重了&#xff0c;年轻人不好找工作&#xff1b;教育内卷&#xff1b;考研内卷&#xff1b;当然还有计算机行业内卷…… 这里的内卷当然不是这个词原本的意思&#xff0c;而是“过剩”“饱和”的替代词。 按照…

JMeter接口自动化测试(数据驱动)

之前我们的用例数据都是配置在HTTP请求中&#xff0c;每次需要增加&#xff0c;修改用例都需要打开JMeter重新编辑&#xff0c;当用例越来越多的时候&#xff0c;用例维护起来就越来越麻烦&#xff0c;有没有好的方法来解决这种情况呢&#xff1f;我们可以将用例的数据存放在cs…

Effective Modern C++ 第七章 并发API 2

目录 条款37&#xff1a;使std::thread型别对象在所有路径皆不可联结 要点速记&#xff1a; 条款38&#xff1a;对变化多端的线程句柄析构函数行为保持关注 要点速记&#xff1a; 参考&#xff1a;EffectiveModernCppChinese/src/7.TheConcurrencyAPI/item37.md at master …

【java爬虫】使用vue+element-plus编写一个简单的管理页面

前言 前面我们已经将某宝联盟的数据获取下来了&#xff0c;并且编写了一个接口将数据返回&#xff0c;现在我们需要使用vueelement-plus编写一个简单的管理页面进行数据展示&#xff0c;由于第一次使用vue编写前端项目&#xff0c;所以只是编写了一个非常简单的页面。 项目结…